47 #include <Zoltan2_PartitioningProblem.hpp>
48 #include <Zoltan2_XpetraCrsMatrixAdapter.hpp>
49 #include <Zoltan2_XpetraMultiVectorAdapter.hpp>
50 #include <Teuchos_ParameterList.hpp>
51 #include <Teuchos_RCP.hpp>
52 #include <Teuchos_CommandLineProcessor.hpp>
53 #include <Tpetra_CrsMatrix.hpp>
54 #include <Tpetra_Vector.hpp>
55 #include <Galeri_XpetraMaps.hpp>
56 #include <Galeri_XpetraProblemFactory.hpp>
65 int main(
int narg,
char** arg)
68 Tpetra::ScopeGuard tscope(&narg, &arg);
69 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
70 int me = comm->getRank();
74 typedef Tpetra::Map<> Map_t;
75 typedef Map_t::local_ordinal_type localId_t;
76 typedef Map_t::global_ordinal_type globalId_t;
77 typedef Tpetra::Details::DefaultTypes::scalar_type scalar_t;
78 typedef Tpetra::CrsMatrix<scalar_t, localId_t, globalId_t> Matrix_t;
79 typedef Tpetra::MultiVector<scalar_t, localId_t, globalId_t> MultiVector_t;
80 typedef Tpetra::Vector<scalar_t, localId_t, globalId_t> Vector_t;
83 typedef Zoltan2::XpetraCrsMatrixAdapter<Matrix_t> MatrixAdapter_t;
84 typedef Zoltan2::XpetraMultiVectorAdapter<Vector_t> MultiVectorAdapter_t;
87 std::string method =
"scotch";
88 globalId_t nx = 50, ny = 40, nz = 30;
92 Teuchos::CommandLineProcessor cmdp (
false,
false);
93 cmdp.setOption(
"method", &method,
94 "Partitioning method to use: scotch or parmetis.");
95 cmdp.setOption(
"nx", &nx,
96 "number of gridpoints in X dimension for "
97 "mesh used to generate matrix; must be >= 1.");
98 cmdp.setOption(
"ny", &ny,
99 "number of gridpoints in Y dimension for "
100 "mesh used to generate matrix; must be >= 1.");
101 cmdp.setOption(
"nz", &nz,
102 "number of gridpoints in Z dimension for "
103 "mesh used to generate matrix; must be >= 1.");
104 cmdp.parse(narg, arg);
106 if ((nx < 1) || (ny < 1) || (nz < 1)) {
107 std::cout <<
"Input error: nx, ny and nz must be >= 1" << std::endl;
115 Teuchos::ParameterList galeriList;
116 galeriList.set(
"nx", nx);
117 galeriList.set(
"ny", ny);
118 galeriList.set(
"nz", nz);
119 Tpetra::global_size_t nGlobalElements = nx * ny * nz;
121 RCP<Matrix_t> origMatrix;
124 RCP<const Map_t> map = rcp(
new Map_t(nGlobalElements, 0, comm));
126 typedef Galeri::Xpetra::Problem<Map_t,Matrix_t,MultiVector_t> Galeri_t;
127 RCP<Galeri_t> galeriProblem =
128 Galeri::Xpetra::BuildProblem<scalar_t, localId_t, globalId_t,
129 Map_t, Matrix_t, MultiVector_t>
130 (
"Laplace3D", map, galeriList);
131 origMatrix = galeriProblem->BuildMatrix();
133 catch (std::exception &e) {
134 std::cout <<
"Exception in Galeri matrix generation. " << e.what() << std::endl;
139 std::cout <<
"NumRows = " << origMatrix->getGlobalNumRows() << std::endl
140 <<
"NumNonzeros = " << origMatrix->getGlobalNumEntries() << std::endl
141 <<
"NumProcs = " << comm->getSize() << std::endl;
144 RCP<Vector_t> origVector, origProd;
145 origProd = Tpetra::createVector<scalar_t,localId_t,globalId_t>(
146 origMatrix->getRangeMap());
147 origVector = Tpetra::createVector<scalar_t,localId_t,globalId_t>(
148 origMatrix->getDomainMap());
149 origVector->randomize();
152 Teuchos::ParameterList param;
153 param.set(
"partitioning_approach",
"partition");
154 param.set(
"algorithm", method);
157 MatrixAdapter_t adapter(origMatrix);
160 Zoltan2::PartitioningProblem<MatrixAdapter_t> problem(&adapter, ¶m);
165 catch (std::exception &e) {
166 std::cout <<
"Exception returned from solve(). " << e.what() << std::endl;
173 if (me == 0) std::cout <<
"Redistributing matrix..." << std::endl;
174 RCP<Matrix_t> redistribMatrix;
175 adapter.applyPartitioningSolution(*origMatrix, redistribMatrix,
176 problem.getSolution());
178 if (me == 0) std::cout <<
"Redistributing vectors..." << std::endl;
179 RCP<Vector_t> redistribVector;
180 MultiVectorAdapter_t adapterVector(origVector);
181 adapterVector.applyPartitioningSolution(*origVector, redistribVector,
182 problem.getSolution());
185 RCP<Vector_t> redistribProd;
186 redistribProd = Tpetra::createVector<scalar_t,localId_t,globalId_t>(
187 redistribMatrix->getRangeMap());
191 if (origMatrix->getGlobalNumRows() <= 50) {
192 std::cout << me <<
" ORIGINAL: ";
193 for (
size_t i = 0; i < origVector->getLocalLength(); i++)
194 std::cout << origVector->getMap()->getGlobalElement(i) <<
" ";
195 std::cout << std::endl;
196 std::cout << me <<
" REDISTRIB: ";
197 for (
size_t i = 0; i < redistribVector->getLocalLength(); i++)
198 std::cout << redistribVector->getMap()->getGlobalElement(i) <<
" ";
199 std::cout << std::endl;
206 if (me == 0) std::cout <<
"Matvec original..." << std::endl;
207 origMatrix->apply(*origVector, *origProd);
208 scalar_t origNorm = origProd->norm2();
210 std::cout <<
"Norm of Original matvec prod: " << origNorm << std::endl;
212 if (me == 0) std::cout <<
"Matvec redistributed..." << std::endl;
213 redistribMatrix->apply(*redistribVector, *redistribProd);
214 scalar_t redistribNorm = redistribProd->norm2();
216 std::cout <<
"Norm of Redistributed matvec prod: " << redistribNorm << std::endl;
219 const scalar_t epsilon = 0.001;
220 if (redistribNorm > origNorm+epsilon || redistribNorm < origNorm-epsilon)
221 std::cout <<
"Mat-Vec product changed; FAIL" << std::endl;
223 std::cout <<
"PASS" << std::endl;
int main(int argc, char *argv[])