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_DefaultPlatform.hpp> 57 #include <Tpetra_Vector.hpp> 58 #include <MatrixMarket_Tpetra.hpp> 68 typedef Tpetra::Vector<z2TestScalar, z2TestLO, z2TestGO>
Vector;
69 typedef Vector::node_type
Node;
71 typedef Tpetra::MultiVector<z2TestScalar, z2TestLO, z2TestGO,znode_t>
tMVector_t;
83 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm);
85 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> >);
87 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> >);
92 int main(
int argc,
char** argv)
94 std::string inputFile =
"";
96 bool distributeInput =
true;
104 Teuchos::GlobalMPISession mpiSession(&argc, &argv, NULL);
105 RCP<const Teuchos::Comm<int> > comm =
106 Tpetra::DefaultPlatform::getDefaultPlatform().getComm();
107 int me = comm->getRank();
113 Teuchos::CommandLineProcessor cmdp (
false,
false);
114 cmdp.setOption(
"inputPath", &inputPath,
115 "Path to the MatrixMarket or Zoltan file to be read; " 116 "if not specified, a default path will be used.");
117 cmdp.setOption(
"inputFile", &inputFile,
118 "Name of the Matrix Market or Zoltan file to read; " 120 cmdp.setOption(
"distribute",
"no-distribute", &distributeInput,
121 "for Zoltan input files only, " 122 "indicate whether or not to distribute " 123 "input across the communicator");
124 cmdp.setOption(
"numParts", &numParts,
125 "Global number of parts;");
127 Teuchos::CommandLineProcessor::EParseCommandLineReturn
128 parseReturn= cmdp.parse( argc, argv );
130 if( parseReturn == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED )
139 RCP<UserInputForTests> uinput;
144 true, distributeInput));
148 std::cout <<
"Input file must be specified." << std::endl;
151 RCP<SparseMatrix_t> origMatrix = uinput->getUITpetraCrsMatrix();
156 cout <<
"NumRows = " << origMatrix->getGlobalNumRows() << endl
157 <<
"NumNonzeros = " << origMatrix->getGlobalNumEntries() << endl
158 <<
"NumProcs = " << comm->getSize() << endl
159 <<
"NumParts = " << numParts << endl;
162 if (origMatrix->getGlobalNumRows() < 40)
164 Teuchos::FancyOStream out(Teuchos::rcp(&std::cout,
false));
165 origMatrix->describe(out, Teuchos::VERB_EXTREME);
172 RCP<tMVector_t> coords;
175 coords = uinput->getUICoordinates();
180 std::cout <<
"FAIL: get coordinates" << std::endl;
199 std::cout <<
"FAIL: vector adapter" << std::endl;
208 int errRCB =
testForRCB(matAdapter, me, numParts, coords, comm);
209 int errPHG =
testForPHG(matAdapter, me, numParts, coords, comm);
214 #ifdef BRUTE_FORCE_SEARCH 215 for(
int setParts = 1; setParts <= 25; ++setParts) {
219 std::cout <<
"Brute force testing num parts: " << numParts << std::endl;
222 if(
testForRCB(matAdapter, me, numParts, coords, comm) != 0) {
return 1; }
223 if(
testForPHG(matAdapter, me, numParts, coords, comm) != 0) {
return 1; }
233 std::cout <<
"PASS" << std::endl;
245 std::vector<part_t> permPartNums,
246 std::vector<part_t> splitRangeBeg,
247 std::vector<part_t> splitRangeEnd,
248 std::vector<part_t> treeVertParents
252 if(numTreeVerts != static_cast<part_t>(splitRangeBeg.size()) - 1) {
255 if(numTreeVerts != static_cast<part_t>(splitRangeEnd.size()) - 1) {
258 if(numTreeVerts != static_cast<part_t>(treeVertParents.size()) - 1) {
262 for(
part_t n = 0; n <= numTreeVerts; ++n) {
263 if(n < static_cast<part_t>(permPartNums.size())) {
265 if(splitRangeEnd[n] != splitRangeBeg[n] + 1) {
266 std::cout <<
"Invalid terminal - range should be 1" << std::endl;
269 if(splitRangeBeg[n] != n) {
270 std::cout <<
"Invalid terminal - not pointing to myself!" << std::endl;
275 part_t beg = splitRangeBeg[n];
276 part_t end = splitRangeEnd[n];
278 std::vector<bool> findChildren(count,
false);
279 for(
part_t n2 = 0; n2 <= numTreeVerts; ++n2) {
280 if(treeVertParents[n2] == n) {
281 part_t beg2 = splitRangeBeg[n2];
282 part_t end2 = splitRangeEnd[n2];
283 for(
part_t q = beg2; q < end2; ++q) {
284 part_t setIndex = q - beg;
285 if(setIndex < 0 || setIndex >= count) {
286 std::cout <<
"Found bad child index - invalid results!" << std::endl;
289 if(findChildren[setIndex]) {
290 std::cout <<
"Found child twice - invalid results!" << std::endl;
293 findChildren[setIndex] =
true;
297 for(
part_t q = 0; q < count; ++q) {
298 if(!findChildren[q]) {
299 std::cout <<
"Did not find all children. Invalid results!" << std::endl;
304 if(n == numTreeVerts) {
306 if(splitRangeBeg[n] != 0) {
307 std::cout <<
"Root must start at 0!" << std::endl;
310 if(splitRangeEnd[n] != static_cast<part_t>(permPartNums.size())) {
311 std::cout <<
"Root must contain all parts!" << std::endl;
324 RCP<
const Teuchos::Comm<int> > comm)
327 std::vector<part_t> permPartNums;
328 std::vector<part_t> splitRangeBeg;
329 std::vector<part_t> splitRangeEnd;
330 std::vector<part_t> treeVertParents;
336 splitRangeEnd,treeVertParents);
339 if(comm->getRank() == 0) {
344 cout << endl <<
"Printing partition tree info..." << endl << endl;
347 cout <<
" numTreeVerts: " << numTreeVerts << endl << endl;
350 cout <<
" part array index:";
351 for(
part_t n = 0; n < static_cast<part_t>(permPartNums.size()); ++n) {
352 cout << setw(4) << n <<
" ";
357 cout <<
" permPartNums: ";
358 for(
part_t n = 0; n < static_cast<part_t>(permPartNums.size()); ++n) {
359 cout << setw(4) << permPartNums[n] <<
" ";
361 cout << endl << endl;
364 cout <<
" node index: ";
365 for(
part_t n = 0; n < static_cast<part_t>(splitRangeBeg.size()); ++n) {
366 cout << setw(4) << n <<
" ";
371 cout <<
" splitRangeBeg: ";
372 for(
part_t n = 0; n < static_cast<part_t>(splitRangeBeg.size()); ++n) {
373 cout << setw(4) << splitRangeBeg[n] <<
" ";
378 cout <<
" splitRangeEnd: ";
379 for(
part_t n = 0; n < static_cast<part_t>(splitRangeEnd.size()); ++n) {
380 cout << setw(4) << splitRangeEnd[n] <<
" ";
385 cout <<
" treeVertParents: ";
386 for(
part_t n = 0; n < static_cast<part_t>(treeVertParents.size()); ++n) {
387 cout << setw(4) << treeVertParents[n] <<
" ";
389 cout << endl << endl;
393 if(!
validate(numTreeVerts, permPartNums, splitRangeBeg, splitRangeEnd,
406 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
412 Teuchos::ParameterList params;
414 params.set(
"num_global_parts", numParts);
415 params.set(
"partitioning_approach",
"partition");
416 params.set(
"algorithm",
"rcb");
417 params.set(
"keep_partition_tree",
true);
428 if (me == 0) cout <<
"Calling solve() " << endl;
430 if (me == 0) cout <<
"Done solve() " << endl;
432 catch (std::runtime_error &e)
434 cout <<
"Runtime exception returned from solve(): " << e.what();
435 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
437 cout <<
" PASS" << endl;
442 cout <<
" FAIL" << endl;
446 catch (std::logic_error &e)
448 cout <<
"Logic exception returned from solve(): " << e.what()
452 catch (std::bad_alloc &e)
454 cout <<
"Bad_alloc exception returned from solve(): " << e.what()
458 catch (std::exception &e)
460 cout <<
"Unknown exception returned from solve(). " << e.what()
473 cout <<
"RCB should produce a binary partitioning tree. FAIL" << std::endl;
486 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
492 Teuchos::ParameterList params;
494 params.set(
"num_global_parts", numParts);
495 params.set(
"partitioning_approach",
"partition");
496 params.set(
"algorithm",
"zoltan");
497 params.set(
"keep_partition_tree",
true);
499 Teuchos::ParameterList &zparams = params.sublist(
"zoltan_parameters",
false);
500 zparams.set(
"LB_METHOD",
"phg");
501 zparams.set(
"FINAL_OUTPUT",
"1");
512 if (me == 0) cout <<
"Calling solve() " << endl;
514 if (me == 0) cout <<
"Done solve() " << endl;
516 catch (std::runtime_error &e)
518 cout <<
"Runtime exception returned from solve(): " << e.what();
519 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
521 cout <<
" PASS" << endl;
526 cout <<
" FAIL" << endl;
530 catch (std::logic_error &e)
532 cout <<
"Logic exception returned from solve(): " << e.what()
536 catch (std::bad_alloc &e)
538 cout <<
"Bad_alloc exception returned from solve(): " << e.what()
542 catch (std::exception &e)
544 cout <<
"Unknown exception returned from solve(). " << e.what()
556 cout <<
"PHG should produce a binary partitioning tree. FAIL" << std::endl;
569 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
575 Teuchos::ParameterList params;
577 params.set(
"num_global_parts", numParts);
578 params.set(
"algorithm",
"multijagged");
579 params.set(
"rectilinear",
true);
581 params.set(
"keep_partition_tree",
true);
592 if (me == 0) cout <<
"Calling solve() " << endl;
594 if (me == 0) cout <<
"Done solve() " << endl;
596 catch (std::runtime_error &e)
598 cout <<
"Runtime exception returned from solve(): " << e.what();
599 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
601 cout <<
" PASS" << endl;
606 cout <<
" FAIL" << endl;
610 catch (std::logic_error &e)
612 cout <<
"Logic exception returned from solve(): " << e.what()
616 catch (std::bad_alloc &e)
618 cout <<
"Bad_alloc exception returned from solve(): " << e.what()
622 catch (std::exception &e)
624 cout <<
"Unknown exception returned from solve(). " << e.what()
659 cout <<
"MJ should not produce a binary partitioning tree for this problem. FAIL" << std::endl;
Zoltan2::XpetraCrsMatrixAdapter< SparseMatrix_t, tMVector_t > SparseMatrixAdapter_t
Tpetra::CrsMatrix< z2TestScalar, z2TestLO, z2TestGO > SparseMatrix_t
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
Tpetra::MultiVector< z2TestScalar, z2TestLO, z2TestGO, znode_t > tMVector_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
int analyze(Zoltan2::PartitioningProblem< SparseMatrixAdapter_t > &problem, RCP< const Teuchos::Comm< int > > comm)
int main(int argc, char **argv)
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
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 > >)
virtual bool isPartitioningTreeBinary() const
calculate if partition tree is binary.
void solve(bool updateInputData=true)
Direct the problem to create a solution.
Tpetra::Vector< z2TestScalar, z2TestLO, z2TestGO > Vector
std::string testDataFilePath(".")