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(".")