51 #include <Teuchos_ParameterList.hpp>
52 #include <Teuchos_RCP.hpp>
53 #include <Teuchos_FancyOStream.hpp>
54 #include <Teuchos_CommandLineProcessor.hpp>
55 #include <Tpetra_CrsMatrix.hpp>
56 #include <Tpetra_Vector.hpp>
57 #include <MatrixMarket_Tpetra.hpp>
66 typedef Tpetra::Vector<z2TestScalar, z2TestLO, z2TestGO>
Vector;
67 typedef Vector::node_type
Node;
69 typedef Tpetra::MultiVector<z2TestScalar, z2TestLO, z2TestGO,znode_t>
tMVector_t;
81 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm);
83 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> >);
85 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> >);
90 int main(
int narg,
char** arg)
92 Tpetra::ScopeGuard tscope(&narg, &arg);
93 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
94 int me = comm->getRank();
98 std::string inputFile =
"";
100 bool distributeInput =
true;
108 Teuchos::CommandLineProcessor cmdp (
false,
false);
109 cmdp.setOption(
"inputPath", &inputPath,
110 "Path to the MatrixMarket or Zoltan file to be read; "
111 "if not specified, a default path will be used.");
112 cmdp.setOption(
"inputFile", &inputFile,
113 "Name of the Matrix Market or Zoltan file to read; "
115 cmdp.setOption(
"distribute",
"no-distribute", &distributeInput,
116 "for Zoltan input files only, "
117 "indicate whether or not to distribute "
118 "input across the communicator");
119 cmdp.setOption(
"numParts", &numParts,
120 "Global number of parts;");
122 Teuchos::CommandLineProcessor::EParseCommandLineReturn
123 parseReturn= cmdp.parse( narg, arg );
125 if( parseReturn == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED )
134 RCP<UserInputForTests> uinput;
139 true, distributeInput));
143 std::cout <<
"Input file must be specified." << std::endl;
146 RCP<SparseMatrix_t> origMatrix = uinput->getUITpetraCrsMatrix();
151 std::cout <<
"NumRows = " << origMatrix->getGlobalNumRows() << std::endl
152 <<
"NumNonzeros = " << origMatrix->getGlobalNumEntries() << std::endl
153 <<
"NumProcs = " << comm->getSize() << std::endl
154 <<
"NumParts = " << numParts << std::endl;
157 if (origMatrix->getGlobalNumRows() < 40)
159 Teuchos::FancyOStream out(Teuchos::rcp(&std::cout,
false));
160 origMatrix->describe(out, Teuchos::VERB_EXTREME);
167 RCP<tMVector_t> coords;
170 coords = uinput->getUICoordinates();
175 std::cout <<
"FAIL: get coordinates" << std::endl;
194 std::cout <<
"FAIL: vector adapter" << std::endl;
203 int errRCB =
testForRCB(matAdapter, me, numParts, coords, comm);
204 int errPHG =
testForPHG(matAdapter, me, numParts, coords, comm);
209 #ifdef BRUTE_FORCE_SEARCH
210 for(
int setParts = 1; setParts <= 25; ++setParts) {
214 std::cout <<
"Brute force testing num parts: " << numParts << std::endl;
217 if(
testForRCB(matAdapter, me, numParts, coords, comm) != 0) {
return 1; }
218 if(
testForPHG(matAdapter, me, numParts, coords, comm) != 0) {
return 1; }
228 std::cout <<
"PASS" << std::endl;
240 std::vector<part_t> permPartNums,
241 std::vector<part_t> splitRangeBeg,
242 std::vector<part_t> splitRangeEnd,
243 std::vector<part_t> treeVertParents
247 if(numTreeVerts != static_cast<part_t>(splitRangeBeg.size()) - 1) {
250 if(numTreeVerts != static_cast<part_t>(splitRangeEnd.size()) - 1) {
253 if(numTreeVerts != static_cast<part_t>(treeVertParents.size()) - 1) {
257 for(
part_t n = 0; n <= numTreeVerts; ++n) {
258 if(n < static_cast<part_t>(permPartNums.size())) {
260 if(splitRangeEnd[n] != splitRangeBeg[n] + 1) {
261 std::cout <<
"Invalid terminal - range should be 1" << std::endl;
264 if(splitRangeBeg[n] != n) {
265 std::cout <<
"Invalid terminal - not pointing to myself!" << std::endl;
270 part_t beg = splitRangeBeg[n];
271 part_t end = splitRangeEnd[n];
273 std::vector<bool> findChildren(count,
false);
274 for(
part_t n2 = 0; n2 <= numTreeVerts; ++n2) {
275 if(treeVertParents[n2] == n) {
276 part_t beg2 = splitRangeBeg[n2];
277 part_t end2 = splitRangeEnd[n2];
278 for(
part_t q = beg2; q < end2; ++q) {
279 part_t setIndex = q - beg;
280 if(setIndex < 0 || setIndex >= count) {
281 std::cout <<
"Found bad child index - invalid results!" << std::endl;
284 if(findChildren[setIndex]) {
285 std::cout <<
"Found child twice - invalid results!" << std::endl;
288 findChildren[setIndex] =
true;
292 for(
part_t q = 0; q < count; ++q) {
293 if(!findChildren[q]) {
294 std::cout <<
"Did not find all children. Invalid results!" << std::endl;
299 if(n == numTreeVerts) {
301 if(splitRangeBeg[n] != 0) {
302 std::cout <<
"Root must start at 0!" << std::endl;
305 if(splitRangeEnd[n] != static_cast<part_t>(permPartNums.size())) {
306 std::cout <<
"Root must contain all parts!" << std::endl;
319 RCP<
const Teuchos::Comm<int> > comm)
322 std::vector<part_t> permPartNums;
323 std::vector<part_t> splitRangeBeg;
324 std::vector<part_t> splitRangeEnd;
325 std::vector<part_t> treeVertParents;
331 splitRangeEnd,treeVertParents);
334 if(comm->getRank() == 0) {
339 std::cout << std::endl <<
"Printing partition tree info..." << std::endl << std::endl;
342 std::cout <<
" numTreeVerts: " << numTreeVerts << std::endl << std::endl;
345 std::cout <<
" part array index:";
346 for(
part_t n = 0; n < static_cast<part_t>(permPartNums.size()); ++n) {
347 std::cout << std::setw(4) << n <<
" ";
349 std::cout << std::endl;
352 std::cout <<
" permPartNums: ";
353 for(
part_t n = 0; n < static_cast<part_t>(permPartNums.size()); ++n) {
354 std::cout << std::setw(4) << permPartNums[n] <<
" ";
356 std::cout << std::endl << std::endl;
359 std::cout <<
" node index: ";
360 for(
part_t n = 0; n < static_cast<part_t>(splitRangeBeg.size()); ++n) {
361 std::cout << std::setw(4) << n <<
" ";
363 std::cout << std::endl;
366 std::cout <<
" splitRangeBeg: ";
367 for(
part_t n = 0; n < static_cast<part_t>(splitRangeBeg.size()); ++n) {
368 std::cout << std::setw(4) << splitRangeBeg[n] <<
" ";
370 std::cout << std::endl;
373 std::cout <<
" splitRangeEnd: ";
374 for(
part_t n = 0; n < static_cast<part_t>(splitRangeEnd.size()); ++n) {
375 std::cout << std::setw(4) << splitRangeEnd[n] <<
" ";
377 std::cout << std::endl;
380 std::cout <<
" treeVertParents: ";
381 for(
part_t n = 0; n < static_cast<part_t>(treeVertParents.size()); ++n) {
382 std::cout << std::setw(4) << treeVertParents[n] <<
" ";
384 std::cout << std::endl << std::endl;
388 if(!
validate(numTreeVerts, permPartNums, splitRangeBeg, splitRangeEnd,
401 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
407 Teuchos::ParameterList params;
409 params.set(
"num_global_parts", numParts);
410 params.set(
"partitioning_approach",
"partition");
411 params.set(
"algorithm",
"rcb");
412 params.set(
"keep_partition_tree",
true);
423 if (me == 0) std::cout <<
"Calling solve() " << std::endl;
425 if (me == 0) std::cout <<
"Done solve() " << std::endl;
427 catch (std::runtime_error &e)
429 std::cout <<
"Runtime exception returned from solve(): " << e.what();
430 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
432 std::cout <<
" PASS" << std::endl;
437 std::cout <<
" FAIL" << std::endl;
441 catch (std::logic_error &e)
443 std::cout <<
"Logic exception returned from solve(): " << e.what()
444 <<
" FAIL" << std::endl;
447 catch (std::bad_alloc &e)
449 std::cout <<
"Bad_alloc exception returned from solve(): " << e.what()
450 <<
" FAIL" << std::endl;
453 catch (std::exception &e)
455 std::cout <<
"Unknown exception returned from solve(). " << e.what()
456 <<
" FAIL" << std::endl;
468 std::cout <<
"RCB should produce a binary partitioning tree. FAIL" << std::endl;
481 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
487 Teuchos::ParameterList params;
489 params.set(
"num_global_parts", numParts);
490 params.set(
"partitioning_approach",
"partition");
491 params.set(
"algorithm",
"zoltan");
492 params.set(
"keep_partition_tree",
true);
494 Teuchos::ParameterList &zparams = params.sublist(
"zoltan_parameters",
false);
495 zparams.set(
"LB_METHOD",
"phg");
496 zparams.set(
"FINAL_OUTPUT",
"1");
507 if (me == 0) std::cout <<
"Calling solve() " << std::endl;
509 if (me == 0) std::cout <<
"Done solve() " << std::endl;
511 catch (std::runtime_error &e)
513 std::cout <<
"Runtime exception returned from solve(): " << e.what();
514 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
516 std::cout <<
" PASS" << std::endl;
521 std::cout <<
" FAIL" << std::endl;
525 catch (std::logic_error &e)
527 std::cout <<
"Logic exception returned from solve(): " << e.what()
528 <<
" FAIL" << std::endl;
531 catch (std::bad_alloc &e)
533 std::cout <<
"Bad_alloc exception returned from solve(): " << e.what()
534 <<
" FAIL" << std::endl;
537 catch (std::exception &e)
539 std::cout <<
"Unknown exception returned from solve(). " << e.what()
540 <<
" FAIL" << std::endl;
551 std::cout <<
"PHG should produce a binary partitioning tree. FAIL" << std::endl;
564 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
570 Teuchos::ParameterList params;
572 params.set(
"num_global_parts", numParts);
573 params.set(
"algorithm",
"multijagged");
574 params.set(
"rectilinear",
true);
576 params.set(
"keep_partition_tree",
true);
587 if (me == 0) std::cout <<
"Calling solve() " << std::endl;
589 if (me == 0) std::cout <<
"Done solve() " << std::endl;
591 catch (std::runtime_error &e)
593 std::cout <<
"Runtime exception returned from solve(): " << e.what();
594 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
596 std::cout <<
" PASS" << std::endl;
601 std::cout <<
" FAIL" << std::endl;
605 catch (std::logic_error &e)
607 std::cout <<
"Logic exception returned from solve(): " << e.what()
608 <<
" FAIL" << std::endl;
611 catch (std::bad_alloc &e)
613 std::cout <<
"Bad_alloc exception returned from solve(): " << e.what()
614 <<
" FAIL" << std::endl;
617 catch (std::exception &e)
619 std::cout <<
"Unknown exception returned from solve(). " << e.what()
620 <<
" FAIL" << std::endl;
654 std::cout <<
"MJ should not produce a binary partitioning tree for this problem. FAIL" << std::endl;
Tpetra::Vector< z2TestScalar, z2TestLO, z2TestGO > Vector
Zoltan2::XpetraCrsMatrixAdapter< SparseMatrix_t, tMVector_t > SparseMatrixAdapter_t
Tpetra::CrsMatrix< z2TestScalar, z2TestLO, z2TestGO > SparseMatrix_t
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
int main(int narg, char *arg[])
virtual bool isPartitioningTreeBinary() const
calculate if partition tree is binary.
int analyze(Zoltan2::PartitioningProblem< SparseMatrixAdapter_t > &problem, RCP< const Teuchos::Comm< int > > comm)
void setCoordinateInput(VectorAdapter< UserCoord > *coordData)
Allow user to provide additional data that contains coordinate info associated with the MatrixAdapter...
common code used by tests
Defines the XpetraMultiVectorAdapter.
SparseMatrixAdapter_t::part_t part_t
Defines the XpetraCrsMatrixAdapter class.
A PartitioningSolution is a solution to a partitioning problem.
bool validate(part_t numTreeVerts, std::vector< part_t > permPartNums, std::vector< part_t > splitRangeBeg, std::vector< part_t > splitRangeEnd, std::vector< part_t > treeVertParents)
InputTraits< User >::part_t part_t
void getPartitionTree(part_t &numTreeVerts, std::vector< part_t > &permPartNums, std::vector< part_t > &splitRangeBeg, std::vector< part_t > &splitRangeEnd, std::vector< part_t > &treeVertParents) const
get the partition tree - fill the relevant arrays
An adapter for Xpetra::MultiVector.
int testForRCB(SparseMatrixAdapter_t &matAdapter, int myrank, part_t numparts, RCP< tMVector_t > coords, RCP< const Teuchos::Comm< int > > comm)
Zoltan2::XpetraMultiVectorAdapter< tMVector_t > MultiVectorAdapter_t
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
PartitioningProblem sets up partitioning problems for the user.
int testForMJ(SparseMatrixAdapter_t &matAdapter, int myrank, part_t numparts, RCP< tMVector_t > coords, RCP< const Teuchos::Comm< int > >)
Defines the PartitioningProblem class.
int testForPHG(SparseMatrixAdapter_t &matAdapter, int myrank, part_t numparts, RCP< tMVector_t > coords, RCP< const Teuchos::Comm< int > >)
void solve(bool updateInputData=true)
Direct the problem to create a solution.
std::string testDataFilePath(".")