Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
15 #include <Zoltan2_TestHelpers.hpp>
20 #include <GeometricGenerator.hpp>
21 
23 
24 #include "Teuchos_XMLParameterListHelpers.hpp"
25 
26 #include <Teuchos_LAPACK.hpp>
27 #include <fstream>
28 #include <string>
29 using Teuchos::RCP;
30 using 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 
86 const 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 
102 string trim_copy(
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 
109 template <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 
133 template <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 
266 template <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 
457 void 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 
520 template<class bv_use_node_t>
521 int 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 
527  typedef Zoltan2::XpetraMultiVectorAdapter<tMVector_t> inputAdapter_t;
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,
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  }
591  CATCH_EXCEPTIONS_AND_RETURN("solve()")
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 
636 template<class bv_use_node_t>
637 int 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;
708  typedef Zoltan2::XpetraMultiVectorAdapter<tMVector_t> inputAdapter_t;
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  }
769  CATCH_EXCEPTIONS_AND_RETURN("solve()")
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 
812 template<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 
843  typedef Zoltan2::XpetraMultiVectorAdapter<tMVector_t> inputAdapter_t;
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  }
900  CATCH_EXCEPTIONS_AND_RETURN("solve()")
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 
932 template <typename zscalar_t, typename zlno_t>
933 void 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 
954 int 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  }
1087  CATCH_EXCEPTIONS_AND_RETURN("solve()")
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 
1130 string 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 }
1136 bool 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 
1329 void 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 
1347 int 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 }
void getCoords(void *data, int numGid, int numLid, int numObj, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids, int dim, double *coords_, int *ierr)
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)
#define CATCH_EXCEPTIONS_WITH_COUNT(ierr, pp)
typename InputTraits< User >::scalar_t scalar_t
string trim_right_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
static ArrayRCP< ArrayRCP< zscalar_t > > weights
void print_usage(char *executable)
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)
void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP< const Teuchos::Comm< int > > &comm)
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
A simple class that can be the User template argument for an InputAdapter.
Zoltan2::EvaluatePartition< matrixAdapter_t > quality_t
int main(int narg, char **arg)
Definition: coloring1.cpp:164
Defines the PartitioningSolution class.
common code used by tests
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)
Defines the XpetraMultiVectorAdapter.
string trim_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
const char param_comment
SparseMatrixAdapter_t::part_t part_t
list fname
Begin.
Definition: validXML.py:19
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)
Defines the EvaluatePartition class.
int run_boxAssign_tests(Zoltan2::PartitioningProblem< Adapter > *problem, RCP< tMVector_t > &coords)
RCP< const Comm< int > > getComm()
Return the communicator used by the problem.
BasicVectorAdapter represents a vector (plus optional weights) supplied by the user as pointers to st...
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:26
void printTimers() const
Return the communicator passed to the problem.
An adapter for Xpetra::MultiVector.
#define CATCH_EXCEPTIONS_AND_RETURN(pp)
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)
Tpetra::Map::local_ordinal_type zlno_t
int run_pointAssign_tests(Zoltan2::PartitioningProblem< Adapter > *problem, RCP< tMVector_t > &coords, bool print_details)
static const std::string fail
string convert_to_string(char *args)
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
PartitioningProblem sets up partitioning problems for the user.
string trim_left_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
int getNumWeights()
##END Predistribution functions######################//
bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline)
RCP< tMVector_t > getUICoordinates()
Defines the PartitioningProblem class.
A class that computes and returns quality metrics.
float zscalar_t
Defines the BasicVectorAdapter class.
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
Tpetra::Map::global_ordinal_type zgno_t
void solve(bool updateInputData=true)
Direct the problem to create a solution.
std::string testDataFilePath(".")