Zoltan2
Loading...
Searching...
No Matches
MultiJaggedTest.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
21
23
24#include "Teuchos_XMLParameterListHelpers.hpp"
25
26#include <Teuchos_LAPACK.hpp>
27#include <fstream>
28#include <string>
29using Teuchos::RCP;
30using Teuchos::rcp;
31
32
33//#define hopper_separate_test
34#ifdef hopper_separate_test
35#include "stdio.h"
36#endif
37#define CATCH_EXCEPTIONS_AND_RETURN(pp) \
38 catch (std::runtime_error &e) { \
39 std::cout << "Runtime exception returned from " << pp << ": " \
40 << e.what() << " FAIL" << std::endl; \
41 return -1; \
42 } \
43 catch (std::logic_error &e) { \
44 std::cout << "Logic exception returned from " << pp << ": " \
45 << e.what() << " FAIL" << std::endl; \
46 return -1; \
47 } \
48 catch (std::bad_alloc &e) { \
49 std::cout << "Bad_alloc exception returned from " << pp << ": " \
50 << e.what() << " FAIL" << std::endl; \
51 return -1; \
52 } \
53 catch (std::exception &e) { \
54 std::cout << "Unknown exception returned from " << pp << ": " \
55 << e.what() << " FAIL" << std::endl; \
56 return -1; \
57 }
58
59#define CATCH_EXCEPTIONS_WITH_COUNT(ierr, pp) \
60 catch (std::runtime_error &e) { \
61 std::cout << "Runtime exception returned from " << pp << ": " \
62 << e.what() << " FAIL" << std::endl; \
63 (ierr)++; \
64 } \
65 catch (std::logic_error &e) { \
66 std::cout << "Logic exception returned from " << pp << ": " \
67 << e.what() << " FAIL" << std::endl; \
68 (ierr)++; \
69 } \
70 catch (std::bad_alloc &e) { \
71 std::cout << "Bad_alloc exception returned from " << pp << ": " \
72 << e.what() << " FAIL" << std::endl; \
73 (ierr)++; \
74 } \
75 catch (std::exception &e) { \
76 std::cout << "Unknown exception returned from " << pp << ": " \
77 << e.what() << " FAIL" << std::endl; \
78 (ierr)++; \
79 }
80
86const char param_comment = '#';
87
89 const string& s,
90 const string& delimiters = " \f\n\r\t\v" )
91{
92 return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
93}
94
96 const string& s,
97 const string& delimiters = " \f\n\r\t\v" )
98{
99 return s.substr( s.find_first_not_of( delimiters ) );
100}
101
103 const string& s,
104 const string& delimiters = " \f\n\r\t\v" )
105{
106 return trim_left_copy( trim_right_copy( s, delimiters ), delimiters );
107}
108
109template <typename Adapter>
111 const char *str,
112 int dim,
113 typename Adapter::scalar_t *lower,
114 typename Adapter::scalar_t *upper,
115 size_t nparts,
116 typename Adapter::part_t *parts
117)
118{
119 std::cout << "boxAssign test " << str << ": Box (";
120 for (int j = 0; j < dim; j++) std::cout << lower[j] << " ";
121 std::cout << ") x (";
122 for (int j = 0; j < dim; j++) std::cout << upper[j] << " ";
123
124 if (nparts == 0)
125 std::cout << ") does not overlap any parts" << std::endl;
126 else {
127 std::cout << ") overlaps parts ";
128 for (size_t k = 0; k < nparts; k++) std::cout << parts[k] << " ";
129 std::cout << std::endl;
130 }
131}
132
133template <typename Adapter>
136 RCP<tMVector_t> &coords,
137 bool print_details)
138{
139 int ierr = 0;
140
141 // pointAssign tests
142 int coordDim = coords->getNumVectors();
143 zscalar_t *pointDrop = new zscalar_t[coordDim];
144 typename Adapter::part_t part = -1;
145
146 char mechar[10];
147 sprintf(mechar, "%d", problem->getComm()->getRank());
148 string me(mechar);
149
150 // test correctness of pointAssign for owned points
151 {
152 const typename Adapter::part_t *solnPartView =
153 problem->getSolution().getPartListView();
154
155 size_t numPoints = coords->getLocalLength();
156 for (size_t localID = 0; localID < numPoints; localID++) {
157
158 typename Adapter::part_t solnPart = solnPartView[localID];
159
160 for (int i = 0; i < coordDim; i++)
161 pointDrop[i] = coords->getData(i)[localID];
162
163 try {
164 part = problem->getSolution().pointAssign(coordDim, pointDrop);
165 }
166 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + ": pointAssign -- OwnedPoints");
167
168 if(print_details) {
169 std::cout << me << " Point " << localID
170 << " gid " << coords->getMap()->getGlobalElement(localID)
171 << " (" << pointDrop[0];
172 if (coordDim > 1) std::cout << " " << pointDrop[1];
173 if (coordDim > 2) std::cout << " " << pointDrop[2];
174 std::cout << ") in boxPart " << part
175 << " in solnPart " << solnPart
176 << std::endl;
177 }
178
179// this error test does not work for points that fall on the cuts.
180// like Zoltan's RCB, pointAssign arbitrarily picks a part along the cut.
181// the arbitrarily chosen part will not necessarily be the one to which
182// the coordinate was assigned in partitioning.
183//
184// if (part != solnPart) {
185// std::cout << me << " pointAssign: incorrect part " << part
186// << " found; should be " << solnPart
187// << " for point " << j << std::endl;
188// ierr++;
189// }
190 }
191 }
192
193 {
194 const std::vector<Zoltan2::coordinateModelPartBox>
195 pBoxes = problem->getSolution().getPartBoxesView();
196 if(print_details) {
197 for (size_t i = 0; i < pBoxes.size(); i++) {
198 typename Zoltan2::coordinateModelPartBox::coord_t *lmin = pBoxes[i].getlmins();
199 typename Zoltan2::coordinateModelPartBox::coord_t *lmax = pBoxes[i].getlmaxs();;
200 std::cout << me << " pBox " << i << " pid " << pBoxes[i].getpId()
201 << " (" << lmin[0] << "," << lmin[1] << ","
202 << (coordDim > 2 ? lmin[2] : 0) << ") x "
203 << " (" << lmax[0] << "," << lmax[1] << ","
204 << (coordDim > 2 ? lmax[2] : 0) << ")" << std::endl;
205 }
206 }
207 }
208
209 // test the origin
210 {
211 for (int i = 0; i < coordDim; i++) pointDrop[i] = 0.;
212 try {
213 part = problem->getSolution().pointAssign(coordDim, pointDrop);
214 }
215 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " pointAssign -- Origin");
216
217 std::cout << me << " OriginPoint (" << pointDrop[0];
218 if (coordDim > 1) std::cout << " " << pointDrop[1];
219 if (coordDim > 2) std::cout << " " << pointDrop[2];
220 std::cout << ") part " << part << std::endl;
221 }
222
223 // test point with negative coordinates
224 {
225 for (int i = 0; i < coordDim; i++) pointDrop[i] = -100.+i;
226 try {
227 part = problem->getSolution().pointAssign(coordDim, pointDrop);
228 }
229 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " pointAssign -- Negative Point");
230 std::cout << me << " NegativePoint (" << pointDrop[0];
231 if (coordDim > 1) std::cout << " " << pointDrop[1];
232 if (coordDim > 2) std::cout << " " << pointDrop[2];
233 std::cout << ") part " << part << std::endl;
234 }
235
236 // test a point that's way out there
237 {
238 for (int i = 0; i < coordDim; i++) pointDrop[i] = i*5;
239 try {
240 part = problem->getSolution().pointAssign(coordDim, pointDrop);
241 }
242 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " pointAssign -- i*5 Point");
243 std::cout << me << " i*5-Point (" << pointDrop[0];
244 if (coordDim > 1) std::cout << " " << pointDrop[1];
245 if (coordDim > 2) std::cout << " " << pointDrop[2];
246 std::cout << ") part " << part << std::endl;
247 }
248
249 // test a point that's way out there
250 {
251 for (int i = 0; i < coordDim; i++) pointDrop[i] = 10+i*5;
252 try {
253 part = problem->getSolution().pointAssign(coordDim, pointDrop);
254 }
255 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " pointAssign -- WoopWoop");
256 std::cout << me << " WoopWoop-Point (" << pointDrop[0];
257 if (coordDim > 1) std::cout << " " << pointDrop[1];
258 if (coordDim > 2) std::cout << " " << pointDrop[2];
259 std::cout << ") part " << part << std::endl;
260 }
261
262 delete [] pointDrop;
263 return ierr;
264}
265
266template <typename Adapter>
269 RCP<tMVector_t> &coords)
270{
271 int ierr = 0;
272
273 // boxAssign tests
274 int coordDim = coords->getNumVectors();
275 zscalar_t *lower = new zscalar_t[coordDim];
276 zscalar_t *upper = new zscalar_t[coordDim];
277
278 char mechar[10];
279 sprintf(mechar, "%d", problem->getComm()->getRank());
280 string me(mechar);
281
282 const std::vector<Zoltan2::coordinateModelPartBox>
283 pBoxes = problem->getSolution().getPartBoxesView();
284 size_t nBoxes = pBoxes.size();
285
286 // test a box that is smaller than a part
287 {
288 size_t nparts;
289 typename Adapter::part_t *parts;
290 size_t pickabox = nBoxes / 2;
291 for (int i = 0; i < coordDim; i++) {
292 zscalar_t dd = 0.2 * (pBoxes[pickabox].getlmaxs()[i] -
293 pBoxes[pickabox].getlmins()[i]);
294 lower[i] = pBoxes[pickabox].getlmins()[i] + dd;
295 upper[i] = pBoxes[pickabox].getlmaxs()[i] - dd;
296 }
297 try {
298 problem->getSolution().boxAssign(coordDim, lower, upper,
299 nparts, &parts);
300 }
301 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- smaller");
302 if (nparts > 1) {
303 std::cout << me << " FAIL boxAssign error: smaller test, nparts > 1"
304 << std::endl;
305 ierr++;
306 }
307 print_boxAssign_result<Adapter>("smallerbox", coordDim,
308 lower, upper, nparts, parts);
309 delete [] parts;
310 }
311
312 // test a box that is larger than a part
313 {
314 size_t nparts;
315 typename Adapter::part_t *parts;
316 size_t pickabox = nBoxes / 2;
317 for (int i = 0; i < coordDim; i++) {
318 zscalar_t dd = 0.2 * (pBoxes[pickabox].getlmaxs()[i] -
319 pBoxes[pickabox].getlmins()[i]);
320 lower[i] = pBoxes[pickabox].getlmins()[i] - dd;
321 upper[i] = pBoxes[pickabox].getlmaxs()[i] + dd;
322 }
323 try {
324 problem->getSolution().boxAssign(coordDim, lower, upper,
325 nparts, &parts);
326 }
327 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- larger");
328
329 // larger box should have at least two parts in it for k > 1.
330 if ((nBoxes > 1) && (nparts < 2)) {
331 std::cout << me << " FAIL boxAssign error: "
332 << "larger test, nparts < 2"
333 << std::endl;
334 ierr++;
335 }
336
337 // parts should include pickabox's part
338 bool found_pickabox = 0;
339 for (size_t i = 0; i < nparts; i++)
340 if (parts[i] == pBoxes[pickabox].getpId()) {
341 found_pickabox = 1;
342 break;
343 }
344 if (!found_pickabox) {
345 std::cout << me << " FAIL boxAssign error: "
346 << "larger test, pickabox not found"
347 << std::endl;
348 ierr++;
349 }
350
351 print_boxAssign_result<Adapter>("largerbox", coordDim,
352 lower, upper, nparts, parts);
353 delete [] parts;
354 }
355
356 // test a box that includes all parts
357 {
358 size_t nparts;
359 typename Adapter::part_t *parts;
360 for (int i = 0; i < coordDim; i++) {
361 lower[i] = std::numeric_limits<zscalar_t>::max();
362 upper[i] = std::numeric_limits<zscalar_t>::min();
363 }
364 for (size_t j = 0; j < nBoxes; j++) {
365 for (int i = 0; i < coordDim; i++) {
366 if (pBoxes[j].getlmins()[i] <= lower[i])
367 lower[i] = pBoxes[j].getlmins()[i];
368 if (pBoxes[j].getlmaxs()[i] >= upper[i])
369 upper[i] = pBoxes[j].getlmaxs()[i];
370 }
371 }
372 try {
373 problem->getSolution().boxAssign(coordDim, lower, upper,
374 nparts, &parts);
375 }
376 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- global");
377
378 // global box should have all parts
379 if (nparts != nBoxes) {
380 std::cout << me << " FAIL boxAssign error: "
381 << "global test, nparts found " << nparts
382 << " != num global parts " << nBoxes
383 << std::endl;
384 ierr++;
385 }
386 print_boxAssign_result<Adapter>("globalbox", coordDim,
387 lower, upper, nparts, parts);
388 delete [] parts;
389 }
390
391 // test a box that is bigger than the entire domain
392 // Assuming lower and upper are still set to the global box boundary
393 // from the previous test
394 {
395 size_t nparts;
396 typename Adapter::part_t *parts;
397 for (int i = 0; i < coordDim; i++) {
398 lower[i] -= 2.;
399 upper[i] += 2.;
400 }
401
402 try {
403 problem->getSolution().boxAssign(coordDim, lower, upper,
404 nparts, &parts);
405 }
406 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- bigdomain");
407
408 // bigdomain box should have all parts
409 if (nparts != nBoxes) {
410 std::cout << me << " FAIL boxAssign error: "
411 << "bigdomain test, nparts found " << nparts
412 << " != num global parts " << nBoxes
413 << std::endl;
414 ierr++;
415 }
416 print_boxAssign_result<Adapter>("bigdomainbox", coordDim,
417 lower, upper, nparts, parts);
418 delete [] parts;
419 }
420
421 // test a box that is way out there
422 // Assuming lower and upper are still set to at least the global box
423 // boundary from the previous test
424 {
425 size_t nparts;
426 typename Adapter::part_t *parts;
427 for (int i = 0; i < coordDim; i++) {
428 lower[i] = upper[i] + 10;
429 upper[i] += 20;
430 }
431
432 try {
433 problem->getSolution().boxAssign(coordDim, lower, upper,
434 nparts, &parts);
435 }
436 CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- out there");
437
438 // For now, boxAssign returns zero if there is no box overlap.
439 // TODO: this result should be changed in boxAssign definition
440 if (nparts != 0) {
441 std::cout << me << " FAIL boxAssign error: "
442 << "outthere test, nparts found " << nparts
443 << " != zero"
444 << std::endl;
445 ierr++;
446 }
447 print_boxAssign_result<Adapter>("outthere box", coordDim,
448 lower, upper, nparts, parts);
449 delete [] parts;
450 }
451
452 delete [] lower;
453 delete [] upper;
454 return ierr;
455}
456
457void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP<const Teuchos::Comm<int> > & comm){
458 std::string input = "";
459 char inp[25000];
460 for(int i = 0; i < 25000; ++i){
461 inp[i] = 0;
462 }
463
464 bool fail = false;
465 if(comm->getRank() == 0){
466
467 std::fstream inParam(paramFileName.c_str());
468 if (inParam.fail())
469 {
470 fail = true;
471 }
472 if(!fail)
473 {
474 std::string tmp = "";
475 getline (inParam,tmp);
476 while (!inParam.eof()){
477 if(tmp != ""){
478 tmp = trim_copy(tmp);
479 if(tmp != ""){
480 input += tmp + "\n";
481 }
482 }
483 getline (inParam,tmp);
484 }
485 inParam.close();
486 for (size_t i = 0; i < input.size(); ++i){
487 inp[i] = input[i];
488 }
489 }
490 }
491
492
493
494 int size = input.size();
495 if(fail){
496 size = -1;
497 }
498 comm->broadcast(0, sizeof(int), (char*) &size);
499 if(size == -1){
500 throw std::runtime_error("File " + paramFileName + " cannot be opened.");
501 }
502 comm->broadcast(0, size, inp);
503 std::istringstream inParam(inp);
504 string str;
505 getline (inParam,str);
506 while (!inParam.eof()){
507 if(str[0] != param_comment){
508 size_t pos = str.find('=');
509 if(pos == string::npos){
510 throw std::runtime_error("Invalid Line:" + str + " in parameter file");
511 }
512 string paramname = trim_copy(str.substr(0,pos));
513 string paramvalue = trim_copy(str.substr(pos + 1));
514 geoparams.set(paramname, paramvalue);
515 }
516 getline (inParam,str);
517 }
518}
519
520template<class bv_use_node_t>
521int compareWithBasicVectorAdapterTest(RCP<const Teuchos::Comm<int> > &comm,
522 Teuchos::RCP<Teuchos::ParameterList> params,
524 RCP<tMVector_t> coords,
525 Zoltan2::XpetraMultiVectorAdapter<tMVector_t>::scalar_t ** weights = NULL, int numWeightsPerCoord = 0) {
526
528
529 // Run a test with BasicVectorAdapter and xyzxyz format coordinates
530 const int bvme = comm->getRank();
531 const inputAdapter_t::lno_t bvlen =
532 inputAdapter_t::lno_t(coords->getLocalLength());
533 const size_t bvnvecs = coords->getNumVectors();
534 const size_t bvsize = coords->getNumVectors() * coords->getLocalLength();
535
536 ArrayRCP<inputAdapter_t::scalar_t> *bvtpetravectors =
537 new ArrayRCP<inputAdapter_t::scalar_t>[bvnvecs];
538 for (size_t i = 0; i < bvnvecs; i++)
539 bvtpetravectors[i] = coords->getDataNonConst(i);
540 int idx = 0;
541 inputAdapter_t::gno_t *bvgids = new
542 inputAdapter_t::gno_t[coords->getLocalLength()];
543 inputAdapter_t::scalar_t *bvcoordarr = new inputAdapter_t::scalar_t[bvsize];
544 for (inputAdapter_t::lno_t j = 0; j < bvlen; j++) {
545 bvgids[j] = coords->getMap()->getGlobalElement(j);
546 for (size_t i = 0; i < bvnvecs; i++) {
547 bvcoordarr[idx++] = bvtpetravectors[i][j];
548 }
549 }
550
551 // my test node type
552 typedef Zoltan2::BasicUserTypes<inputAdapter_t::scalar_t,
553 inputAdapter_t::lno_t,
554 inputAdapter_t::gno_t,
555 bv_use_node_t> bvtypes_t;
556 typedef Zoltan2::BasicVectorAdapter<bvtypes_t> bvadapter_t;
557 std::vector<const inputAdapter_t::scalar_t *> bvcoords(bvnvecs);
558 std::vector<int> bvstrides(bvnvecs);
559 for (size_t i = 0; i < bvnvecs; i++) {
560 bvcoords[i] = &bvcoordarr[i];
561 bvstrides[i] = bvnvecs;
562 }
563 std::vector<const inputAdapter_t::scalar_t *> bvwgts;
564 std::vector<int> bvwgtstrides;
565
566 if(numWeightsPerCoord > 0) {
567 bvwgts = std::vector<const inputAdapter_t::scalar_t *>(numWeightsPerCoord);
568 bvwgtstrides = std::vector<int>(coords->getLocalLength());
569 for (size_t i = 0; i < coords->getLocalLength(); i++) {
570 bvwgtstrides[i] = numWeightsPerCoord;
571 }
572 for (int i = 0; i < numWeightsPerCoord; i++) {
573 bvwgts[i] = weights[i];
574 }
575 }
576
577 bvadapter_t bvia(bvlen, bvgids, bvcoords, bvstrides,
578 bvwgts, bvwgtstrides);
579
581 try {
582 bvproblem = new Zoltan2::PartitioningProblem<bvadapter_t>(&bvia,
583 params.getRawPtr(),
584 comm);
585 }
586 CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
587
588 try {
589 bvproblem->solve();
590 }
592
593 int ierr = 0;
594
595 // Compare with MultiVectorAdapter result
596 for (inputAdapter_t::lno_t i = 0; i < bvlen; i++) {
597 if (problem->getSolution().getPartListView()[i] !=
598 bvproblem->getSolution().getPartListView()[i]) {
599 std::cout << bvme << " " << i << " "
600 << coords->getMap()->getGlobalElement(i) << " " << bvgids[i]
601 << ": XMV " << problem->getSolution().getPartListView()[i]
602 << "; BMV " << bvproblem->getSolution().getPartListView()[i]
603 << " : FAIL" << std::endl;
604 ++ierr;
605 }
606 /* For debugging - plot all success as well
607 else {
608 std::cout << bvme << " " << i << " "
609 << coords->getMap()->getGlobalElement(i) << " " << bvgids[i]
610 << ": XMV " << problem->getSolution().getPartListView()[i]
611 << "; BMV " << bvproblem->getSolution().getPartListView()[i]
612 << " : PASS" << std::endl;
613 }
614 */
615 }
616
617 delete [] bvgids;
618 delete [] bvcoordarr;
619 delete [] bvtpetravectors;
620 delete bvproblem;
621
622 if (coords->getGlobalLength() < 40) {
623 int len = coords->getLocalLength();
624 const inputAdapter_t::part_t *zparts =
625 problem->getSolution().getPartListView();
626 for (int i = 0; i < len; i++)
627 std::cout << comm->getRank()
628 << " lid " << i
629 << " gid " << coords->getMap()->getGlobalElement(i)
630 << " part " << zparts[i] << std::endl;
631 }
632
633 return ierr;
634}
635
636template<class bv_use_node_t>
637int GeometricGenInterface(RCP<const Teuchos::Comm<int> > &comm,
638 int numTeams, int numParts, float imbalance,
639 std::string paramFile, std::string pqParts,
640 std::string pfname,
641 int k,
642 int migration_check_option,
643 int migration_all_to_all_type,
644 zscalar_t migration_imbalance_cut_off,
645 int migration_processor_assignment_type,
646 int migration_doMigration_type,
647 bool uvm,
648 bool print_details,
649 bool test_boxes,
650 bool rectilinear,
651 int mj_premigration_option,
652 int mj_premigration_coordinate_cutoff
653)
654{
655 int ierr = 0;
656 Teuchos::ParameterList geoparams("geo params");
657 readGeoGenParams(paramFile, geoparams, comm);
658
661 comm);
662
663 int coord_dim = gg->getCoordinateDimension();
664 int numWeightsPerCoord = gg->getNumWeights();
665 zlno_t numLocalPoints = gg->getNumLocalCoords();
666 zgno_t numGlobalPoints = gg->getNumGlobalCoords();
667 zscalar_t **coords = new zscalar_t * [coord_dim];
668 for(int i = 0; i < coord_dim; ++i){
669 coords[i] = new zscalar_t[numLocalPoints];
670 }
671 gg->getLocalCoordinatesCopy(coords);
672 zscalar_t **weight = NULL;
673 if (numWeightsPerCoord) {
674 weight= new zscalar_t * [numWeightsPerCoord];
675 for(int i = 0; i < numWeightsPerCoord; ++i){
676 weight[i] = new zscalar_t[numLocalPoints];
677 }
678 gg->getLocalWeightsCopy(weight);
679 }
680
681 delete gg;
682
683 // Run 1st test with MV which always runs UVM on
684 RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
685 new Tpetra::Map<zlno_t, zgno_t, znode_t>(numGlobalPoints,
686 numLocalPoints, 0, comm));
687 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
688 for (int i=0; i < coord_dim; i++){
689 if(numLocalPoints > 0){
690 Teuchos::ArrayView<const zscalar_t> a(coords[i], numLocalPoints);
691 coordView[i] = a;
692 }
693 else {
694 Teuchos::ArrayView<const zscalar_t> a;
695 coordView[i] = a;
696 }
697 }
698 RCP<tMVector_t> tmVector = RCP<tMVector_t>(new
699 tMVector_t(mp, coordView.view(0, coord_dim),
700 coord_dim));
701 std::vector<const zscalar_t *> weights;
702 if(numWeightsPerCoord){
703 for (int i = 0; i < numWeightsPerCoord;++i){
704 weights.push_back(weight[i]);
705 }
706 }
707 std::vector<int> stride;
710 //inputAdapter_t ia(coordsConst);
711 inputAdapter_t *ia = new inputAdapter_t(tmVector, weights, stride);
712
713 Teuchos::RCP<Teuchos::ParameterList> params;
714
715 //Teuchos::ParameterList params("test params");
716 if(pfname != ""){
717 params = Teuchos::getParametersFromXmlFile(pfname);
718 }
719 else {
720 params =RCP<Teuchos::ParameterList>(new Teuchos::ParameterList, true);
721 }
722/*
723 params->set("memory_output_stream" , "std::cout");
724 params->set("memory_procs" , 0);
725 */
726
727 params->set("timer_output_stream" , "std::cout");
728
729 params->set("algorithm", "multijagged");
730 if (test_boxes)
731 params->set("mj_keep_part_boxes", true); // bool parameter
732 if (rectilinear)
733 params->set("rectilinear", true ); // bool parameter
734
735 if(imbalance > 1)
736 params->set("imbalance_tolerance", double(imbalance));
737 params->set("mj_premigration_option", mj_premigration_option);
738 if (mj_premigration_coordinate_cutoff > 0){
739 params->set("mj_premigration_coordinate_count",
740 mj_premigration_coordinate_cutoff);
741 }
742
743 if(pqParts != "")
744 params->set("mj_parts", pqParts);
745 if(numTeams > 0) {
746 params->set("mj_num_teams", numTeams);
747 }
748 if(numParts > 0)
749 params->set("num_global_parts", numParts);
750 if (k > 0)
751 params->set("mj_concurrent_part_count", k);
752 if(migration_check_option >= 0)
753 params->set("mj_migration_option", migration_check_option);
754 if(migration_imbalance_cut_off >= 0)
755 params->set("mj_minimum_migration_imbalance",
756 double(migration_imbalance_cut_off));
757
759 try {
761 params.getRawPtr(),
762 comm);
763 }
764 CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
765
766 try {
767 problem->solve();
768 }
770 {
771 ierr += compareWithBasicVectorAdapterTest<bv_use_node_t>(
772 comm, params, problem, tmVector,
773 weight, numWeightsPerCoord);
774 }
775
776 // create metric object
777
778 RCP<quality_t> metricObject =
779 rcp(new quality_t(ia,params.getRawPtr(),comm,&problem->getSolution()));
780
781 if (comm->getRank() == 0){
782 metricObject->printMetrics(std::cout);
783 }
784
785 problem->printTimers();
786
787 // run pointAssign tests
788 if (test_boxes) {
789 ierr += run_pointAssign_tests<inputAdapter_t>(problem, tmVector,
790 print_details);
791 ierr += run_boxAssign_tests<inputAdapter_t>(problem, tmVector);
792 }
793
794 if(numWeightsPerCoord){
795 for(int i = 0; i < numWeightsPerCoord; ++i) {
796 delete [] weight[i];
797 }
798 delete [] weight;
799 }
800 if(coord_dim){
801 for(int i = 0; i < coord_dim; ++i) {
802 delete [] coords[i];
803 }
804 delete [] coords;
805 }
806
807 delete problem;
808 delete ia;
809 return ierr;
810}
811
812template<class bv_use_node_t>
814 RCP<const Teuchos::Comm<int> > &comm,
815 int numTeams,
816 int numParts,
817 float imbalance,
818 std::string fname,
819 std::string pqParts,
820 std::string pfname,
821 int k,
822 int migration_check_option,
823 int migration_all_to_all_type,
824 zscalar_t migration_imbalance_cut_off,
825 int migration_processor_assignment_type,
826 int migration_doMigration_type,
827 bool uvm,
828 bool print_details,
829 bool test_boxes,
830 bool rectilinear,
831 int mj_premigration_option,
832 int mj_premigration_coordinate_cutoff
833)
834{
835 int ierr = 0;
836 //std::string fname("simple");
837 //std::cout << "running " << fname << std::endl;
838
839 UserInputForTests uinput(testDataFilePath, fname, comm, true);
840
841 RCP<tMVector_t> coords = uinput.getUICoordinates();
842
845 inputAdapter_t *ia = new inputAdapter_t(coords);
846
847 Teuchos::RCP <Teuchos::ParameterList> params ;
848
849 //Teuchos::ParameterList params("test params");
850 if(pfname != ""){
851 params = Teuchos::getParametersFromXmlFile(pfname);
852 }
853 else {
854 params =RCP <Teuchos::ParameterList> (new Teuchos::ParameterList, true);
855 }
856
857 //params->set("timer_output_stream" , "std::cout");
858 if (test_boxes)
859 params->set("mj_keep_part_boxes", true); // bool parameter
860 if (rectilinear)
861 params->set("rectilinear", true); // bool parameter
862 params->set("algorithm", "multijagged");
863 if(imbalance > 1){
864 params->set("imbalance_tolerance", double(imbalance));
865 }
866
867 if(pqParts != ""){
868 params->set("mj_parts", pqParts);
869 }
870 params->set("mj_premigration_option", mj_premigration_option);
871
872 if(numParts > 0){
873 params->set("num_global_parts", numParts);
874 }
875 if (k > 0){
876 params->set("mj_concurrent_part_count", k);
877 }
878 if(migration_check_option >= 0){
879 params->set("mj_migration_option", migration_check_option);
880 }
881 if(migration_imbalance_cut_off >= 0){
882 params->set("mj_minimum_migration_imbalance",
883 double (migration_imbalance_cut_off));
884 }
885 if (mj_premigration_coordinate_cutoff > 0){
886 params->set("mj_premigration_coordinate_count",
887 mj_premigration_coordinate_cutoff);
888 }
889
891 try {
893 params.getRawPtr(),
894 comm);
895 }
896 CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
897 try {
898 problem->solve();
899 }
901 {
902 ierr += compareWithBasicVectorAdapterTest<bv_use_node_t>(
903 comm, params, problem, coords);
904 }
905
906 // create metric object
907
908 RCP<quality_t> metricObject =
909 rcp(new quality_t(ia,params.getRawPtr(),comm,&problem->getSolution()));
910
911 if (comm->getRank() == 0){
912 metricObject->printMetrics(std::cout);
913 std::cout << "testFromDataFile is done " << std::endl;
914 }
915
916 problem->printTimers();
917
918 // run pointAssign tests
919 if (test_boxes) {
920 ierr += run_pointAssign_tests<inputAdapter_t>(problem, coords,
921 print_details);
922 ierr += run_boxAssign_tests<inputAdapter_t>(problem, coords);
923 }
924
925 delete problem;
926 delete ia;
927 return ierr;
928}
929
930#ifdef hopper_separate_test
931
932template <typename zscalar_t, typename zlno_t>
933void getCoords(zscalar_t **&coords, zlno_t &numLocal, int &dim, string fileName){
934 FILE *f = fopen(fileName.c_str(), "r");
935 if (f == NULL){
936 std::cout << fileName << " cannot be opened" << std::endl;
937 std::terminate();
938 }
939 fscanf(f, "%d", &numLocal);
940 fscanf(f, "%d", &dim);
941 coords = new zscalar_t *[ dim];
942 for (int i = 0; i < dim; ++i){
943 coords[i] = new zscalar_t[numLocal];
944 }
945 for (int i = 0; i < dim; ++i){
946 for (zlno_t j = 0; j < numLocal; ++j){
947 fscanf(f, "%lf", &(coords[i][j]));
948 }
949 }
950 fclose(f);
951 std::cout << "done reading:" << fileName << std::endl;
952}
953
954int testFromSeparateDataFiles(
955 RCP<const Teuchos::Comm<int> > &comm,
956 int numTeams,
957 int numParts,
958 float imbalance,
959 std::string fname,
960 std::string pqParts,
961 std::string pfname,
962 int k,
963 int migration_check_option,
964 int migration_all_to_all_type,
965 zscalar_t migration_imbalance_cut_off,
966 int migration_processor_assignment_type,
967 int migration_doMigration_type,
968 bool uvm,
969 bool test_boxes,
970 bool rectilinear,
971 int mj_premigration_option
972)
973{
974 //std::string fname("simple");
975 //std::cout << "running " << fname << std::endl;
976
977 int ierr = 0;
978 int mR = comm->getRank();
979 if (mR == 0) std::cout << "size of zscalar_t:" << sizeof(zscalar_t) << std::endl;
980 string tFile = fname +"_" + std::to_string(mR) + ".mtx";
981 zscalar_t **double_coords;
982 zlno_t numLocal = 0;
983 int dim = 0;
984 getCoords<zscalar_t, zlno_t>(double_coords, numLocal, dim, tFile);
985 //UserInputForTests uinput(testDataFilePath, fname, comm, true);
986 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(dim);
987 for (int i=0; i < dim; i++){
988 if(numLocal > 0){
989 Teuchos::ArrayView<const zscalar_t> a(double_coords[i], numLocal);
990 coordView[i] = a;
991 } else{
992 Teuchos::ArrayView<const zscalar_t> a;
993 coordView[i] = a;
994 }
995 }
996
997 zgno_t numGlobal;
998 zgno_t nL = numLocal;
999 Teuchos::Comm<int> *tcomm = (Teuchos::Comm<int> *)comm.getRawPtr();
1000
1001 reduceAll<int, zgno_t>(
1002 *tcomm,
1003 Teuchos::REDUCE_SUM,
1004 1,
1005 &nL,
1006 &numGlobal
1007 );
1008
1009
1010 RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
1011 new Tpetra::Map<zlno_t, zgno_t, znode_t> (numGlobal, numLocal, 0, comm));
1012 RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >coords = RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >(
1013 new Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>( mp, coordView.view(0, dim), dim));
1014
1015
1016 RCP<const tMVector_t> coordsConst = rcp_const_cast<const tMVector_t>(coords);
1017
1018 typedef Zoltan2::XpetraMultiVectorAdapter<tMVector_t> inputAdapter_t;
1020
1021 inputAdapter_t *ia = new inputAdapter_t(coordsConst);
1022
1023
1024
1025 Teuchos::RCP <Teuchos::ParameterList> params ;
1026
1027 //Teuchos::ParameterList params("test params");
1028 if(pfname != ""){
1029 params = Teuchos::getParametersFromXmlFile(pfname);
1030 }
1031 else {
1032 params =RCP <Teuchos::ParameterList> (new Teuchos::ParameterList, true);
1033 }
1034
1035 //params->set("timer_output_stream" , "std::cout");
1036 params->set("algorithm", "multijagged");
1037 if(imbalance > 1){
1038 params->set("imbalance_tolerance", double(imbalance));
1039 }
1040
1041 params->set("mj_premigration_option", mj_premigration_option);
1042 if(pqParts != ""){
1043 params->set("mj_parts", pqParts);
1044 }
1045 if(numTeams > 0){
1046 params->set("mj_num_teams", numTeams);
1047 }
1048 if(numParts > 0){
1049 params->set("num_global_parts", numParts);
1050 }
1051 if (k > 0){
1052 params->set("parallel_part_calculation_count", k);
1053 }
1054 if(migration_processor_assignment_type >= 0){
1055 params->set("migration_processor_assignment_type", migration_processor_assignment_type);
1056 }
1057 if(migration_check_option >= 0){
1058 params->set("migration_check_option", migration_check_option);
1059 }
1060 if(migration_all_to_all_type >= 0){
1061 params->set("migration_all_to_all_type", migration_all_to_all_type);
1062 }
1063 if(migration_imbalance_cut_off >= 0){
1064 params->set("migration_imbalance_cut_off",
1065 double (migration_imbalance_cut_off));
1066 }
1067 if (migration_doMigration_type >= 0){
1068 params->set("migration_doMigration_type", int (migration_doMigration_type));
1069 }
1070 if (test_boxes)
1071 params->set("mj_keep_part_boxes", true); // bool parameter
1072 if (rectilinear)
1073 params->set("rectilinear", true); // bool parameter
1074
1076 try {
1077 problem =
1079 params.getRawPtr(),
1080 comm);
1081 }
1082 CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
1083
1084 try {
1085 problem->solve();
1086 }
1088 {
1089 ierr += compareWithBasicVectorAdapterTest<bv_use_node_t>(
1090 comm, params, problem, coords);
1091 }
1092
1093 if (coordsConst->getGlobalLength() < 40) {
1094 int len = coordsConst->getLocalLength();
1095 const inputAdapter_t::part_t *zparts =
1096 problem->getSolution().getPartListView();
1097 for (int i = 0; i < len; i++)
1098 std::cout << comm->getRank()
1099 << " gid " << coords->getMap()->getGlobalElement(i)
1100 << " part " << zparts[i] << std::endl;
1101 }
1102
1103 //create metric object
1104
1105 RCP<quality_t> metricObject =
1106 rcp(new quality_t(ia,params.getRawPtr(),comm,&problem->getSolution()));
1107
1108 if (comm->getRank() == 0){
1109 metricObject->printMetrics(std::cout);
1110 std::cout << "testFromDataFile is done " << std::endl;
1111 }
1112
1113 problem->printTimers();
1114
1115 // run pointAssign tests
1116 if (test_boxes) {
1117 ierr += run_pointAssign_tests<inputAdapter_t>(problem, coords,
1118 print_details);
1119 ierr += run_boxAssign_tests<inputAdapter_t>(problem, coords);
1120 }
1121
1122 delete problem;
1123 delete ia;
1124 return ierr;
1125}
1126#endif
1127
1128
1129
1130string convert_to_string(char *args){
1131 string tmp = "";
1132 for(int i = 0; args[i] != 0; i++)
1133 tmp += args[i];
1134 return tmp;
1135}
1136bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline){
1137 std::stringstream stream(std::stringstream::in | std::stringstream::out);
1138 stream << argumentline;
1139 getline(stream, argumentid, '=');
1140 if (stream.eof()){
1141 return false;
1142 }
1143 stream >> argumentValue;
1144 return true;
1145}
1146
1148 int narg,
1149 char **arg,
1150 int &numTeams,
1151 int &numParts,
1152 float &imbalance ,
1153 string &pqParts,
1154 int &opt,
1155 std::string &fname,
1156 std::string &pfname,
1157 int &k,
1158 int &migration_check_option,
1159 int &migration_all_to_all_type,
1160 zscalar_t &migration_imbalance_cut_off,
1161 int &migration_processor_assignment_type,
1162 int &migration_doMigration_type,
1163 bool &uvm,
1164 bool &print_details,
1165 bool &test_boxes,
1166 bool &rectilinear,
1167 int &mj_premigration_option,
1168 int &mj_coordinate_cutoff
1169)
1170{
1171 bool isCset = false;
1172 bool isPset = false;
1173 bool isFset = false;
1174 bool isPFset = false;
1175
1176 for(int i = 0; i < narg; ++i){
1177 string tmp = convert_to_string(arg[i]);
1178 string identifier = "";
1179 long long int value = -1; double fval = -1;
1180 if(!getArgumentValue(identifier, fval, tmp)) continue;
1181 value = (long long int) (fval);
1182
1183 if(identifier == "W"){
1184 if(value == 0 || value == 1){
1185 print_details = (value == 0 ? false : true);
1186 } else {
1187 throw std::runtime_error("Invalid argument at " + tmp);
1188 }
1189 }
1190 else if(identifier == "UVM"){
1191 if(value == 0 || value == 1){
1192 uvm = (value == 0 ? false : true);
1193 } else {
1194 throw std::runtime_error("Invalid argument at " + tmp);
1195 }
1196 }
1197 else if(identifier == "T"){
1198 if(value > 0){
1199 numTeams=value;
1200 } else {
1201 throw std::runtime_error("Invalid argument at " + tmp);
1202 }
1203 } else if(identifier == "C"){
1204 if(value > 0){
1205 numParts=value;
1206 isCset = true;
1207 } else {
1208 throw std::runtime_error("Invalid argument at " + tmp);
1209 }
1210 } else if(identifier == "P"){
1211 std::stringstream stream(std::stringstream::in | std::stringstream::out);
1212 stream << tmp;
1213 string ttmp;
1214 getline(stream, ttmp, '=');
1215 stream >> pqParts;
1216 isPset = true;
1217 }else if(identifier == "I"){
1218 if(fval > 0){
1219 imbalance=fval;
1220 } else {
1221 throw std::runtime_error("Invalid argument at " + tmp);
1222 }
1223 } else if(identifier == "MI"){
1224 if(fval > 0){
1225 migration_imbalance_cut_off=fval;
1226 } else {
1227 throw std::runtime_error("Invalid argument at " + tmp);
1228 }
1229 } else if(identifier == "MO"){
1230 if(value >=0 ){
1231 migration_check_option = value;
1232 } else {
1233 throw std::runtime_error("Invalid argument at " + tmp);
1234 }
1235 } else if(identifier == "AT"){
1236 if(value >=0 ){
1237 migration_processor_assignment_type = value;
1238 } else {
1239 throw std::runtime_error("Invalid argument at " + tmp);
1240 }
1241 }
1242
1243 else if(identifier == "MT"){
1244 if(value >=0 ){
1245 migration_all_to_all_type = value;
1246 } else {
1247 throw std::runtime_error("Invalid argument at " + tmp);
1248 }
1249 }
1250 else if(identifier == "PCC"){
1251 if(value >=0 ){
1252 mj_coordinate_cutoff = value;
1253 } else {
1254 throw std::runtime_error("Invalid argument at " + tmp);
1255 }
1256 }
1257
1258 else if(identifier == "PM"){
1259 if(value >=0 ){
1260 mj_premigration_option = value;
1261 } else {
1262 throw std::runtime_error("Invalid argument at " + tmp);
1263 }
1264 }
1265
1266 else if(identifier == "DM"){
1267 if(value >=0 ){
1268 migration_doMigration_type = value;
1269 } else {
1270 throw std::runtime_error("Invalid argument at " + tmp);
1271 }
1272 }
1273 else if(identifier == "F"){
1274 std::stringstream stream(std::stringstream::in | std::stringstream::out);
1275 stream << tmp;
1276 getline(stream, fname, '=');
1277
1278 stream >> fname;
1279 isFset = true;
1280 }
1281 else if(identifier == "PF"){
1282 std::stringstream stream(std::stringstream::in | std::stringstream::out);
1283 stream << tmp;
1284 getline(stream, pfname, '=');
1285
1286 stream >> pfname;
1287 isPFset = true;
1288 }
1289
1290 else if(identifier == "O"){
1291 if(value >= 0 && value <= 3){
1292 opt = value;
1293 } else {
1294 throw std::runtime_error("Invalid argument at " + tmp);
1295 }
1296 }
1297 else if(identifier == "K"){
1298 if(value >=0 ){
1299 k = value;
1300 } else {
1301 throw std::runtime_error("Invalid argument at " + tmp);
1302 }
1303 }
1304 else if(identifier == "TB"){
1305 if(value >=0 ){
1306 test_boxes = (value == 0 ? false : true);
1307 } else {
1308 throw std::runtime_error("Invalid argument at " + tmp);
1309 }
1310 }
1311 else if(identifier == "R"){
1312 if(value >=0 ){
1313 rectilinear = (value == 0 ? false : true);
1314 } else {
1315 throw std::runtime_error("Invalid argument at " + tmp);
1316 }
1317 }
1318 else {
1319 throw std::runtime_error("Invalid argument at " + tmp);
1320 }
1321
1322 }
1323 if(!( (isCset || isPset || isPFset) && isFset)){
1324 throw std::runtime_error("(C || P || PF) && F are mandatory arguments.");
1325 }
1326
1327}
1328
1329void print_usage(char *executable){
1330 std::cout << "\nUsage:" << std::endl;
1331 std::cout << executable << " arglist" << std::endl;
1332 std::cout << "arglist:" << std::endl;
1333 std::cout << "\tT=numTeams: numTeams > 0" << std::endl;
1334 std::cout << "\tC=numParts: numParts > 0" << std::endl;
1335 std::cout << "\tP=MultiJaggedPart: Example: P=512,512" << std::endl;
1336 std::cout << "\tI=imbalance: Example I=1.03 (ignored for now.)" << std::endl;
1337 std::cout << "\tF=filePath: When O=0 the path of the coordinate input file, for O>1 the path to the geometric generator parameter file." << std::endl;
1338 std::cout << "\tO=input option: O=0 for reading coordinate from file, O>0 for generating coordinate from coordinate generator file. Default will run geometric generator." << std::endl;
1339 std::cout << "\tK=concurrent part calculation input: K>0." << std::endl;
1340 std::cout << "\tMI=migration_imbalance_cut_off: MI=1.35. " << std::endl;
1341 std::cout << "\tMT=migration_all_to_all_type: 0 for alltoallv, 1 for Zoltan_Comm, 2 for Zoltan2 Distributor object(Default 1)." << std::endl;
1342 std::cout << "\tMO=migration_check_option: 0 for decision on imbalance, 1 for forcing migration, >1 for avoiding migration. (Default-0)" << std::endl;
1343 std::cout << "\tAT=migration_processor_assignment_type. 0-for assigning procs with respect to proc ownment, otherwise, assignment with respect to proc closeness." << std::endl;
1344 std::cout << "Example:\n" << executable << " P=2,2,2 C=8 F=simple O=0" << std::endl;
1345}
1346
1347int main(int narg, char *arg[])
1348{
1349 Tpetra::ScopeGuard tscope(&narg, &arg);
1350 Teuchos::RCP<const Teuchos::Comm<int> > tcomm = Tpetra::getDefaultComm();
1351
1352 int rank = tcomm->getRank();
1353
1354
1355 int numTeams = 0; // will use default if not set
1356 int numParts = -10;
1357 float imbalance = -1.03;
1358 int k = -1;
1359
1360 string pqParts = "";
1361 int opt = 1;
1362 std::string fname = "";
1363 std::string paramFile = "";
1364
1365
1366 int migration_check_option = -2;
1367 int migration_all_to_all_type = -1;
1368 zscalar_t migration_imbalance_cut_off = -1.15;
1369 int migration_processor_assignment_type = -1;
1370 int migration_doMigration_type = -1;
1371 int mj_premigration_option = 0;
1372 int mj_premigration_coordinate_cutoff = 0;
1373
1374 bool uvm = true;
1375 bool print_details = true;
1376 bool test_boxes = false;
1377 bool rectilinear = false;
1378
1379 // make a new node type so we can run BasicVectorAdapter with UVM off
1380 // The Tpetra MV will still run with UVM on and we'll compare the results.
1381 // For Serial/OpenMP the 2nd test will be turned off at the CMake level.
1382 // For CUDA we control uvm on/off with parameter uvm set to 0 or 1.
1383 // For HIP uvm is simply always off.
1384 // TODO: Probably this should all change eventually so we don't have a node
1385 // declared like this.
1386#if defined(KOKKOS_ENABLE_CUDA)
1387 using uvm_off_node_t = Tpetra::KokkosCompat::KokkosDeviceWrapperNode<
1388 Kokkos::Cuda, Kokkos::CudaSpace>;
1389#elif defined(KOKKOS_ENABLE_HIP)
1390 using uvm_off_node_t = Tpetra::KokkosCompat::KokkosDeviceWrapperNode<
1391 Kokkos::HIP, Kokkos::HIPSpace>;
1392#endif
1393
1394 try{
1395 try {
1396 getArgVals(
1397 narg,
1398 arg,
1399 numTeams,
1400 numParts,
1401 imbalance ,
1402 pqParts,
1403 opt,
1404 fname,
1405 paramFile,
1406 k,
1407 migration_check_option,
1408 migration_all_to_all_type,
1409 migration_imbalance_cut_off,
1410 migration_processor_assignment_type,
1411 migration_doMigration_type,
1412 uvm,
1413 print_details,
1414 test_boxes,
1415 rectilinear,
1416 mj_premigration_option, mj_premigration_coordinate_cutoff);
1417 }
1418 catch(std::exception &s){
1419 if(tcomm->getRank() == 0){
1420 print_usage(arg[0]);
1421 }
1422 throw s;
1423 }
1424
1425 int ierr = 0;
1426
1427 switch (opt){
1428
1429 case 0:
1430 if(uvm == true) { // true by default, if not CUDA it should be unset
1431 ierr = testFromDataFile<znode_t>(tcomm, numTeams, numParts,
1432 imbalance, fname, pqParts, paramFile, k,
1433 migration_check_option,
1434 migration_all_to_all_type,
1435 migration_imbalance_cut_off,
1436 migration_processor_assignment_type,
1437 migration_doMigration_type, uvm, print_details, test_boxes,
1438 rectilinear,
1439 mj_premigration_option, mj_premigration_coordinate_cutoff);
1440 }
1441 else {
1442#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP)
1443 ierr = testFromDataFile<uvm_off_node_t>(tcomm, numTeams, numParts,
1444 imbalance, fname, pqParts, paramFile, k,
1445 migration_check_option,
1446 migration_all_to_all_type,
1447 migration_imbalance_cut_off,
1448 migration_processor_assignment_type,
1449 migration_doMigration_type, uvm, print_details, test_boxes,
1450 rectilinear,
1451 mj_premigration_option, mj_premigration_coordinate_cutoff);
1452#else
1453 throw std::logic_error("uvm set off but this is not a cuda/hip test.");
1454#endif
1455 }
1456 break;
1457
1458#ifdef hopper_separate_test
1459 case 1:
1460 // TODO: Note made changes here but did not actually run this
1461 // method.
1462 ierr = testFromSeparateDataFiles(tcomm, numTeams, numParts,
1463 imbalance, fname, pqParts, paramFile, k,
1464 migration_check_option,
1465 migration_all_to_all_type,
1466 migration_imbalance_cut_off,
1467 migration_processor_assignment_type,
1468 migration_doMigration_type,uvm, print_details, test_boxes,
1469 rectilinear,
1470 mj_premigration_option, mj_premigration_coordinate_cutoff);
1471 break;
1472#endif
1473 default:
1474 if(uvm == true) { // true by default, if not CUDA it should be unset
1475 ierr = GeometricGenInterface<znode_t>(tcomm, numTeams, numParts,
1476 imbalance, fname, pqParts, paramFile, k,
1477 migration_check_option,
1478 migration_all_to_all_type,
1479 migration_imbalance_cut_off,
1480 migration_processor_assignment_type,
1481 migration_doMigration_type, uvm, print_details, test_boxes,
1482 rectilinear,
1483 mj_premigration_option, mj_premigration_coordinate_cutoff);
1484 }
1485 else {
1486#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP)
1487 ierr = GeometricGenInterface<uvm_off_node_t>(tcomm, numTeams,
1488 numParts, imbalance, fname, pqParts, paramFile, k,
1489 migration_check_option,
1490 migration_all_to_all_type,
1491 migration_imbalance_cut_off,
1492 migration_processor_assignment_type,
1493 migration_doMigration_type, uvm, print_details, test_boxes,
1494 rectilinear,
1495 mj_premigration_option, mj_premigration_coordinate_cutoff);
1496#else
1497 throw std::logic_error("uvm set off but this is not a cuda test.");
1498#endif
1499 }
1500 break;
1501 }
1502
1503 if (rank == 0) {
1504 if (ierr == 0) std::cout << "PASS" << std::endl;
1505 else std::cout << "FAIL" << std::endl;
1506 }
1507 }
1508
1509
1510 catch(std::string &s){
1511 if (rank == 0)
1512 std::cerr << s << std::endl;
1513 }
1514
1515 catch(char * s){
1516 if (rank == 0)
1517 std::cerr << s << std::endl;
1518 }
1519
1520 return 0;
1521}
#define CATCH_EXCEPTIONS_WITH_COUNT(ierr, pp)
int run_pointAssign_tests(Zoltan2::PartitioningProblem< Adapter > *problem, RCP< tMVector_t > &coords, bool print_details)
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")
string convert_to_string(char *args)
bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline)
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)
int testFromDataFile(RCP< const Teuchos::Comm< int > > &comm, int numTeams, int numParts, float imbalance, std::string fname, std::string pqParts, 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_premigration_coordinate_cutoff)
string trim_right_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
#define CATCH_EXCEPTIONS_AND_RETURN(pp)
string trim_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
const char param_comment
void print_usage(char *executable)
void print_boxAssign_result(const char *str, int dim, typename Adapter::scalar_t *lower, typename Adapter::scalar_t *upper, size_t nparts, typename Adapter::part_t *parts)
int compareWithBasicVectorAdapterTest(RCP< const Teuchos::Comm< int > > &comm, Teuchos::RCP< Teuchos::ParameterList > params, Zoltan2::PartitioningProblem< Zoltan2::XpetraMultiVectorAdapter< tMVector_t > > *problem, RCP< tMVector_t > coords, Zoltan2::XpetraMultiVectorAdapter< tMVector_t >::scalar_t **weights=NULL, int numWeightsPerCoord=0)
int GeometricGenInterface(RCP< const Teuchos::Comm< int > > &comm, int numTeams, int numParts, float imbalance, std::string paramFile, std::string pqParts, 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_premigration_coordinate_cutoff)
int run_boxAssign_tests(Zoltan2::PartitioningProblem< Adapter > *problem, RCP< tMVector_t > &coords)
Defines the BasicVectorAdapter class.
Defines the EvaluatePartition class.
Defines the PartitioningProblem class.
Defines the PartitioningSolution class.
common code used by tests
float zscalar_t
Tpetra::Map ::local_ordinal_type zlno_t
std::string testDataFilePath(".")
Tpetra::Map ::global_ordinal_type zgno_t
Defines the XpetraMultiVectorAdapter.
int main()
RCP< tMVector_t > getUICoordinates()
typename InputTraits< User >::scalar_t scalar_t
A simple class that can be the User template argument for an InputAdapter.
BasicVectorAdapter represents a vector (plus optional weights) supplied by the user as pointers to st...
A class that computes and returns quality metrics.
PartitioningProblem sets up partitioning problems for the user.
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
void solve(bool updateInputData=true)
Direct the problem to create a solution.
RCP< const Comm< int > > getComm()
Return the communicator used by the problem.
void printTimers() const
Return the communicator passed to the problem.
static const std::string fail
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
fname
Begin.
Definition validXML.py:19
static ArrayRCP< ArrayRCP< zscalar_t > > weights
void getCoords(void *data, int numGid, int numLid, int numObj, zgno_t *gids, zgno_t *lids, int dim, double *coords, int *ierr)
Zoltan2::EvaluatePartition< matrixAdapter_t > quality_t