16 #include <Teuchos_ParameterList.hpp>
17 #include <Teuchos_RCP.hpp>
18 #include <Teuchos_FancyOStream.hpp>
19 #include <Teuchos_CommandLineProcessor.hpp>
20 #include <Tpetra_CrsMatrix.hpp>
21 #include <Tpetra_Vector.hpp>
22 #include <MatrixMarket_Tpetra.hpp>
31 typedef Tpetra::Vector<z2TestScalar, z2TestLO, z2TestGO>
Vector;
32 typedef Vector::node_type
Node;
34 typedef Tpetra::MultiVector<z2TestScalar, z2TestLO, z2TestGO,znode_t>
tMVector_t;
46 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm);
48 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> >);
50 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> >);
55 int main(
int narg,
char** arg)
57 Tpetra::ScopeGuard tscope(&narg, &arg);
58 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
59 int me = comm->getRank();
63 std::string inputFile =
"";
65 bool distributeInput =
true;
73 Teuchos::CommandLineProcessor cmdp (
false,
false);
74 cmdp.setOption(
"inputPath", &inputPath,
75 "Path to the MatrixMarket or Zoltan file to be read; "
76 "if not specified, a default path will be used.");
77 cmdp.setOption(
"inputFile", &inputFile,
78 "Name of the Matrix Market or Zoltan file to read; "
80 cmdp.setOption(
"distribute",
"no-distribute", &distributeInput,
81 "for Zoltan input files only, "
82 "indicate whether or not to distribute "
83 "input across the communicator");
84 cmdp.setOption(
"numParts", &numParts,
85 "Global number of parts;");
87 Teuchos::CommandLineProcessor::EParseCommandLineReturn
88 parseReturn= cmdp.parse( narg, arg );
90 if( parseReturn == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED )
99 RCP<UserInputForTests> uinput;
104 true, distributeInput));
108 std::cout <<
"Input file must be specified." << std::endl;
111 RCP<SparseMatrix_t> origMatrix = uinput->getUITpetraCrsMatrix();
116 std::cout <<
"NumRows = " << origMatrix->getGlobalNumRows() << std::endl
117 <<
"NumNonzeros = " << origMatrix->getGlobalNumEntries() << std::endl
118 <<
"NumProcs = " << comm->getSize() << std::endl
119 <<
"NumParts = " << numParts << std::endl;
122 if (origMatrix->getGlobalNumRows() < 40)
124 Teuchos::FancyOStream out(Teuchos::rcp(&std::cout,
false));
125 origMatrix->describe(out, Teuchos::VERB_EXTREME);
132 RCP<tMVector_t> coords;
135 coords = uinput->getUICoordinates();
140 std::cout <<
"FAIL: get coordinates" << std::endl;
159 std::cout <<
"FAIL: vector adapter" << std::endl;
168 int errRCB =
testForRCB(matAdapter, me, numParts, coords, comm);
169 int errPHG =
testForPHG(matAdapter, me, numParts, coords, comm);
174 #ifdef BRUTE_FORCE_SEARCH
175 for(
int setParts = 1; setParts <= 25; ++setParts) {
179 std::cout <<
"Brute force testing num parts: " << numParts << std::endl;
182 if(
testForRCB(matAdapter, me, numParts, coords, comm) != 0) {
return 1; }
183 if(
testForPHG(matAdapter, me, numParts, coords, comm) != 0) {
return 1; }
193 std::cout <<
"PASS" << std::endl;
205 std::vector<part_t> permPartNums,
206 std::vector<part_t> splitRangeBeg,
207 std::vector<part_t> splitRangeEnd,
208 std::vector<part_t> treeVertParents
212 if(numTreeVerts != static_cast<part_t>(splitRangeBeg.size()) - 1) {
215 if(numTreeVerts != static_cast<part_t>(splitRangeEnd.size()) - 1) {
218 if(numTreeVerts != static_cast<part_t>(treeVertParents.size()) - 1) {
222 for(
part_t n = 0; n <= numTreeVerts; ++n) {
223 if(n < static_cast<part_t>(permPartNums.size())) {
225 if(splitRangeEnd[n] != splitRangeBeg[n] + 1) {
226 std::cout <<
"Invalid terminal - range should be 1" << std::endl;
229 if(splitRangeBeg[n] != n) {
230 std::cout <<
"Invalid terminal - not pointing to myself!" << std::endl;
235 part_t beg = splitRangeBeg[n];
236 part_t end = splitRangeEnd[n];
238 std::vector<bool> findChildren(count,
false);
239 for(
part_t n2 = 0; n2 <= numTreeVerts; ++n2) {
240 if(treeVertParents[n2] == n) {
241 part_t beg2 = splitRangeBeg[n2];
242 part_t end2 = splitRangeEnd[n2];
243 for(
part_t q = beg2; q < end2; ++q) {
244 part_t setIndex = q - beg;
245 if(setIndex < 0 || setIndex >= count) {
246 std::cout <<
"Found bad child index - invalid results!" << std::endl;
249 if(findChildren[setIndex]) {
250 std::cout <<
"Found child twice - invalid results!" << std::endl;
253 findChildren[setIndex] =
true;
257 for(
part_t q = 0; q < count; ++q) {
258 if(!findChildren[q]) {
259 std::cout <<
"Did not find all children. Invalid results!" << std::endl;
264 if(n == numTreeVerts) {
266 if(splitRangeBeg[n] != 0) {
267 std::cout <<
"Root must start at 0!" << std::endl;
270 if(splitRangeEnd[n] != static_cast<part_t>(permPartNums.size())) {
271 std::cout <<
"Root must contain all parts!" << std::endl;
284 RCP<
const Teuchos::Comm<int> > comm)
287 std::vector<part_t> permPartNums;
288 std::vector<part_t> splitRangeBeg;
289 std::vector<part_t> splitRangeEnd;
290 std::vector<part_t> treeVertParents;
296 splitRangeEnd,treeVertParents);
299 if(comm->getRank() == 0) {
304 std::cout << std::endl <<
"Printing partition tree info..." << std::endl << std::endl;
307 std::cout <<
" numTreeVerts: " << numTreeVerts << std::endl << std::endl;
310 std::cout <<
" part array index:";
311 for(
part_t n = 0; n < static_cast<part_t>(permPartNums.size()); ++n) {
312 std::cout << std::setw(4) << n <<
" ";
314 std::cout << std::endl;
317 std::cout <<
" permPartNums: ";
318 for(
part_t n = 0; n < static_cast<part_t>(permPartNums.size()); ++n) {
319 std::cout << std::setw(4) << permPartNums[n] <<
" ";
321 std::cout << std::endl << std::endl;
324 std::cout <<
" node index: ";
325 for(
part_t n = 0; n < static_cast<part_t>(splitRangeBeg.size()); ++n) {
326 std::cout << std::setw(4) << n <<
" ";
328 std::cout << std::endl;
331 std::cout <<
" splitRangeBeg: ";
332 for(
part_t n = 0; n < static_cast<part_t>(splitRangeBeg.size()); ++n) {
333 std::cout << std::setw(4) << splitRangeBeg[n] <<
" ";
335 std::cout << std::endl;
338 std::cout <<
" splitRangeEnd: ";
339 for(
part_t n = 0; n < static_cast<part_t>(splitRangeEnd.size()); ++n) {
340 std::cout << std::setw(4) << splitRangeEnd[n] <<
" ";
342 std::cout << std::endl;
345 std::cout <<
" treeVertParents: ";
346 for(
part_t n = 0; n < static_cast<part_t>(treeVertParents.size()); ++n) {
347 std::cout << std::setw(4) << treeVertParents[n] <<
" ";
349 std::cout << std::endl << std::endl;
353 if(!
validate(numTreeVerts, permPartNums, splitRangeBeg, splitRangeEnd,
366 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
372 Teuchos::ParameterList params;
374 params.set(
"num_global_parts", numParts);
375 params.set(
"partitioning_approach",
"partition");
376 params.set(
"algorithm",
"rcb");
377 params.set(
"keep_partition_tree",
true);
388 if (me == 0) std::cout <<
"Calling solve() " << std::endl;
390 if (me == 0) std::cout <<
"Done solve() " << std::endl;
392 catch (std::runtime_error &e)
394 std::cout <<
"Runtime exception returned from solve(): " << e.what();
395 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
397 std::cout <<
" PASS" << std::endl;
402 std::cout <<
" FAIL" << std::endl;
406 catch (std::logic_error &e)
408 std::cout <<
"Logic exception returned from solve(): " << e.what()
409 <<
" FAIL" << std::endl;
412 catch (std::bad_alloc &e)
414 std::cout <<
"Bad_alloc exception returned from solve(): " << e.what()
415 <<
" FAIL" << std::endl;
418 catch (std::exception &e)
420 std::cout <<
"Unknown exception returned from solve(). " << e.what()
421 <<
" FAIL" << std::endl;
433 std::cout <<
"RCB should produce a binary partitioning tree. FAIL" << std::endl;
446 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
452 Teuchos::ParameterList params;
454 params.set(
"num_global_parts", numParts);
455 params.set(
"partitioning_approach",
"partition");
456 params.set(
"algorithm",
"zoltan");
457 params.set(
"keep_partition_tree",
true);
459 Teuchos::ParameterList &zparams = params.sublist(
"zoltan_parameters",
false);
460 zparams.set(
"LB_METHOD",
"phg");
461 zparams.set(
"FINAL_OUTPUT",
"1");
472 if (me == 0) std::cout <<
"Calling solve() " << std::endl;
474 if (me == 0) std::cout <<
"Done solve() " << std::endl;
476 catch (std::runtime_error &e)
478 std::cout <<
"Runtime exception returned from solve(): " << e.what();
479 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
481 std::cout <<
" PASS" << std::endl;
486 std::cout <<
" FAIL" << std::endl;
490 catch (std::logic_error &e)
492 std::cout <<
"Logic exception returned from solve(): " << e.what()
493 <<
" FAIL" << std::endl;
496 catch (std::bad_alloc &e)
498 std::cout <<
"Bad_alloc exception returned from solve(): " << e.what()
499 <<
" FAIL" << std::endl;
502 catch (std::exception &e)
504 std::cout <<
"Unknown exception returned from solve(). " << e.what()
505 <<
" FAIL" << std::endl;
516 std::cout <<
"PHG should produce a binary partitioning tree. FAIL" << std::endl;
529 RCP<tMVector_t> coords, RCP<
const Teuchos::Comm<int> > comm)
535 Teuchos::ParameterList params;
537 params.set(
"num_global_parts", numParts);
538 params.set(
"algorithm",
"multijagged");
539 params.set(
"rectilinear",
true);
541 params.set(
"keep_partition_tree",
true);
552 if (me == 0) std::cout <<
"Calling solve() " << std::endl;
554 if (me == 0) std::cout <<
"Done solve() " << std::endl;
556 catch (std::runtime_error &e)
558 std::cout <<
"Runtime exception returned from solve(): " << e.what();
559 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
561 std::cout <<
" PASS" << std::endl;
566 std::cout <<
" FAIL" << std::endl;
570 catch (std::logic_error &e)
572 std::cout <<
"Logic exception returned from solve(): " << e.what()
573 <<
" FAIL" << std::endl;
576 catch (std::bad_alloc &e)
578 std::cout <<
"Bad_alloc exception returned from solve(): " << e.what()
579 <<
" FAIL" << std::endl;
582 catch (std::exception &e)
584 std::cout <<
"Unknown exception returned from solve(). " << e.what()
585 <<
" FAIL" << std::endl;
619 std::cout <<
"MJ should not produce a binary partitioning tree for this problem. FAIL" << std::endl;
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
virtual bool isPartitioningTreeBinary() const
calculate if partition tree is binary.
int analyze(Zoltan2::PartitioningProblem< SparseMatrixAdapter_t > &problem, RCP< const Teuchos::Comm< int > > comm)
Tpetra::CrsMatrix< z2TestScalar, z2TestLO, z2TestGO > SparseMatrix_t
int main(int narg, char **arg)
common code used by tests
typename InputTraits< User >::part_t part_t
Tpetra::Vector< z2TestScalar, z2TestLO, z2TestGO > Vector
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)
Zoltan2::XpetraCrsMatrixAdapter< SparseMatrix_t, tMVector_t > SparseMatrixAdapter_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
Zoltan2::XpetraMultiVectorAdapter< tMVector_t > MultiVectorAdapter_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)
Tpetra::Map::local_ordinal_type zlno_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.
void setCoordinateInput(VectorAdapter< UserCoord > *coordData) override
Allow user to provide additional data that contains coordinate info associated with the MatrixAdapter...
int testForPHG(SparseMatrixAdapter_t &matAdapter, int myrank, part_t numparts, RCP< tMVector_t > coords, RCP< const Teuchos::Comm< int > >)
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
Tpetra::Map::global_ordinal_type zgno_t
void solve(bool updateInputData=true)
Direct the problem to create a solution.
std::string testDataFilePath(".")