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;
631  //inputAdapter_t ia(coordsConst);
632  inputAdapter_t *ia = new inputAdapter_t(coordsConst,weights, stride);
633 
634  Teuchos::RCP<Teuchos::ParameterList> params ;
635 
636  //Teuchos::ParameterList params("test params");
637  if(pfname != ""){
638  params = Teuchos::getParametersFromXmlFile(pfname);
639  }
640  else {
641  params =RCP<Teuchos::ParameterList>(new Teuchos::ParameterList, true);
642  }
643 /*
644  params->set("memory_output_stream" , "std::cout");
645  params->set("memory_procs" , 0);
646  */
647  params->set("timer_output_stream" , "std::cout");
648 
649  params->set("algorithm", "multijagged");
650  if (test_boxes)
651  params->set("mj_keep_part_boxes", true); // bool parameter
652  if (rectilinear)
653  params->set("rectilinear", true ); // bool parameter
654 
655  if(imbalance > 1)
656  params->set("imbalance_tolerance", double(imbalance));
657 
658  if(pqParts != "")
659  params->set("mj_parts", pqParts);
660  if(numParts > 0)
661  params->set("num_global_parts", numParts);
662  if (k > 0)
663  params->set("mj_concurrent_part_count", k);
664  if(migration_check_option >= 0)
665  params->set("mj_migration_option", migration_check_option);
666  if(migration_imbalance_cut_off >= 0)
667  params->set("mj_minimum_migration_imbalance",
668  double(migration_imbalance_cut_off));
669 
671  try {
673  params.getRawPtr(),
674  comm);
675  }
676  CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
677 
678  try {
679  problem->solve();
680  }
681  CATCH_EXCEPTIONS_AND_RETURN("solve()")
682 
683  // create metric object
684 
685  RCP<quality_t> metricObject =
686  rcp(new quality_t(ia,params.getRawPtr(),comm,&problem->getSolution()));
687 
688  if (comm->getRank() == 0){
689  metricObject->printMetrics(cout);
690  }
691  problem->printTimers();
692 
693  // run pointAssign tests
694  if (test_boxes) {
695  ierr = run_pointAssign_tests<inputAdapter_t>(problem, tmVector);
696  ierr += run_boxAssign_tests<inputAdapter_t>(problem, tmVector);
697  }
698 
699  if(numWeightsPerCoord){
700  for(int i = 0; i < numWeightsPerCoord; ++i)
701  delete [] weight[i];
702  delete [] weight;
703  }
704  if(coord_dim){
705  for(int i = 0; i < coord_dim; ++i)
706  delete [] coords[i];
707  delete [] coords;
708  }
709  delete problem;
710  delete ia;
711  return ierr;
712 }
713 
715  RCP<const Teuchos::Comm<int> > &comm,
716  int numParts,
717  float imbalance,
718  std::string fname,
719  std::string pqParts,
720  std::string pfname,
721  int k,
722  int migration_check_option,
723  int migration_all_to_all_type,
724  zscalar_t migration_imbalance_cut_off,
725  int migration_processor_assignment_type,
726  int migration_doMigration_type,
727  bool test_boxes,
728  bool rectilinear
729 )
730 {
731  int ierr = 0;
732  //std::string fname("simple");
733  //cout << "running " << fname << endl;
734 
735  UserInputForTests uinput(testDataFilePath, fname, comm, true);
736 
737  RCP<tMVector_t> coords = uinput.getUICoordinates();
738 
739  RCP<const tMVector_t> coordsConst = rcp_const_cast<const tMVector_t>(coords);
740  typedef Zoltan2::XpetraMultiVectorAdapter<tMVector_t> inputAdapter_t;
743  inputAdapter_t *ia = new inputAdapter_t(coordsConst);
744 
745  Teuchos::RCP <Teuchos::ParameterList> params ;
746 
747  //Teuchos::ParameterList params("test params");
748  if(pfname != ""){
749  params = Teuchos::getParametersFromXmlFile(pfname);
750  }
751  else {
752  params =RCP <Teuchos::ParameterList> (new Teuchos::ParameterList, true);
753  }
754 
755  //params->set("timer_output_stream" , "std::cout");
756  if (test_boxes)
757  params->set("mj_keep_part_boxes", true); // bool parameter
758  if (rectilinear)
759  params->set("rectilinear", true); // bool parameter
760  params->set("algorithm", "multijagged");
761  if(imbalance > 1){
762  params->set("imbalance_tolerance", double(imbalance));
763  }
764 
765  if(pqParts != ""){
766  params->set("mj_parts", pqParts);
767  }
768  if(numParts > 0){
769  params->set("num_global_parts", numParts);
770  }
771  if (k > 0){
772  params->set("mj_concurrent_part_count", k);
773  }
774  if(migration_check_option >= 0){
775  params->set("mj_migration_option", migration_check_option);
776  }
777  if(migration_imbalance_cut_off >= 0){
778  params->set("mj_minimum_migration_imbalance",
779  double (migration_imbalance_cut_off));
780  }
781 
783  try {
785  params.getRawPtr(),
786  comm);
787  }
788  CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
789 
790  try {
791  problem->solve();
792  }
793  CATCH_EXCEPTIONS_AND_RETURN("solve()")
794 
795  {
796  // Run a test with BasicVectorAdapter and xyzxyz format coordinates
797  const int bvme = comm->getRank();
798  const inputAdapter_t::lno_t bvlen =
799  inputAdapter_t::lno_t(coords->getLocalLength());
800  const size_t bvnvecs = coords->getNumVectors();
801  const size_t bvsize = coords->getNumVectors() * coords->getLocalLength();
802 
803  ArrayRCP<inputAdapter_t::scalar_t> *bvtpetravectors =
804  new ArrayRCP<inputAdapter_t::scalar_t>[bvnvecs];
805  for (size_t i = 0; i < bvnvecs; i++)
806  bvtpetravectors[i] = coords->getDataNonConst(i);
807 
808  int idx = 0;
809  inputAdapter_t::gno_t *bvgids = new
810  inputAdapter_t::gno_t[coords->getLocalLength()];
811  inputAdapter_t::scalar_t *bvcoordarr = new inputAdapter_t::scalar_t[bvsize];
812  for (inputAdapter_t::lno_t j = 0; j < bvlen; j++) {
813  bvgids[j] = coords->getMap()->getGlobalElement(j);
814  for (size_t i = 0; i < bvnvecs; i++) {
815  bvcoordarr[idx++] = bvtpetravectors[i][j];
816  }
817  }
818 
819  typedef Zoltan2::BasicUserTypes<inputAdapter_t::scalar_t,
820  inputAdapter_t::lno_t,
821  inputAdapter_t::gno_t> bvtypes_t;
822  typedef Zoltan2::BasicVectorAdapter<bvtypes_t> bvadapter_t;
823  std::vector<const inputAdapter_t::scalar_t *> bvcoords(bvnvecs);
824  std::vector<int> bvstrides(bvnvecs);
825  for (size_t i = 0; i < bvnvecs; i++) {
826  bvcoords[i] = &bvcoordarr[i];
827  bvstrides[i] = bvnvecs;
828  }
829  std::vector<const inputAdapter_t::scalar_t *> bvwgts;
830  std::vector<int> bvwgtstrides;
831 
832  bvadapter_t bvia(bvlen, bvgids, bvcoords, bvstrides,
833  bvwgts, bvwgtstrides);
834 
836  try {
837  bvproblem = new Zoltan2::PartitioningProblem<bvadapter_t>(&bvia,
838  params.getRawPtr(),
839  comm);
840  }
841  CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
842 
843  try {
844  bvproblem->solve();
845  }
846  CATCH_EXCEPTIONS_AND_RETURN("solve()")
847 
848  // Compare with MultiVectorAdapter result
849  for (inputAdapter_t::lno_t i = 0; i < bvlen; i++) {
850  if (problem->getSolution().getPartListView()[i] !=
851  bvproblem->getSolution().getPartListView()[i])
852  cout << bvme << " " << i << " "
853  << coords->getMap()->getGlobalElement(i) << " " << bvgids[i]
854  << ": XMV " << problem->getSolution().getPartListView()[i]
855  << "; BMV " << bvproblem->getSolution().getPartListView()[i]
856  << " : FAIL" << endl;
857  }
858 
859  delete [] bvgids;
860  delete [] bvcoordarr;
861  delete [] bvtpetravectors;
862  delete bvproblem;
863  }
864 
865  if (coordsConst->getGlobalLength() < 40) {
866  int len = coordsConst->getLocalLength();
867  const inputAdapter_t::part_t *zparts =
868  problem->getSolution().getPartListView();
869  for (int i = 0; i < len; i++)
870  cout << comm->getRank()
871  << " lid " << i
872  << " gid " << coords->getMap()->getGlobalElement(i)
873  << " part " << zparts[i] << endl;
874  }
875 
876  // create metric object
877 
878  RCP<quality_t> metricObject =
879  rcp(new quality_t(ia,params.getRawPtr(),comm,&problem->getSolution()));
880 
881  if (comm->getRank() == 0){
882  metricObject->printMetrics(cout);
883  cout << "testFromDataFile is done " << endl;
884  }
885 
886  problem->printTimers();
887 
888  // run pointAssign tests
889  if (test_boxes) {
890  ierr = run_pointAssign_tests<inputAdapter_t>(problem, coords);
891  ierr += run_boxAssign_tests<inputAdapter_t>(problem, coords);
892  }
893 
894  delete problem;
895  delete ia;
896  return ierr;
897 }
898 
899 #ifdef hopper_separate_test
900 
901 template <typename zscalar_t, typename zlno_t>
902 void getCoords(zscalar_t **&coords, zlno_t &numLocal, int &dim, string fileName){
903  FILE *f = fopen(fileName.c_str(), "r");
904  if (f == NULL){
905  cout << fileName << " cannot be opened" << endl;
906  exit(1);
907  }
908  fscanf(f, "%d", &numLocal);
909  fscanf(f, "%d", &dim);
910  coords = new zscalar_t *[ dim];
911  for (int i = 0; i < dim; ++i){
912  coords[i] = new zscalar_t[numLocal];
913  }
914  for (int i = 0; i < dim; ++i){
915  for (zlno_t j = 0; j < numLocal; ++j){
916  fscanf(f, "%lf", &(coords[i][j]));
917  }
918  }
919  fclose(f);
920 }
921 
922 int testFromSeparateDataFiles(
923  RCP<const Teuchos::Comm<int> > &comm,
924  int numParts,
925  float imbalance,
926  std::string fname,
927  std::string pqParts,
928  std::string pfname,
929  int k,
930  int migration_check_option,
931  int migration_all_to_all_type,
932  zscalar_t migration_imbalance_cut_off,
933  int migration_processor_assignment_type,
934  int migration_doMigration_type,
935  int test_boxes,
936  bool rectilinear
937 )
938 {
939  //std::string fname("simple");
940  //cout << "running " << fname << endl;
941 
942  int ierr = 0;
943  int mR = comm->getRank();
944  if (mR == 0) cout << "size of zscalar_t:" << sizeof(zscalar_t) << endl;
945  string tFile = fname +"_" + Teuchos::toString<int>(mR) + ".mtx";
946  zscalar_t **double_coords;
947  zlno_t numLocal = 0;
948  int dim = 0;
949  getCoords<zscalar_t, zlno_t>(double_coords, numLocal, dim, tFile);
950  //UserInputForTests uinput(testDataFilePath, fname, comm, true);
951  Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(dim);
952  for (int i=0; i < dim; i++){
953  if(numLocal > 0){
954  Teuchos::ArrayView<const zscalar_t> a(double_coords[i], numLocal);
955  coordView[i] = a;
956  } else{
957  Teuchos::ArrayView<const zscalar_t> a;
958  coordView[i] = a;
959  }
960  }
961 
962  zgno_t numGlobal;
963  zgno_t nL = numLocal;
964  Teuchos::Comm<int> *tcomm = (Teuchos::Comm<int> *)comm.getRawPtr();
965 
966  reduceAll<int, zgno_t>(
967  *tcomm,
968  Teuchos::REDUCE_SUM,
969  1,
970  &nL,
971  &numGlobal
972  );
973 
974 
975  RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
976  new Tpetra::Map<zlno_t, zgno_t, znode_t> (numGlobal, numLocal, 0, comm));
977  RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >coords = RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >(
978  new Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>( mp, coordView.view(0, dim), dim));
979 
980 
981 
982  RCP<const tMVector_t> coordsConst = rcp_const_cast<const tMVector_t>(coords);
983 
984  typedef Zoltan2::XpetraMultiVectorInput<tMVector_t> inputAdapter_t;
987  inputAdapter_t *ia = new inputAdapter_t(coordsConst);
988 
989  Teuchos::RCP <Teuchos::ParameterList> params ;
990 
991  //Teuchos::ParameterList params("test params");
992  if(pfname != ""){
993  params = Teuchos::getParametersFromXmlFile(pfname);
994  }
995  else {
996  params =RCP <Teuchos::ParameterList> (new Teuchos::ParameterList, true);
997  }
998 
999  //params->set("timer_output_stream" , "std::cout");
1000  params->set("algorithm", "multijagged");
1001  if(imbalance > 1){
1002  params->set("imbalance_tolerance", double(imbalance));
1003  }
1004 
1005  if(pqParts != ""){
1006  params->set("mj_parts", pqParts);
1007  }
1008  if(numParts > 0){
1009  params->set("num_global_parts", numParts);
1010  }
1011  if (k > 0){
1012  params->set("parallel_part_calculation_count", k);
1013  }
1014  if(migration_processor_assignment_type >= 0){
1015  params->set("migration_processor_assignment_type", migration_processor_assignment_type);
1016  }
1017  if(migration_check_option >= 0){
1018  params->set("migration_check_option", migration_check_option);
1019  }
1020  if(migration_all_to_all_type >= 0){
1021  params->set("migration_all_to_all_type", migration_all_to_all_type);
1022  }
1023  if(migration_imbalance_cut_off >= 0){
1024  params->set("migration_imbalance_cut_off",
1025  double (migration_imbalance_cut_off));
1026  }
1027  if (migration_doMigration_type >= 0){
1028  params->set("migration_doMigration_type", int (migration_doMigration_type));
1029  }
1030  if (test_boxes)
1031  params->set("mj_keep_part_boxes", true); // bool parameter
1032  if (rectilinear)
1033  params->set("rectilinear", true); // bool parameter
1034 
1036  try {
1037  problem =
1039  params.getRawPtr(),
1040  comm);
1041  }
1042  CATCH_EXCEPTIONS_AND_RETURN("PartitioningProblem()")
1043 
1044  try {
1045  problem->solve();
1046  }
1047  CATCH_EXCEPTIONS_AND_RETURN("solve()")
1048 
1049  if (coordsConst->getGlobalLength() < 40) {
1050  int len = coordsConst->getLocalLength();
1051  const inputAdapter_t::part_t *zparts =
1052  problem->getSolution().getPartListView();
1053  for (int i = 0; i < len; i++)
1054  cout << comm->getRank()
1055  << " gid " << coords->getMap()->getGlobalElement(i)
1056  << " part " << zparts[i] << endl;
1057  }
1058 
1059  //create metric object
1060 
1061  RCP<quality_t> metricObject =
1062  rcp(new quality_t(ia,params.getRawPtr(),comm,&problem->getSolution()));
1063 
1064  if (comm->getRank() == 0){
1065  metricObject->printMetrics(cout);
1066  cout << "testFromDataFile is done " << endl;
1067  }
1068 
1069  problem->printTimers();
1070 
1071  // run pointAssign tests
1072  if (test_boxes) {
1073  ierr = run_pointAssign_tests<inputAdapter_t>(problem, coords);
1074  ierr += run_boxAssign_tests<inputAdapter_t>(problem, coords);
1075  }
1076 
1077  delete problem;
1078  delete ia;
1079  return ierr;
1080 }
1081 #endif
1082 
1083 
1084 
1085 string convert_to_string(char *args){
1086  string tmp = "";
1087  for(int i = 0; args[i] != 0; i++)
1088  tmp += args[i];
1089  return tmp;
1090 }
1091 bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline){
1092  stringstream stream(stringstream::in | stringstream::out);
1093  stream << argumentline;
1094  getline(stream, argumentid, '=');
1095  if (stream.eof()){
1096  return false;
1097  }
1098  stream >> argumentValue;
1099  return true;
1100 }
1101 
1103  int argc,
1104  char **argv,
1105  int &numParts,
1106  float &imbalance ,
1107  string &pqParts,
1108  int &opt,
1109  std::string &fname,
1110  std::string &pfname,
1111  int &k,
1112  int &migration_check_option,
1113  int &migration_all_to_all_type,
1114  zscalar_t &migration_imbalance_cut_off,
1115  int &migration_processor_assignment_type,
1116  int &migration_doMigration_type,
1117  bool &test_boxes,
1118  bool &rectilinear
1119 )
1120 {
1121  bool isCset = false;
1122  bool isPset = false;
1123  bool isFset = false;
1124  bool isPFset = false;
1125 
1126  for(int i = 0; i < argc; ++i){
1127  string tmp = convert_to_string(argv[i]);
1128  string identifier = "";
1129  long long int value = -1; double fval = -1;
1130  if(!getArgumentValue(identifier, fval, tmp)) continue;
1131  value = (long long int) (fval);
1132 
1133  if(identifier == "C"){
1134  if(value > 0){
1135  numParts=value;
1136  isCset = true;
1137  } else {
1138  throw "Invalid argument at " + tmp;
1139  }
1140  } else if(identifier == "P"){
1141  stringstream stream(stringstream::in | stringstream::out);
1142  stream << tmp;
1143  string ttmp;
1144  getline(stream, ttmp, '=');
1145  stream >> pqParts;
1146  isPset = true;
1147  }else if(identifier == "I"){
1148  if(fval > 0){
1149  imbalance=fval;
1150  } else {
1151  throw "Invalid argument at " + tmp;
1152  }
1153  } else if(identifier == "MI"){
1154  if(fval > 0){
1155  migration_imbalance_cut_off=fval;
1156  } else {
1157  throw "Invalid argument at " + tmp;
1158  }
1159  } else if(identifier == "MO"){
1160  if(value >=0 ){
1161  migration_check_option = value;
1162  } else {
1163  throw "Invalid argument at " + tmp;
1164  }
1165  } else if(identifier == "AT"){
1166  if(value >=0 ){
1167  migration_processor_assignment_type = value;
1168  } else {
1169  throw "Invalid argument at " + tmp;
1170  }
1171  }
1172 
1173  else if(identifier == "MT"){
1174  if(value >=0 ){
1175  migration_all_to_all_type = value;
1176  } else {
1177  throw "Invalid argument at " + tmp;
1178  }
1179  }
1180  else if(identifier == "DM"){
1181  if(value >=0 ){
1182  migration_doMigration_type = value;
1183  } else {
1184  throw "Invalid argument at " + tmp;
1185  }
1186  }
1187  else if(identifier == "F"){
1188  stringstream stream(stringstream::in | stringstream::out);
1189  stream << tmp;
1190  getline(stream, fname, '=');
1191 
1192  stream >> fname;
1193  isFset = true;
1194  }
1195  else if(identifier == "PF"){
1196  stringstream stream(stringstream::in | stringstream::out);
1197  stream << tmp;
1198  getline(stream, pfname, '=');
1199 
1200  stream >> pfname;
1201  isPFset = true;
1202  }
1203 
1204  else if(identifier == "O"){
1205  if(value >= 0 && value <= 3){
1206  opt = value;
1207  } else {
1208  throw "Invalid argument at " + tmp;
1209  }
1210  }
1211  else if(identifier == "K"){
1212  if(value >=0 ){
1213  k = value;
1214  } else {
1215  throw "Invalid argument at " + tmp;
1216  }
1217  }
1218  else if(identifier == "TB"){
1219  if(value >=0 ){
1220  test_boxes = (value == 0 ? false : true);
1221  } else {
1222  throw "Invalid argument at " + tmp;
1223  }
1224  }
1225  else if(identifier == "R"){
1226  if(value >=0 ){
1227  rectilinear = (value == 0 ? false : true);
1228  } else {
1229  throw "Invalid argument at " + tmp;
1230  }
1231  }
1232  else {
1233  throw "Invalid argument at " + tmp;
1234  }
1235 
1236  }
1237  if(!( (isCset || isPset || isPFset) && isFset)){
1238  throw "(C || P || PF) && F are mandatory arguments.";
1239  }
1240 
1241 }
1242 
1243 void print_usage(char *executable){
1244  cout << "\nUsage:" << endl;
1245  cout << executable << " arglist" << endl;
1246  cout << "arglist:" << endl;
1247  cout << "\tC=numParts: numParts > 0" << endl;
1248  cout << "\tP=MultiJaggedPart: Example: P=512,512" << endl;
1249  cout << "\tI=imbalance: Example I=1.03 (ignored for now.)" << endl;
1250  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;
1251  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;
1252  cout << "\tK=concurrent part calculation input: K>0." << endl;
1253  cout << "\tMI=migration_imbalance_cut_off: MI=1.35. " << endl;
1254  cout << "\tMT=migration_all_to_all_type: 0 for alltoallv, 1 for Zoltan_Comm, 2 for Zoltan2 Distributor object(Default 1)." << endl;
1255  cout << "\tMO=migration_check_option: 0 for decision on imbalance, 1 for forcing migration, >1 for avoiding migration. (Default-0)" << endl;
1256  cout << "\tAT=migration_processor_assignment_type. 0-for assigning procs with respect to proc ownment, otherwise, assignment with respect to proc closeness." << endl;
1257  cout << "Example:\n" << executable << " P=2,2,2 C=8 F=simple O=0" << endl;
1258 }
1259 
1260 int main(int argc, char *argv[])
1261 {
1262  Teuchos::GlobalMPISession session(&argc, &argv);
1263  Kokkos::initialize (argc, argv);
1264  //cout << argv << endl;
1265 
1266  RCP<const Teuchos::Comm<int> > tcomm = Teuchos::DefaultComm<int>::getComm();
1267  int rank = tcomm->getRank();
1268 
1269 
1270  int numParts = -10;
1271  float imbalance = -1.03;
1272  int k = -1;
1273 
1274  string pqParts = "";
1275  int opt = 1;
1276  std::string fname = "";
1277  std::string paramFile = "";
1278 
1279 
1280  int migration_check_option = -2;
1281  int migration_all_to_all_type = -1;
1282  zscalar_t migration_imbalance_cut_off = -1.15;
1283  int migration_processor_assignment_type = -1;
1284  int migration_doMigration_type = -1;
1285  bool test_boxes = false;
1286  bool rectilinear = false;
1287 
1288  try{
1289  try {
1290  getArgVals(
1291  argc,
1292  argv,
1293  numParts,
1294  imbalance ,
1295  pqParts,
1296  opt,
1297  fname,
1298  paramFile,
1299  k,
1300  migration_check_option,
1301  migration_all_to_all_type,
1302  migration_imbalance_cut_off,
1303  migration_processor_assignment_type,
1304  migration_doMigration_type,
1305  test_boxes,
1306  rectilinear);
1307  }
1308  catch(std::string s){
1309  if(tcomm->getRank() == 0){
1310  print_usage(argv[0]);
1311  }
1312  throw s;
1313  }
1314 
1315  catch(char * s){
1316  if(tcomm->getRank() == 0){
1317  print_usage(argv[0]);
1318  }
1319  throw s;
1320  }
1321  catch(char const * s){
1322  if(tcomm->getRank() == 0){
1323  print_usage(argv[0]);
1324  }
1325  throw s;
1326  }
1327 
1328  int ierr = 0;
1329 
1330  switch (opt){
1331 
1332  case 0:
1333  ierr = testFromDataFile(tcomm,numParts, imbalance,fname,
1334  pqParts, paramFile, k,
1335  migration_check_option,
1336  migration_all_to_all_type,
1337  migration_imbalance_cut_off,
1338  migration_processor_assignment_type,
1339  migration_doMigration_type, test_boxes, rectilinear);
1340  break;
1341 #ifdef hopper_separate_test
1342  case 1:
1343  ierr = testFromSeparateDataFiles(tcomm,numParts, imbalance,fname,
1344  pqParts, paramFile, k,
1345  migration_check_option,
1346  migration_all_to_all_type,
1347  migration_imbalance_cut_off,
1348  migration_processor_assignment_type,
1349  migration_doMigration_type, test_boxes, rectilinear);
1350  break;
1351 #endif
1352  default:
1353  ierr = GeometricGenInterface(tcomm, numParts, imbalance, fname,
1354  pqParts, paramFile, k,
1355  migration_check_option,
1356  migration_all_to_all_type,
1357  migration_imbalance_cut_off,
1358  migration_processor_assignment_type,
1359  migration_doMigration_type, test_boxes, rectilinear);
1360  break;
1361  }
1362 
1363  if (rank == 0) {
1364  if (ierr == 0) std::cout << "PASS" << std::endl;
1365  else std::cout << "FAIL" << std::endl;
1366  }
1367  }
1368 
1369 
1370  catch(std::string &s){
1371  if (rank == 0)
1372  cerr << s << endl;
1373  }
1374 
1375  catch(char * s){
1376  if (rank == 0)
1377  cerr << s << endl;
1378  }
1379 
1380  catch(char const* s){
1381  if (rank == 0)
1382  cerr << s << endl;
1383  }
1384 
1385  Kokkos::finalize ();
1386  return 0;
1387 }
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
#define CATCH_EXCEPTIONS_WITH_COUNT(ierr, pp)
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.
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)
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...
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)
void printTimers() const
Return the communicator passed to the problem.
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
string trim_right_copy(const string &s, const string &delimiters=" \\\)
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_copy(const string &s, const string &delimiters=" \\\)
Tpetra::MultiVector< double, int, int > tMVector_t
int getNumWeights()
##END Predistribution functions######################//
bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline)
RCP< tMVector_t > getUICoordinates()
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
Defines the PartitioningProblem class.
A class that computes and returns quality metrics.
string trim_left_copy(const string &s, const string &delimiters=" \\\)
Defines the BasicVectorAdapter class.
void solve(bool updateInputData=true)
Direct the problem to create a solution.
std::string testDataFilePath(".")