17 #include <Teuchos_ParameterList.hpp>
18 #include <Teuchos_RCP.hpp>
19 #include <Teuchos_FancyOStream.hpp>
20 #include <Teuchos_CommandLineProcessor.hpp>
21 #include <Tpetra_CrsMatrix.hpp>
22 #include <Tpetra_Vector.hpp>
23 #include <MatrixMarket_Tpetra.hpp>
47 typedef Tpetra::CrsMatrix<z2TestScalar, z2TestLO, z2TestGO>
SparseMatrix;
49 typedef Tpetra::Vector<z2TestScalar, z2TestLO, z2TestGO>
VectorT;
50 typedef VectorT::node_type
Node;
58 typedef Tpetra::Vector<int, z2TestLO, z2TestGO>
IntVector;
61 #define epsilon 0.00000001
65 int main(
int narg,
char** arg)
67 std::string inputFile =
"";
68 std::string outputFile =
"";
71 bool distributeInput =
true;
72 bool haveFailure =
false;
77 bool isNormalized =
false;
78 bool isGeneralized =
false;
79 std::string precType =
"jacobi";
80 std::string initialGuess =
"random";
81 bool useFullOrtho =
true;
84 Tpetra::ScopeGuard tscope(&narg, &arg);
85 RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
86 int me = comm->getRank();
87 int commsize = comm->getSize();
90 Teuchos::CommandLineProcessor cmdp (
false,
false);
91 cmdp.setOption(
"inputPath", &inputPath,
92 "Path to the MatrixMarket or Zoltan file to be read; "
93 "if not specified, a default path will be used.");
94 cmdp.setOption(
"inputFile", &inputFile,
95 "Name of the Matrix Market or Zoltan file to read; "
96 "if not specified, a matrix will be generated by MueLu.");
97 cmdp.setOption(
"outputFile", &outputFile,
98 "Name of the Matrix Market sparse matrix file to write, "
99 "echoing the input/generated matrix.");
100 cmdp.setOption(
"vertexWeights", &nVwgts,
101 "Number of weights to generate for each vertex");
102 cmdp.setOption(
"verbose",
"quiet", &verbose,
103 "Print messages and results.");
104 cmdp.setOption(
"distribute",
"no-distribute", &distributeInput,
105 "indicate whether or not to distribute "
106 "input across the communicator");
108 cmdp.setOption(
"normalized",
"combinatorial", &isNormalized,
109 "indicate whether or not to use a normalized Laplacian.");
110 cmdp.setOption(
"generalized",
"non-generalized", &isGeneralized,
111 "indicate whether or not to use a generalized Laplacian.");
112 cmdp.setOption(
"precond", &precType,
113 "indicate which preconditioner to use [muelu|jacobi|polynomial].");
114 cmdp.setOption(
"initialGuess", &initialGuess,
115 "initial guess for LOBPCG");
116 cmdp.setOption(
"useFullOrtho",
"partialOrtho", &useFullOrtho,
117 "use full orthogonalization.");
128 std::string matrixType(
"Laplace3D");
130 cmdp.setOption(
"x", &xdim,
131 "number of gridpoints in X dimension for "
132 "mesh used to generate matrix.");
133 cmdp.setOption(
"y", &ydim,
134 "number of gridpoints in Y dimension for "
135 "mesh used to generate matrix.");
136 cmdp.setOption(
"z", &zdim,
137 "number of gridpoints in Z dimension for "
138 "mesh used to generate matrix.");
139 cmdp.setOption(
"matrix", &matrixType,
140 "Matrix type: Laplace1D, Laplace2D, or Laplace3D");
143 cmdp.parse(narg, arg);
145 RCP<UserInputForTests> uinput;
149 true, distributeInput));
153 true, distributeInput));
155 RCP<SparseMatrix> origMatrix = uinput->getUITpetraCrsMatrix();
157 if (origMatrix->getGlobalNumRows() < 40) {
158 Teuchos::FancyOStream out(Teuchos::rcp(&std::cout,
false));
159 origMatrix->describe(out, Teuchos::VERB_EXTREME);
163 if (outputFile !=
"") {
165 Tpetra::MatrixMarket::Writer<SparseMatrix>::writeSparseFile(outputFile,
166 origMatrix, verbose);
170 std::cout <<
"NumRows = " << origMatrix->getGlobalNumRows() << std::endl
171 <<
"NumNonzeros = " << origMatrix->getGlobalNumEntries() << std::endl
172 <<
"NumProcs = " << comm->getSize() << std::endl
173 <<
"NumLocalRows (rank 0) = " << origMatrix->getLocalNumRows() << std::endl;
176 RCP<VectorT> origVector, origProd;
177 origProd = Tpetra::createVector<z2TestScalar,z2TestLO,z2TestGO>(
178 origMatrix->getRangeMap());
179 origVector = Tpetra::createVector<z2TestScalar,z2TestLO,z2TestGO>(
180 origMatrix->getDomainMap());
181 origVector->randomize();
184 Teuchos::RCP<Teuchos::ParameterList> params(
new Teuchos::ParameterList);
185 params->set(
"num_global_parts", commsize);
186 Teuchos::RCP<Teuchos::ParameterList> sphynxParams(
new Teuchos::ParameterList);
187 sphynxParams->set(
"sphynx_skip_preprocessing",
true);
188 sphynxParams->set(
"sphynx_preconditioner_type", precType);
189 sphynxParams->set(
"sphynx_verbosity", verbose ? 1 : 0);
190 sphynxParams->set(
"sphynx_initial_guess", initialGuess);
191 sphynxParams->set(
"sphynx_use_full_ortho", useFullOrtho);
192 std::string problemType =
"combinatorial";
194 problemType =
"normalized";
195 else if(isGeneralized)
196 problemType =
"generalized";
197 sphynxParams->set(
"sphynx_problem_type", problemType);
200 Teuchos::RCP<SparseGraphAdapter> adapter = Teuchos::rcp(
new SparseGraphAdapter(origMatrix->getCrsGraph(), nVwgts));
209 size_t nrows = origMatrix->getLocalNumRows();
212 for (
size_t i = 0; i < nrows; i++) {
213 size_t idx = i * nVwgts;
214 vwgts[idx] =
zscalar_t(origMatrix->getRowMap()->getGlobalElement(i));
215 for (
int j = 1; j < nVwgts; j++) vwgts[idx+j] = 1.;
217 for (
int j = 0; j < nVwgts; j++) {
218 if (j !=
NNZ_IDX) adapter->setVertexWeights(&vwgts[j], nVwgts, j);
219 else adapter->setVertexWeightIsDegree(
NNZ_IDX);
228 if (me == 0) std::cout <<
"Calling solve() " << std::endl;
232 if (me == 0) std::cout <<
"Done solve() " << std::endl;
234 catch (std::runtime_error &e) {
236 std::cout <<
"Runtime exception returned from solve(): " << e.what();
237 if (!strncmp(e.what(),
"BUILD ERROR", 11)) {
239 std::cout <<
" PASS" << std::endl;
244 std::cout <<
" FAIL" << std::endl;
248 catch (std::logic_error &e) {
250 std::cout <<
"Logic exception returned from solve(): " << e.what()
251 <<
" FAIL" << std::endl;
254 catch (std::bad_alloc &e) {
256 std::cout <<
"Bad_alloc exception returned from solve(): " << e.what()
257 <<
" FAIL" << std::endl;
260 catch (std::exception &e) {
262 std::cout <<
"Unknown exception returned from solve(). " << e.what()
263 <<
" FAIL" << std::endl;
269 size_t checkNparts = comm->getSize();
271 size_t checkLength = origMatrix->getLocalNumRows();
275 size_t *countPerPart =
new size_t[checkNparts];
276 size_t *globalCountPerPart =
new size_t[checkNparts];
279 for (
size_t i = 0; i < checkNparts; i++) countPerPart[i] = 0;
280 for (
size_t i = 0; i < checkNparts * nVwgts; i++) wtPerPart[i] = 0.;
282 for (
size_t i = 0; i < checkLength; i++) {
283 if (
size_t(checkParts[i]) >= checkNparts)
284 std::cout <<
"Invalid Part " << checkParts[i] <<
": FAIL" << std::endl;
285 countPerPart[checkParts[i]]++;
286 for (
int j = 0; j < nVwgts; j++) {
288 wtPerPart[checkParts[i]*nVwgts+j] += vwgts[i*nVwgts+j];
290 wtPerPart[checkParts[i]*nVwgts+j] += origMatrix->getNumEntriesInLocalRow(i);
293 Teuchos::reduceAll<int, size_t>(*comm, Teuchos::REDUCE_SUM, checkNparts,
294 countPerPart, globalCountPerPart);
295 Teuchos::reduceAll<int, zscalar_t>(*comm, Teuchos::REDUCE_SUM,
297 wtPerPart, globalWtPerPart);
299 size_t min = std::numeric_limits<std::size_t>::max();
302 size_t minrank = 0, maxrank = 0;
303 for (
size_t i = 0; i < checkNparts; i++) {
304 if (globalCountPerPart[i] < min) {min = globalCountPerPart[i]; minrank = i;}
305 if (globalCountPerPart[i] > max) {max = globalCountPerPart[i]; maxrank = i;}
306 sum += globalCountPerPart[i];
310 float avg = (float) sum / (
float) checkNparts;
311 std::cout <<
"Minimum count: " << min <<
" on rank " << minrank << std::endl;
312 std::cout <<
"Maximum count: " << max <<
" on rank " << maxrank << std::endl;
313 std::cout <<
"Average count: " << avg << std::endl;
314 std::cout <<
"Total count: " << sum
315 << (sum != origMatrix->getGlobalNumRows()
316 ?
"Work was lost; FAIL"
319 std::cout <<
"Imbalance: " << max / avg << std::endl;
321 std::vector<zscalar_t> minwt(nVwgts, std::numeric_limits<zscalar_t>::max());
322 std::vector<zscalar_t> maxwt(nVwgts, 0.);
323 std::vector<zscalar_t> sumwt(nVwgts, 0.);
324 for (
size_t i = 0; i < checkNparts; i++) {
325 for (
int j = 0; j < nVwgts; j++) {
326 size_t idx = i*nVwgts+j;
327 if (globalWtPerPart[idx] < minwt[j]) minwt[j] = globalWtPerPart[idx];
328 if (globalWtPerPart[idx] > maxwt[j]) maxwt[j] = globalWtPerPart[idx];
329 sumwt[j] += globalWtPerPart[idx];
332 for (
int j = 0; j < nVwgts; j++) {
333 float avgwt = (float) sumwt[j] / (
float) checkNparts;
334 std::cout << std::endl;
335 std::cout <<
"Minimum weight[" << j <<
"]: " << minwt[j] << std::endl;
336 std::cout <<
"Maximum weight[" << j <<
"]: " << maxwt[j] << std::endl;
337 std::cout <<
"Average weight[" << j <<
"]: " << avgwt << std::endl;
338 std::cout <<
"Imbalance: " << maxwt[j] / avgwt << std::endl;
343 delete [] countPerPart;
345 delete [] globalCountPerPart;
346 delete [] globalWtPerPart;
350 if (me == 0) std::cout <<
"Redistributing matrix..." << std::endl;
354 problem.getSolution());
355 if (redistribMatrix->getGlobalNumRows() < 40) {
356 Teuchos::FancyOStream out(Teuchos::rcp(&std::cout,
false));
357 redistribMatrix->describe(out, Teuchos::VERB_EXTREME);
360 if (me == 0) std::cout <<
"Redistributing vectors..." << std::endl;
364 problem.getSolution());
366 RCP<VectorT> redistribProd;
367 redistribProd = Tpetra::createVector<z2TestScalar,z2TestLO,z2TestGO>(
368 redistribMatrix->getRangeMap());
372 RCP<IntVector> origIntVec;
374 origIntVec = Tpetra::createVector<int,z2TestLO,z2TestGO>(
375 origMatrix->getRangeMap());
376 for (
size_t i = 0; i < origIntVec->getLocalLength(); i++)
377 origIntVec->replaceLocalValue(i, me);
381 problem.getSolution());
382 int origIntNorm = origIntVec->norm1();
383 int redistIntNorm = redistIntVec->norm1();
384 if (me == 0) std::cout <<
"IntegerVectorTest: " << origIntNorm <<
" == "
385 << redistIntNorm <<
" ?";
386 if (origIntNorm != redistIntNorm) {
387 if (me == 0) std::cout <<
" FAIL" << std::endl;
390 else if (me == 0) std::cout <<
" OK" << std::endl;
396 if (me == 0) std::cout <<
"Matvec original..." << std::endl;
397 origMatrix->apply(*origVector, *origProd);
400 std::cout <<
"Norm of Original matvec prod: " << origNorm << std::endl;
402 if (me == 0) std::cout <<
"Matvec redistributed..." << std::endl;
403 redistribMatrix->apply(*redistribVector, *redistribProd);
406 std::cout <<
"Norm of Redistributed matvec prod: " << redistribNorm << std::endl;
408 if (redistribNorm > origNorm+
epsilon || redistribNorm < origNorm-
epsilon) {
413 delete redistribVector;
414 delete redistribMatrix;
418 std::cout <<
"Mat-Vec product changed; FAIL" << std::endl;
422 std::cout <<
"PASS" << std::endl;
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
Tpetra::CrsMatrix< z2TestScalar, z2TestLO, z2TestGO > SparseMatrix
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Zoltan2::XpetraCrsGraphAdapter< SparseGraph > SparseGraphAdapter
int main(int narg, char **arg)
common code used by tests
typename InputTraits< User >::part_t part_t
Defines the XpetraMultiVectorAdapter.
Defines XpetraCrsGraphAdapter class.
Defines the XpetraCrsMatrixAdapter class.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
An adapter for Xpetra::MultiVector.
Tpetra::Map::local_ordinal_type zlno_t
Zoltan2::XpetraMultiVectorAdapter< IntVector > IntVectorAdapter
Tpetra::CrsGraph< z2TestLO, z2TestGO > SparseGraph
Zoltan2::XpetraCrsMatrixAdapter< SparseMatrix > SparseMatrixAdapter
Tpetra::Vector< int, z2TestLO, z2TestGO > IntVector
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
Zoltan2::XpetraMultiVectorAdapter< Vector > MultiVectorAdapter
Tpetra::Map::global_ordinal_type zgno_t
Tpetra::Vector< z2TestScalar, z2TestLO, z2TestGO > VectorT
void solve(bool updateInputData=true)
Direct the problem to create a solution.
std::string testDataFilePath(".")