Zoltan2
MultiJaggedTest.cpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Zoltan2: A package of combinatorial algorithms for scientific computing
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Karen Devine (kddevin@sandia.gov)
39 // Erik Boman (egboman@sandia.gov)
40 // Siva Rajamanickam (srajama@sandia.gov)
41 //
42 // ***********************************************************************
43 //
44 // @HEADER
45 
51 #include <Zoltan2_TestHelpers.hpp>
56 #include <GeometricGenerator.hpp>
57 #include <vector>
58 
60 
61 #include "Teuchos_XMLParameterListHelpers.hpp"
62 
63 #include <Teuchos_LAPACK.hpp>
64 #include <fstream>
65 #include <string>
66 using namespace std;
67 using Teuchos::RCP;
68 using Teuchos::rcp;
69 
70 
71 //#define hopper_separate_test
72 #ifdef hopper_separate_test
73 #include "stdio.h"
74 #endif
75 #define CATCH_EXCEPTIONS_AND_RETURN(pp) \
76  catch (std::runtime_error &e) { \
77  cout << "Runtime exception returned from " << pp << ": " \
78  << e.what() << " FAIL" << endl; \
79  return -1; \
80  } \
81  catch (std::logic_error &e) { \
82  cout << "Logic exception returned from " << pp << ": " \
83  << e.what() << " FAIL" << endl; \
84  return -1; \
85  } \
86  catch (std::bad_alloc &e) { \
87  cout << "Bad_alloc exception returned from " << pp << ": " \
88  << e.what() << " FAIL" << endl; \
89  return -1; \
90  } \
91  catch (std::exception &e) { \
92  cout << "Unknown exception returned from " << pp << ": " \
93  << e.what() << " FAIL" << endl; \
94  return -1; \
95  }
96 
97 #define CATCH_EXCEPTIONS_WITH_COUNT(ierr, pp) \
98  catch (std::runtime_error &e) { \
99  cout << "Runtime exception returned from " << pp << ": " \
100  << e.what() << " FAIL" << endl; \
101  (ierr)++; \
102  } \
103  catch (std::logic_error &e) { \
104  cout << "Logic exception returned from " << pp << ": " \
105  << e.what() << " FAIL" << endl; \
106  (ierr)++; \
107  } \
108  catch (std::bad_alloc &e) { \
109  cout << "Bad_alloc exception returned from " << pp << ": " \
110  << e.what() << " FAIL" << endl; \
111  (ierr)++; \
112  } \
113  catch (std::exception &e) { \
114  cout << "Unknown exception returned from " << pp << ": " \
115  << e.what() << " FAIL" << endl; \
116  (ierr)++; \
117  }
118 
119 
120 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> tMVector_t;
121 
127 const char param_comment = '#';
128 
130  const string& s,
131  const string& delimiters = " \f\n\r\t\v" )
132 {
133  return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
134 }
135 
137  const string& s,
138  const string& delimiters = " \f\n\r\t\v" )
139 {
140  return s.substr( s.find_first_not_of( delimiters ) );
141 }
142 
143 string trim_copy(
144  const string& s,
145  const string& delimiters = " \f\n\r\t\v" )
146 {
147  return trim_left_copy( trim_right_copy( s, delimiters ), delimiters );
148 }
149 
150 template <typename Adapter>
152  const char *str,
153  int dim,
154  typename Adapter::scalar_t *lower,
155  typename Adapter::scalar_t *upper,
156  size_t nparts,
157  typename Adapter::part_t *parts
158 )
159 {
160  std::cout << "boxAssign test " << str << ": Box (";
161  for (int j = 0; j < dim; j++) std::cout << lower[j] << " ";
162  std::cout << ") x (";
163  for (int j = 0; j < dim; j++) std::cout << upper[j] << " ";
164 
165  if (nparts == 0)
166  std::cout << ") does not overlap any parts" << std::endl;
167  else {
168  std::cout << ") overlaps parts ";
169  for (size_t k = 0; k < nparts; k++) std::cout << parts[k] << " ";
170  std::cout << std::endl;
171  }
172 }
173 
174 template <typename Adapter>
177  RCP<tMVector_t> &coords)
178 {
179  int ierr = 0;
180 
181  // pointAssign tests
182  int coordDim = coords->getNumVectors();
183  zscalar_t *pointDrop = new zscalar_t[coordDim];
184  typename Adapter::part_t part = -1;
185 
186  char mechar[10];
187  sprintf(mechar, "%d", problem->getComm()->getRank());
188  string me(mechar);
189 
190  // test correctness of pointAssign for owned points
191  {
192  const typename Adapter::part_t *solnPartView =
193  problem->getSolution().getPartListView();
194 
195  size_t numPoints = coords->getLocalLength();
196  for (size_t localID = 0; localID < numPoints; localID++) {
197 
198  typename Adapter::part_t solnPart = solnPartView[localID];
199 
200  for (int i = 0; i < coordDim; i++)
201  pointDrop[i] = coords->getData(i)[localID];
202 
203  try {
204  part = problem->getSolution().pointAssign(coordDim, pointDrop);
205  }
206  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + ": pointAssign -- OwnedPoints");
207 
208  std::cout << me << " Point " << localID
209  << " gid " << coords->getMap()->getGlobalElement(localID)
210  << " (" << pointDrop[0];
211  if (coordDim > 1) std::cout << " " << pointDrop[1];
212  if (coordDim > 2) std::cout << " " << pointDrop[2];
213  std::cout << ") in boxPart " << part
214  << " in solnPart " << solnPart
215  << std::endl;
216 
217 // this error test does not work for points that fall on the cuts.
218 // like Zoltan's RCB, pointAssign arbitrarily picks a part along the cut.
219 // the arbitrarily chosen part will not necessarily be the one to which
220 // the coordinate was assigned in partitioning.
221 //
222 // if (part != solnPart) {
223 // std::cout << me << " pointAssign: incorrect part " << part
224 // << " found; should be " << solnPart
225 // << " for point " << j << std::endl;
226 // ierr++;
227 // }
228  }
229  }
230 
231  {
233  typename Adapter::part_t> >
234  pBoxes = problem->getSolution().getPartBoxesView();
235  for (size_t i = 0; i < pBoxes.size(); i++) {
236  zscalar_t *lmin = pBoxes[i].getlmins();
237  zscalar_t *lmax = pBoxes[i].getlmaxs();;
238  std::cout << me << " pBox " << i << " pid " << pBoxes[i].getpId()
239  << " (" << lmin[0] << "," << lmin[1] << ","
240  << (coordDim > 2 ? lmin[2] : 0) << ") x "
241  << " (" << lmax[0] << "," << lmax[1] << ","
242  << (coordDim > 2 ? lmax[2] : 0) << ")" << std::endl;
243  }
244  }
245 
246  // test the origin
247  {
248  for (int i = 0; i < coordDim; i++) pointDrop[i] = 0.;
249  try {
250  part = problem->getSolution().pointAssign(coordDim, pointDrop);
251  }
252  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " pointAssign -- Origin");
253  std::cout << me << " OriginPoint (" << pointDrop[0];
254  if (coordDim > 1) std::cout << " " << pointDrop[1];
255  if (coordDim > 2) std::cout << " " << pointDrop[2];
256  std::cout << ") part " << part << std::endl;
257  }
258 
259  // test point with negative coordinates
260  {
261  for (int i = 0; i < coordDim; i++) pointDrop[i] = -100.+i;
262  try {
263  part = problem->getSolution().pointAssign(coordDim, pointDrop);
264  }
265  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " pointAssign -- Negative Point");
266  std::cout << me << " NegativePoint (" << pointDrop[0];
267  if (coordDim > 1) std::cout << " " << pointDrop[1];
268  if (coordDim > 2) std::cout << " " << pointDrop[2];
269  std::cout << ") part " << part << std::endl;
270  }
271 
272  // test a point that's way out there
273  {
274  for (int i = 0; i < coordDim; i++) pointDrop[i] = i*5;
275  try {
276  part = problem->getSolution().pointAssign(coordDim, pointDrop);
277  }
278  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " pointAssign -- i*5 Point");
279  std::cout << me << " i*5-Point (" << pointDrop[0];
280  if (coordDim > 1) std::cout << " " << pointDrop[1];
281  if (coordDim > 2) std::cout << " " << pointDrop[2];
282  std::cout << ") part " << part << std::endl;
283  }
284 
285  // test a point that's way out there
286  {
287  for (int i = 0; i < coordDim; i++) pointDrop[i] = 10+i*5;
288  try {
289  part = problem->getSolution().pointAssign(coordDim, pointDrop);
290  }
291  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " pointAssign -- WoopWoop");
292  std::cout << me << " WoopWoop-Point (" << pointDrop[0];
293  if (coordDim > 1) std::cout << " " << pointDrop[1];
294  if (coordDim > 2) std::cout << " " << pointDrop[2];
295  std::cout << ") part " << part << std::endl;
296  }
297 
298  delete [] pointDrop;
299  return ierr;
300 }
301 
302 template <typename Adapter>
305  RCP<tMVector_t> &coords)
306 {
307  int ierr = 0;
308 
309  // boxAssign tests
310  int coordDim = coords->getNumVectors();
311  zscalar_t *lower = new zscalar_t[coordDim];
312  zscalar_t *upper = new zscalar_t[coordDim];
313 
314  char mechar[10];
315  sprintf(mechar, "%d", problem->getComm()->getRank());
316  string me(mechar);
317 
319  typename Adapter::part_t> >
320  pBoxes = problem->getSolution().getPartBoxesView();
321  size_t nBoxes = pBoxes.size();
322 
323  // test a box that is smaller than a part
324  {
325  size_t nparts;
326  typename Adapter::part_t *parts;
327  size_t pickabox = nBoxes / 2;
328  for (int i = 0; i < coordDim; i++) {
329  zscalar_t dd = 0.2 * (pBoxes[pickabox].getlmaxs()[i] -
330  pBoxes[pickabox].getlmins()[i]);
331  lower[i] = pBoxes[pickabox].getlmins()[i] + dd;
332  upper[i] = pBoxes[pickabox].getlmaxs()[i] - dd;
333  }
334  try {
335  problem->getSolution().boxAssign(coordDim, lower, upper,
336  nparts, &parts);
337  }
338  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- smaller");
339  if (nparts > 1) {
340  std::cout << me << " FAIL boxAssign error: smaller test, nparts > 1"
341  << std::endl;
342  ierr++;
343  }
344  print_boxAssign_result<Adapter>("smallerbox", coordDim,
345  lower, upper, nparts, parts);
346  delete [] parts;
347  }
348 
349  // test a box that is larger than a part
350  {
351  size_t nparts;
352  typename Adapter::part_t *parts;
353  size_t pickabox = nBoxes / 2;
354  for (int i = 0; i < coordDim; i++) {
355  zscalar_t dd = 0.2 * (pBoxes[pickabox].getlmaxs()[i] -
356  pBoxes[pickabox].getlmins()[i]);
357  lower[i] = pBoxes[pickabox].getlmins()[i] - dd;
358  upper[i] = pBoxes[pickabox].getlmaxs()[i] + dd;
359  }
360  try {
361  problem->getSolution().boxAssign(coordDim, lower, upper,
362  nparts, &parts);
363  }
364  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- larger");
365 
366  // larger box should have at least two parts in it for k > 1.
367  if ((nBoxes > 1) && (nparts < 2)) {
368  std::cout << me << " FAIL boxAssign error: "
369  << "larger test, nparts < 2"
370  << std::endl;
371  ierr++;
372  }
373 
374  // parts should include pickabox's part
375  bool found_pickabox = 0;
376  for (size_t i = 0; i < nparts; i++)
377  if (parts[i] == pBoxes[pickabox].getpId()) {
378  found_pickabox = 1;
379  break;
380  }
381  if (!found_pickabox) {
382  std::cout << me << " FAIL boxAssign error: "
383  << "larger test, pickabox not found"
384  << std::endl;
385  ierr++;
386  }
387 
388  print_boxAssign_result<Adapter>("largerbox", coordDim,
389  lower, upper, nparts, parts);
390  delete [] parts;
391  }
392 
393  // test a box that includes all parts
394  {
395  size_t nparts;
396  typename Adapter::part_t *parts;
397  for (int i = 0; i < coordDim; i++) {
398  lower[i] = std::numeric_limits<zscalar_t>::max();
399  upper[i] = std::numeric_limits<zscalar_t>::min();
400  }
401  for (size_t j = 0; j < nBoxes; j++) {
402  for (int i = 0; i < coordDim; i++) {
403  if (pBoxes[j].getlmins()[i] <= lower[i])
404  lower[i] = pBoxes[j].getlmins()[i];
405  if (pBoxes[j].getlmaxs()[i] >= upper[i])
406  upper[i] = pBoxes[j].getlmaxs()[i];
407  }
408  }
409  try {
410  problem->getSolution().boxAssign(coordDim, lower, upper,
411  nparts, &parts);
412  }
413  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- global");
414 
415  // global box should have all parts
416  if (nparts != nBoxes) {
417  std::cout << me << " FAIL boxAssign error: "
418  << "global test, nparts found " << nparts
419  << " != num global parts " << nBoxes
420  << std::endl;
421  ierr++;
422  }
423  print_boxAssign_result<Adapter>("globalbox", coordDim,
424  lower, upper, nparts, parts);
425  delete [] parts;
426  }
427 
428  // test a box that is bigger than the entire domain
429  // Assuming lower and upper are still set to the global box boundary
430  // from the previous test
431  {
432  size_t nparts;
433  typename Adapter::part_t *parts;
434  for (int i = 0; i < coordDim; i++) {
435  lower[i] -= 2.;
436  upper[i] += 2.;
437  }
438 
439  try {
440  problem->getSolution().boxAssign(coordDim, lower, upper,
441  nparts, &parts);
442  }
443  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- bigdomain");
444 
445  // bigdomain box should have all parts
446  if (nparts != nBoxes) {
447  std::cout << me << " FAIL boxAssign error: "
448  << "bigdomain test, nparts found " << nparts
449  << " != num global parts " << nBoxes
450  << std::endl;
451  ierr++;
452  }
453  print_boxAssign_result<Adapter>("bigdomainbox", coordDim,
454  lower, upper, nparts, parts);
455  delete [] parts;
456  }
457 
458  // test a box that is way out there
459  // Assuming lower and upper are still set to at least the global box
460  // boundary from the previous test
461  {
462  size_t nparts;
463  typename Adapter::part_t *parts;
464  for (int i = 0; i < coordDim; i++) {
465  lower[i] = upper[i] + 10;
466  upper[i] += 20;
467  }
468 
469  try {
470  problem->getSolution().boxAssign(coordDim, lower, upper,
471  nparts, &parts);
472  }
473  CATCH_EXCEPTIONS_WITH_COUNT(ierr, me + " boxAssign -- out there");
474 
475  // For now, boxAssign returns zero if there is no box overlap.
476  // TODO: this result should be changed in boxAssign definition
477  if (nparts != 0) {
478  std::cout << me << " FAIL boxAssign error: "
479  << "outthere test, nparts found " << nparts
480  << " != zero"
481  << std::endl;
482  ierr++;
483  }
484  print_boxAssign_result<Adapter>("outthere box", coordDim,
485  lower, upper, nparts, parts);
486  delete [] parts;
487  }
488 
489  delete [] lower;
490  delete [] upper;
491  return ierr;
492 }
493 
494 void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP<const Teuchos::Comm<int> > & comm){
495  std::string input = "";
496  char inp[25000];
497  for(int i = 0; i < 25000; ++i){
498  inp[i] = 0;
499  }
500 
501  bool fail = false;
502  if(comm->getRank() == 0){
503 
504  fstream inParam(paramFileName.c_str());
505  if (inParam.fail())
506  {
507  fail = true;
508  }
509  if(!fail)
510  {
511  std::string tmp = "";
512  getline (inParam,tmp);
513  while (!inParam.eof()){
514  if(tmp != ""){
515  tmp = trim_copy(tmp);
516  if(tmp != ""){
517  input += tmp + "\n";
518  }
519  }
520  getline (inParam,tmp);
521  }
522  inParam.close();
523  for (size_t i = 0; i < input.size(); ++i){
524  inp[i] = input[i];
525  }
526  }
527  }
528 
529 
530 
531  int size = input.size();
532  if(fail){
533  size = -1;
534  }
535  comm->broadcast(0, sizeof(int), (char*) &size);
536  if(size == -1){
537  throw "File " + paramFileName + " cannot be opened.";
538  }
539  comm->broadcast(0, size, inp);
540  istringstream inParam(inp);
541  string str;
542  getline (inParam,str);
543  while (!inParam.eof()){
544  if(str[0] != param_comment){
545  size_t pos = str.find('=');
546  if(pos == string::npos){
547  throw "Invalid Line:" + str + " in parameter file";
548  }
549  string paramname = trim_copy(str.substr(0,pos));
550  string paramvalue = trim_copy(str.substr(pos + 1));
551  geoparams.set(paramname, paramvalue);
552  }
553  getline (inParam,str);
554  }
555 }
556 
557 int GeometricGenInterface(RCP<const Teuchos::Comm<int> > &comm,
558  int numParts, float imbalance,
559  std::string paramFile, std::string pqParts,
560  std::string pfname,
561  int k,
562  int migration_check_option,
563  int migration_all_to_all_type,
564  zscalar_t migration_imbalance_cut_off,
565  int migration_processor_assignment_type,
566  int migration_doMigration_type,
567  bool test_boxes,
568  bool rectilinear
569 )
570 {
571  int ierr = 0;
572  Teuchos::ParameterList geoparams("geo params");
573  readGeoGenParams(paramFile, geoparams, comm);
576  comm);
577 
578  int coord_dim = gg->getCoordinateDimension();
579  int numWeightsPerCoord = gg->getNumWeights();
580  zlno_t numLocalPoints = gg->getNumLocalCoords();
581  zgno_t numGlobalPoints = gg->getNumGlobalCoords();
582  zscalar_t **coords = new zscalar_t * [coord_dim];
583  for(int i = 0; i < coord_dim; ++i){
584  coords[i] = new zscalar_t[numLocalPoints];
585  }
586  gg->getLocalCoordinatesCopy(coords);
587  zscalar_t **weight = NULL;
588  if (numWeightsPerCoord) {
589  weight= new zscalar_t * [numWeightsPerCoord];
590  for(int i = 0; i < numWeightsPerCoord; ++i){
591  weight[i] = new zscalar_t[numLocalPoints];
592  }
593  gg->getLocalWeightsCopy(weight);
594  }
595 
596  delete gg;
597 
598  RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
599  new Tpetra::Map<zlno_t, zgno_t, znode_t>(numGlobalPoints,
600  numLocalPoints, 0, comm));
601 
602  Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
603  for (int i=0; i < coord_dim; i++){
604  if(numLocalPoints > 0){
605  Teuchos::ArrayView<const zscalar_t> a(coords[i], numLocalPoints);
606  coordView[i] = a;
607  }
608  else {
609  Teuchos::ArrayView<const zscalar_t> a;
610  coordView[i] = a;
611  }
612  }
613 
614  RCP<tMVector_t> tmVector = RCP<tMVector_t>(new
615  tMVector_t(mp, coordView.view(0, coord_dim),
616  coord_dim));
617 
618  RCP<const tMVector_t> coordsConst =
619  Teuchos::rcp_const_cast<const tMVector_t>(tmVector);
620  vector<const zscalar_t *> weights;
621  if(numWeightsPerCoord){
622  for (int i = 0; i < numWeightsPerCoord;++i){
623  weights.push_back(weight[i]);
624  }
625  }
626  vector <int> stride;
627 
628  typedef Zoltan2::XpetraMultiVectorAdapter<tMVector_t> inputAdapter_t;
629  //inputAdapter_t ia(coordsConst);
630  inputAdapter_t ia(coordsConst,weights, stride);
631 
632  Teuchos::RCP<Teuchos::ParameterList> params ;
633 
634  //Teuchos::ParameterList params("test params");
635  if(pfname != ""){
636  params = Teuchos::getParametersFromXmlFile(pfname);
637  }
638  else {
639  params =RCP<Teuchos::ParameterList>(new Teuchos::ParameterList, true);
640  }
641 /*
642  params->set("memory_output_stream" , "std::cout");
643  params->set("memory_procs" , 0);
644  */
645  params->set("timer_output_stream" , "std::cout");
646 
647  params->set("algorithm", "multijagged");
648  params->set("compute_metrics", "true");
649  if (test_boxes)
650  params->set("mj_keep_part_boxes", 1);
651  if (rectilinear)
652  params->set("rectilinear", "true");
653 
654  if(imbalance > 1)
655  params->set("imbalance_tolerance", double(imbalance));
656 
657  if(pqParts != "")
658  params->set("mj_parts", pqParts);
659  if(numParts > 0)
660  params->set("num_global_parts", numParts);
661  if (k > 0)
662  params->set("mj_concurrent_part_count", k);
663  if(migration_check_option >= 0)
664  params->set("mj_migration_option", migration_check_option);
665  if(migration_imbalance_cut_off >= 0)
666  params->set("mj_minimum_migration_imbalance",
667  double(migration_imbalance_cut_off));
668 
670  try {
672  params.getRawPtr(),
673  comm);
674  }
675  CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
676 
677  try {
678  problem->solve();
679  }
680  CATCH_EXCEPTIONS_AND_RETURN("solve()")
681  if (comm->getRank() == 0){
682  problem->printMetrics(cout);
683  }
684  problem->printTimers();
685 
686  // run pointAssign tests
687  if (test_boxes) {
688  ierr = run_pointAssign_tests<inputAdapter_t>(problem, tmVector);
689  ierr += run_boxAssign_tests<inputAdapter_t>(problem, tmVector);
690  }
691 
692  if(numWeightsPerCoord){
693  for(int i = 0; i < numWeightsPerCoord; ++i)
694  delete [] weight[i];
695  delete [] weight;
696  }
697  if(coord_dim){
698  for(int i = 0; i < coord_dim; ++i)
699  delete [] coords[i];
700  delete [] coords;
701  }
702  delete problem;
703  return ierr;
704 }
705 
707  RCP<const Teuchos::Comm<int> > &comm,
708  int numParts,
709  float imbalance,
710  std::string fname,
711  std::string pqParts,
712  std::string pfname,
713  int k,
714  int migration_check_option,
715  int migration_all_to_all_type,
716  zscalar_t migration_imbalance_cut_off,
717  int migration_processor_assignment_type,
718  int migration_doMigration_type,
719  bool test_boxes,
720  bool rectilinear
721 )
722 {
723  int ierr = 0;
724  //std::string fname("simple");
725  //cout << "running " << fname << endl;
726 
727  UserInputForTests uinput(testDataFilePath, fname, comm, true);
728 
729  RCP<tMVector_t> coords = uinput.getUICoordinates();
730 
731  RCP<const tMVector_t> coordsConst = rcp_const_cast<const tMVector_t>(coords);
732  typedef Zoltan2::XpetraMultiVectorAdapter<tMVector_t> inputAdapter_t;
733  inputAdapter_t ia(coordsConst);
734 
735  Teuchos::RCP <Teuchos::ParameterList> params ;
736 
737  //Teuchos::ParameterList params("test params");
738  if(pfname != ""){
739  params = Teuchos::getParametersFromXmlFile(pfname);
740  }
741  else {
742  params =RCP <Teuchos::ParameterList> (new Teuchos::ParameterList, true);
743  }
744 
745  //params->set("timer_output_stream" , "std::cout");
746  params->set("compute_metrics", "true");
747  if (test_boxes)
748  params->set("mj_keep_part_boxes", 1);
749  if (rectilinear)
750  params->set("rectilinear", "true");
751  params->set("algorithm", "multijagged");
752  if(imbalance > 1){
753  params->set("imbalance_tolerance", double(imbalance));
754  }
755 
756  if(pqParts != ""){
757  params->set("mj_parts", pqParts);
758  }
759  if(numParts > 0){
760  params->set("num_global_parts", numParts);
761  }
762  if (k > 0){
763  params->set("mj_concurrent_part_count", k);
764  }
765  if(migration_check_option >= 0){
766  params->set("mj_migration_option", migration_check_option);
767  }
768  if(migration_imbalance_cut_off >= 0){
769  params->set("mj_minimum_migration_imbalance",
770  double (migration_imbalance_cut_off));
771  }
772 
774  try {
776  params.getRawPtr(),
777  comm);
778  }
779  CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
780 
781  try {
782  problem->solve();
783  }
784  CATCH_EXCEPTIONS_AND_RETURN("solve()")
785 
786  {
787  // Run a test with BasicVectorAdapter and xyzxyz format coordinates
788  const int bvme = comm->getRank();
789  const inputAdapter_t::lno_t bvlen =
790  inputAdapter_t::lno_t(coords->getLocalLength());
791  const size_t bvnvecs = coords->getNumVectors();
792  const size_t bvsize = coords->getNumVectors() * coords->getLocalLength();
793 
794  ArrayRCP<inputAdapter_t::scalar_t> *bvtpetravectors =
795  new ArrayRCP<inputAdapter_t::scalar_t>[bvnvecs];
796  for (size_t i = 0; i < bvnvecs; i++)
797  bvtpetravectors[i] = coords->getDataNonConst(i);
798 
799  int idx = 0;
800  inputAdapter_t::gno_t *bvgids = new
801  inputAdapter_t::gno_t[coords->getLocalLength()];
802  inputAdapter_t::scalar_t *bvcoordarr = new inputAdapter_t::scalar_t[bvsize];
803  for (inputAdapter_t::lno_t j = 0; j < bvlen; j++) {
804  bvgids[j] = coords->getMap()->getGlobalElement(j);
805  for (size_t i = 0; i < bvnvecs; i++) {
806  bvcoordarr[idx++] = bvtpetravectors[i][j];
807  }
808  }
809 
810  typedef Zoltan2::BasicUserTypes<inputAdapter_t::scalar_t,
811  inputAdapter_t::lno_t,
812  inputAdapter_t::gno_t> bvtypes_t;
813  typedef Zoltan2::BasicVectorAdapter<bvtypes_t> bvadapter_t;
814  std::vector<const inputAdapter_t::scalar_t *> bvcoords(bvnvecs);
815  std::vector<int> bvstrides(bvnvecs);
816  for (size_t i = 0; i < bvnvecs; i++) {
817  bvcoords[i] = &bvcoordarr[i];
818  bvstrides[i] = bvnvecs;
819  }
820  std::vector<const inputAdapter_t::scalar_t *> bvwgts;
821  std::vector<int> bvwgtstrides;
822 
823  bvadapter_t bvia(bvlen, bvgids, bvcoords, bvstrides,
824  bvwgts, bvwgtstrides);
825 
827  try {
828  bvproblem = new Zoltan2::PartitioningProblem<bvadapter_t>(&bvia,
829  params.getRawPtr(),
830  comm);
831  }
832  CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
833 
834  try {
835  bvproblem->solve();
836  }
837  CATCH_EXCEPTIONS_AND_RETURN("solve()")
838 
839  // Compare with MultiVectorAdapter result
840  for (inputAdapter_t::lno_t i = 0; i < bvlen; i++) {
841  if (problem->getSolution().getPartListView()[i] !=
842  bvproblem->getSolution().getPartListView()[i])
843  cout << bvme << " " << i << " "
844  << coords->getMap()->getGlobalElement(i) << " " << bvgids[i]
845  << ": XMV " << problem->getSolution().getPartListView()[i]
846  << "; BMV " << bvproblem->getSolution().getPartListView()[i]
847  << " : FAIL" << endl;
848  }
849 
850  delete [] bvgids;
851  delete [] bvcoordarr;
852  delete [] bvtpetravectors;
853  delete bvproblem;
854  }
855 
856  if (coordsConst->getGlobalLength() < 40) {
857  int len = coordsConst->getLocalLength();
858  const inputAdapter_t::part_t *zparts =
859  problem->getSolution().getPartListView();
860  for (int i = 0; i < len; i++)
861  cout << comm->getRank()
862  << " lid " << i
863  << " gid " << coords->getMap()->getGlobalElement(i)
864  << " part " << zparts[i] << endl;
865  }
866 
867  if (comm->getRank() == 0){
868  problem->printMetrics(cout);
869  cout << "testFromDataFile is done " << endl;
870  }
871 
872  problem->printTimers();
873 
874  // run pointAssign tests
875  if (test_boxes) {
876  ierr = run_pointAssign_tests<inputAdapter_t>(problem, coords);
877  ierr += run_boxAssign_tests<inputAdapter_t>(problem, coords);
878  }
879 
880  delete problem;
881  return ierr;
882 }
883 
884 #ifdef hopper_separate_test
885 
886 template <typename zscalar_t, typename zlno_t>
887 void getCoords(zscalar_t **&coords, zlno_t &numLocal, int &dim, string fileName){
888  FILE *f = fopen(fileName.c_str(), "r");
889  if (f == NULL){
890  cout << fileName << " cannot be opened" << endl;
891  exit(1);
892  }
893  fscanf(f, "%d", &numLocal);
894  fscanf(f, "%d", &dim);
895  coords = new zscalar_t *[ dim];
896  for (int i = 0; i < dim; ++i){
897  coords[i] = new zscalar_t[numLocal];
898  }
899  for (int i = 0; i < dim; ++i){
900  for (zlno_t j = 0; j < numLocal; ++j){
901  fscanf(f, "%lf", &(coords[i][j]));
902  }
903  }
904  fclose(f);
905 }
906 
907 int testFromSeparateDataFiles(
908  RCP<const Teuchos::Comm<int> > &comm,
909  int numParts,
910  float imbalance,
911  std::string fname,
912  std::string pqParts,
913  std::string pfname,
914  int k,
915  int migration_check_option,
916  int migration_all_to_all_type,
917  zscalar_t migration_imbalance_cut_off,
918  int migration_processor_assignment_type,
919  int migration_doMigration_type,
920  int test_boxes,
921  bool rectilinear
922 )
923 {
924  //std::string fname("simple");
925  //cout << "running " << fname << endl;
926 
927  int ierr = 0;
928  int mR = comm->getRank();
929  if (mR == 0) cout << "size of zscalar_t:" << sizeof(zscalar_t) << endl;
930  string tFile = fname +"_" + Zoltan2::toString<int>(mR) + ".mtx";
931  zscalar_t **double_coords;
932  zlno_t numLocal = 0;
933  int dim = 0;
934  getCoords<zscalar_t, zlno_t>(double_coords, numLocal, dim, tFile);
935  //UserInputForTests uinput(testDataFilePath, fname, comm, true);
936  Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(dim);
937  for (int i=0; i < dim; i++){
938  if(numLocal > 0){
939  Teuchos::ArrayView<const zscalar_t> a(double_coords[i], numLocal);
940  coordView[i] = a;
941  } else{
942  Teuchos::ArrayView<const zscalar_t> a;
943  coordView[i] = a;
944  }
945  }
946 
947  zgno_t numGlobal;
948  zgno_t nL = numLocal;
949  Teuchos::Comm<int> *tcomm = (Teuchos::Comm<int> *)comm.getRawPtr();
950 
951  reduceAll<int, zgno_t>(
952  *tcomm,
953  Teuchos::REDUCE_SUM,
954  1,
955  &nL,
956  &numGlobal
957  );
958 
959 
960  RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
961  new Tpetra::Map<zlno_t, zgno_t, znode_t> (numGlobal, numLocal, 0, comm));
962  RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >coords = RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >(
963  new Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>( mp, coordView.view(0, dim), dim));
964 
965 
966 
967  RCP<const tMVector_t> coordsConst = rcp_const_cast<const tMVector_t>(coords);
968 
969  typedef Zoltan2::XpetraMultiVectorInput<tMVector_t> inputAdapter_t;
970  inputAdapter_t ia(coordsConst);
971 
972  Teuchos::RCP <Teuchos::ParameterList> params ;
973 
974  //Teuchos::ParameterList params("test params");
975  if(pfname != ""){
976  params = Teuchos::getParametersFromXmlFile(pfname);
977  }
978  else {
979  params =RCP <Teuchos::ParameterList> (new Teuchos::ParameterList, true);
980  }
981 
982  //params->set("timer_output_stream" , "std::cout");
983  params->set("compute_metrics", "true");
984  params->set("algorithm", "multijagged");
985  if(imbalance > 1){
986  params->set("imbalance_tolerance", double(imbalance));
987  }
988 
989  if(pqParts != ""){
990  params->set("pqParts", pqParts);
991  }
992  if(numParts > 0){
993  params->set("num_global_parts", numParts);
994  }
995  if (k > 0){
996  params->set("parallel_part_calculation_count", k);
997  }
998  if(migration_processor_assignment_type >= 0){
999  params->set("migration_processor_assignment_type", migration_processor_assignment_type);
1000  }
1001  if(migration_check_option >= 0){
1002  params->set("migration_check_option", migration_check_option);
1003  }
1004  if(migration_all_to_all_type >= 0){
1005  params->set("migration_all_to_all_type", migration_all_to_all_type);
1006  }
1007  if(migration_imbalance_cut_off >= 0){
1008  params->set("migration_imbalance_cut_off",
1009  double (migration_imbalance_cut_off));
1010  }
1011  if (migration_doMigration_type >= 0){
1012  params->set("migration_doMigration_type", int (migration_doMigration_type));
1013  }
1014  if (test_boxes)
1015  params->set("mj_keep_part_boxes", 1);
1016  if (rectilinear)
1017  params->set("rectilinear", "true");
1018 
1020  try {
1021  problem =
1023  params.getRawPtr(),
1024  comm);
1025  }
1026  CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
1027 
1028  try {
1029  problem->solve();
1030  }
1031  CATCH_EXCEPTIONS_AND_RETURN("solve()")
1032 
1033  if (coordsConst->getGlobalLength() < 40) {
1034  int len = coordsConst->getLocalLength();
1035  const inputAdapter_t::part_t *zparts =
1036  problem->getSolution().getPartListView();
1037  for (int i = 0; i < len; i++)
1038  cout << comm->getRank()
1039  << " gid " << coords->getMap()->getGlobalElement(i)
1040  << " part " << zparts[i] << endl;
1041  }
1042 
1043  if (comm->getRank() == 0){
1044  problem->printMetrics(cout);
1045  cout << "testFromDataFile is done " << endl;
1046  }
1047 
1048  problem->printTimers();
1049 
1050  // run pointAssign tests
1051  if (test_boxes) {
1052  ierr = run_pointAssign_tests<inputAdapter_t>(problem, coords);
1053  ierr += run_boxAssign_tests<inputAdapter_t>(problem, coords);
1054  }
1055 
1056  delete problem;
1057  return ierr;
1058 }
1059 #endif
1060 
1061 
1062 
1063 string convert_to_string(char *args){
1064  string tmp = "";
1065  for(int i = 0; args[i] != 0; i++)
1066  tmp += args[i];
1067  return tmp;
1068 }
1069 bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline){
1070  stringstream stream(stringstream::in | stringstream::out);
1071  stream << argumentline;
1072  getline(stream, argumentid, '=');
1073  if (stream.eof()){
1074  return false;
1075  }
1076  stream >> argumentValue;
1077  return true;
1078 }
1079 
1081  int argc,
1082  char **argv,
1083  int &numParts,
1084  float &imbalance ,
1085  string &pqParts,
1086  int &opt,
1087  std::string &fname,
1088  std::string &pfname,
1089  int &k,
1090  int &migration_check_option,
1091  int &migration_all_to_all_type,
1092  zscalar_t &migration_imbalance_cut_off,
1093  int &migration_processor_assignment_type,
1094  int &migration_doMigration_type,
1095  bool &test_boxes,
1096  bool &rectilinear
1097 )
1098 {
1099  bool isCset = false;
1100  bool isPset = false;
1101  bool isFset = false;
1102  bool isPFset = false;
1103 
1104  for(int i = 0; i < argc; ++i){
1105  string tmp = convert_to_string(argv[i]);
1106  string identifier = "";
1107  long long int value = -1; double fval = -1;
1108  if(!getArgumentValue(identifier, fval, tmp)) continue;
1109  value = (long long int) (fval);
1110 
1111  if(identifier == "C"){
1112  if(value > 0){
1113  numParts=value;
1114  isCset = true;
1115  } else {
1116  throw "Invalid argument at " + tmp;
1117  }
1118  } else if(identifier == "P"){
1119  stringstream stream(stringstream::in | stringstream::out);
1120  stream << tmp;
1121  string ttmp;
1122  getline(stream, ttmp, '=');
1123  stream >> pqParts;
1124  isPset = true;
1125  }else if(identifier == "I"){
1126  if(fval > 0){
1127  imbalance=fval;
1128  } else {
1129  throw "Invalid argument at " + tmp;
1130  }
1131  } else if(identifier == "MI"){
1132  if(fval > 0){
1133  migration_imbalance_cut_off=fval;
1134  } else {
1135  throw "Invalid argument at " + tmp;
1136  }
1137  } else if(identifier == "MO"){
1138  if(value >=0 ){
1139  migration_check_option = value;
1140  } else {
1141  throw "Invalid argument at " + tmp;
1142  }
1143  } else if(identifier == "AT"){
1144  if(value >=0 ){
1145  migration_processor_assignment_type = value;
1146  } else {
1147  throw "Invalid argument at " + tmp;
1148  }
1149  }
1150 
1151  else if(identifier == "MT"){
1152  if(value >=0 ){
1153  migration_all_to_all_type = value;
1154  } else {
1155  throw "Invalid argument at " + tmp;
1156  }
1157  }
1158  else if(identifier == "DM"){
1159  if(value >=0 ){
1160  migration_doMigration_type = value;
1161  } else {
1162  throw "Invalid argument at " + tmp;
1163  }
1164  }
1165  else if(identifier == "F"){
1166  stringstream stream(stringstream::in | stringstream::out);
1167  stream << tmp;
1168  getline(stream, fname, '=');
1169 
1170  stream >> fname;
1171  isFset = true;
1172  }
1173  else if(identifier == "PF"){
1174  stringstream stream(stringstream::in | stringstream::out);
1175  stream << tmp;
1176  getline(stream, pfname, '=');
1177 
1178  stream >> pfname;
1179  isPFset = true;
1180  }
1181 
1182  else if(identifier == "O"){
1183  if(value >= 0 && value <= 3){
1184  opt = value;
1185  } else {
1186  throw "Invalid argument at " + tmp;
1187  }
1188  }
1189  else if(identifier == "K"){
1190  if(value >=0 ){
1191  k = value;
1192  } else {
1193  throw "Invalid argument at " + tmp;
1194  }
1195  }
1196  else if(identifier == "TB"){
1197  if(value >=0 ){
1198  test_boxes = (value == 0 ? false : true);
1199  } else {
1200  throw "Invalid argument at " + tmp;
1201  }
1202  }
1203  else if(identifier == "R"){
1204  if(value >=0 ){
1205  rectilinear = (value == 0 ? false : true);
1206  } else {
1207  throw "Invalid argument at " + tmp;
1208  }
1209  }
1210  else {
1211  throw "Invalid argument at " + tmp;
1212  }
1213 
1214  }
1215  if(!( (isCset || isPset || isPFset) && isFset)){
1216  throw "(C || P || PF) && F are mandatory arguments.";
1217  }
1218 
1219 }
1220 
1221 void print_usage(char *executable){
1222  cout << "\nUsage:" << endl;
1223  cout << executable << " arglist" << endl;
1224  cout << "arglist:" << endl;
1225  cout << "\tC=numParts: numParts > 0" << endl;
1226  cout << "\tP=MultiJaggedPart: Example: P=512,512" << endl;
1227  cout << "\tI=imbalance: Example I=1.03 (ignored for now.)" << endl;
1228  cout << "\tF=filePath: When O=0 the path of the coordinate input file, for O>1 the path to the geometric generator parameter file." << endl;
1229  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." << endl;
1230  cout << "\tK=concurrent part calculation input: K>0." << endl;
1231  cout << "\tMI=migration_imbalance_cut_off: MI=1.35. " << endl;
1232  cout << "\tMT=migration_all_to_all_type: 0 for alltoallv, 1 for Zoltan_Comm, 2 for Zoltan2 Distributor object(Default 1)." << endl;
1233  cout << "\tMO=migration_check_option: 0 for decision on imbalance, 1 for forcing migration, >1 for avoiding migration. (Default-0)" << endl;
1234  cout << "\tAT=migration_processor_assignment_type. 0-for assigning procs with respect to proc ownment, otherwise, assignment with respect to proc closeness." << endl;
1235  cout << "Example:\n" << executable << " P=2,2,2 C=8 F=simple O=0" << endl;
1236 }
1237 
1238 int main(int argc, char *argv[])
1239 {
1240  Teuchos::GlobalMPISession session(&argc, &argv);
1241  //cout << argv << endl;
1242 
1243  RCP<const Teuchos::Comm<int> > tcomm = Teuchos::DefaultComm<int>::getComm();
1244  int rank = tcomm->getRank();
1245 
1246 
1247  int numParts = -10;
1248  float imbalance = -1.03;
1249  int k = -1;
1250 
1251  string pqParts = "";
1252  int opt = 1;
1253  std::string fname = "";
1254  std::string paramFile = "";
1255 
1256 
1257  int migration_check_option = -2;
1258  int migration_all_to_all_type = -1;
1259  zscalar_t migration_imbalance_cut_off = -1.15;
1260  int migration_processor_assignment_type = -1;
1261  int migration_doMigration_type = -1;
1262  bool test_boxes = false;
1263  bool rectilinear = false;
1264 
1265  try{
1266  try {
1267  getArgVals(
1268  argc,
1269  argv,
1270  numParts,
1271  imbalance ,
1272  pqParts,
1273  opt,
1274  fname,
1275  paramFile,
1276  k,
1277  migration_check_option,
1278  migration_all_to_all_type,
1279  migration_imbalance_cut_off,
1280  migration_processor_assignment_type,
1281  migration_doMigration_type,
1282  test_boxes,
1283  rectilinear);
1284  }
1285  catch(std::string s){
1286  if(tcomm->getRank() == 0){
1287  print_usage(argv[0]);
1288  }
1289  throw s;
1290  }
1291 
1292  catch(char * s){
1293  if(tcomm->getRank() == 0){
1294  print_usage(argv[0]);
1295  }
1296  throw s;
1297  }
1298  catch(char const * s){
1299  if(tcomm->getRank() == 0){
1300  print_usage(argv[0]);
1301  }
1302  throw s;
1303  }
1304 
1305  int ierr = 0;
1306 
1307  switch (opt){
1308 
1309  case 0:
1310  ierr = testFromDataFile(tcomm,numParts, imbalance,fname,
1311  pqParts, paramFile, k,
1312  migration_check_option,
1313  migration_all_to_all_type,
1314  migration_imbalance_cut_off,
1315  migration_processor_assignment_type,
1316  migration_doMigration_type, test_boxes, rectilinear);
1317  break;
1318 #ifdef hopper_separate_test
1319  case 1:
1320  ierr = testFromSeparateDataFiles(tcomm,numParts, imbalance,fname,
1321  pqParts, paramFile, k,
1322  migration_check_option,
1323  migration_all_to_all_type,
1324  migration_imbalance_cut_off,
1325  migration_processor_assignment_type,
1326  migration_doMigration_type, test_boxes, rectilinear);
1327  break;
1328 #endif
1329  default:
1330  ierr = GeometricGenInterface(tcomm, numParts, imbalance, fname,
1331  pqParts, paramFile, k,
1332  migration_check_option,
1333  migration_all_to_all_type,
1334  migration_imbalance_cut_off,
1335  migration_processor_assignment_type,
1336  migration_doMigration_type, test_boxes, rectilinear);
1337  break;
1338  }
1339 
1340  if (rank == 0) {
1341  if (ierr == 0) std::cout << "PASS" << std::endl;
1342  else std::cout << "FAIL" << std::endl;
1343  }
1344  }
1345 
1346 
1347  catch(std::string &s){
1348  if (rank == 0)
1349  cerr << s << endl;
1350  }
1351 
1352  catch(char * s){
1353  if (rank == 0)
1354  cerr << s << endl;
1355  }
1356 
1357  catch(char const* s){
1358  if (rank == 0)
1359  cerr << s << endl;
1360  }
1361 
1362  return 0;
1363 }
#define CATCH_EXCEPTIONS_WITH_COUNT(ierr, pp)
string trim_right_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
void print_usage(char *executable)
void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP< const Teuchos::Comm< int > > &comm)
int main(int argc, char *argv[])
double zscalar_t
A simple class that can be the User template argument for an InputAdapter.
int run_pointAssign_tests(Zoltan2::PartitioningProblem< Adapter > *problem, RCP< tMVector_t > &coords)
int testFromDataFile(RCP< const Teuchos::Comm< int > > &comm, 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 test_boxes, bool rectilinear)
static ArrayRCP< ArrayRCP< zscalar_t > > weights
int zlno_t
Defines the PartitioningSolution class.
common code used by tests
int GeometricGenInterface(RCP< const Teuchos::Comm< int > > &comm, 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 test_boxes, bool rectilinear)
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)
coordinateModelPartBox Class, represents the boundaries of the box which is a result of a geometric p...
Defines the XpetraMultiVectorAdapter.
string trim_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
const char param_comment
void getCoords(void *data, int numGid, int numLid, int numObj, zgno_t *gids, zgno_t *lids, int dim, double *coords, int *ierr)
Defines the EvaluatePartition class.
int run_boxAssign_tests(Zoltan2::PartitioningProblem< Adapter > *problem, RCP< tMVector_t > &coords)
void printMetrics(std::ostream &os) const
Print the array of metrics.
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...
void printTimers() const
Return the communicator passed to the problem.
An adapter for Xpetra::MultiVector.
#define CATCH_EXCEPTIONS_AND_RETURN(pp)
static const std::string fail
int zgno_t
string convert_to_string(char *args)
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
PartitioningProblem sets up partitioning problems for the user.
void getArgVals(int argc, char **argv, 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 &test_boxes, bool &rectilinear)
string trim_left_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
Tpetra::MultiVector< double, int, int > tMVector_t
int getNumWeights()
##END Predistribution functions######################//
bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline)
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
Defines the PartitioningProblem class.
RCP< tMVector_t > getUICoordinates()
Defines the BasicVectorAdapter class.
void solve(bool updateInputData=true)
Direct the problem to create a solution.
std::string testDataFilePath(".")