Zoltan2
Loading...
Searching...
No Matches
TpetraCrsColorer.cpp
Go to the documentation of this file.
1
2#include "Tpetra_Core.hpp"
3#include "Kokkos_Random.hpp"
6
7// Class to test the Colorer utility
8class ColorerTest {
9public:
10 using map_t = Tpetra::Map<>;
11 using gno_t = typename map_t::global_ordinal_type;
12 using graph_t = Tpetra::CrsGraph<>;
13 using matrix_t = Tpetra::CrsMatrix<zscalar_t>;
14 using multivector_t = Tpetra::MultiVector<zscalar_t>;
15 using execution_space_t = typename matrix_t::device_type::execution_space;
16
18 // Construct the test:
19 // Read or generate a matrix (JBlock) with default range and domain maps
20 // Construct identical matrix (JCyclic) with cyclic range and domain maps
21
22 ColorerTest(Teuchos::RCP<const Teuchos::Comm<int> > &comm,
23 int narg, char**arg)
24 : symmetric(false)
25 {
26 int me = comm->getRank();
27 int np = comm->getSize();
28
29 // Process command line arguments
30 bool distributeInput = true;
31 size_t xdim = 10, ydim = 11, zdim = 12;
32
33 Teuchos::CommandLineProcessor cmdp(false, false);
34 cmdp.setOption("file", &matrixFileName,
35 "Name of the Matrix Market file to use");
36 cmdp.setOption("xdim", &xdim,
37 "Number of nodes in x-direction for generated matrix");
38 cmdp.setOption("ydim", &ydim,
39 "Number of nodes in y-direction for generated matrix");
40 cmdp.setOption("zdim", &zdim,
41 "Number of nodes in z-direction for generated matrix");
42 cmdp.setOption("distribute", "no-distribute", &distributeInput,
43 "Should Zoltan2 distribute the matrix as it is read?");
44 cmdp.setOption("symmetric", "non-symmetric", &symmetric,
45 "Is the matrix symmetric?");
46 cmdp.parse(narg, arg);
47
48 // Get and store a matrix
49 if (matrixFileName != "") {
50 // Read from a file
51 UserInputForTests uinput(".", matrixFileName, comm, true, distributeInput);
52 JBlock = uinput.getUITpetraCrsMatrix();
53 }
54 else {
55 // Generate a matrix
56 UserInputForTests uinput(xdim, ydim, zdim, string("Laplace3D"), comm,
57 true, distributeInput);
58 JBlock = uinput.getUITpetraCrsMatrix();
59 }
60
61 // Build same matrix with cyclic domain and range maps
62 // To make range and domain maps differ for square matrices,
63 // keep some processors empty in the cyclic maps
64
65 size_t nIndices = std::max(JBlock->getGlobalNumCols(),
66 JBlock->getGlobalNumRows());
67 Teuchos::Array<gno_t> indices(nIndices);
68
69 Teuchos::RCP<const map_t> vMapCyclic =
70 getCyclicMap(JBlock->getGlobalNumCols(), indices, np-1, comm);
71 Teuchos::RCP<const map_t> wMapCyclic =
72 getCyclicMap(JBlock->getGlobalNumRows(), indices, np-2, comm);
73
74 // Fill JBlock with random numbers for a better test.
75 JBlock->resumeFill();
76
77 using IST = typename Kokkos::ArithTraits<zscalar_t>::val_type;
78 using pool_type =
79 Kokkos::Random_XorShift64_Pool<execution_space_t>;
80 pool_type rand_pool(static_cast<uint64_t>(me));
81
82 Kokkos::fill_random(JBlock->getLocalMatrixDevice().values, rand_pool,
83 static_cast<IST>(1.), static_cast<IST>(9999.));
84 JBlock->fillComplete();
85
86
87 // Make JCyclic: same matrix with different Domain and Range maps
88 RCP<const graph_t> block_graph = JBlock->getCrsGraph();
89 RCP<graph_t> cyclic_graph = rcp(new graph_t(*block_graph));
90 cyclic_graph->resumeFill();
91 cyclic_graph->fillComplete(vMapCyclic, wMapCyclic);
92 JCyclic = rcp(new matrix_t(cyclic_graph));
93 JCyclic->resumeFill();
94 TEUCHOS_ASSERT(block_graph->getLocalNumRows() == cyclic_graph->getLocalNumRows());
95 {
96 auto val_s = JBlock->getLocalMatrixHost().values;
97 auto val_d = JCyclic->getLocalMatrixHost().values;
98 TEUCHOS_ASSERT(val_s.extent(0) == val_d.extent(0));
99 Kokkos::deep_copy(val_d, val_s);
100 }
101 JCyclic->fillComplete();
102 }
103
105 bool run(const char *testname, Teuchos::ParameterList &params) {
106
107 bool ok = true;
108
109 params.set("symmetric", symmetric);
110 params.set("library", "zoltan");
111
112 // test with default maps
113 ok = buildAndCheckSeedMatrix(testname, params, true);
114
115 // test with cyclic maps
116 ok &= buildAndCheckSeedMatrix(testname, params, false);
117 // if (matrixFileName != "west0067") {
118
119 params.set("library", "zoltan2");
120 // test with default maps
121 ok = buildAndCheckSeedMatrix(testname, params, true);
122
123 // test with cyclic maps
124 ok &= buildAndCheckSeedMatrix(testname, params, false);
125 // }
126
127 return ok;
128 }
129
132 const char *testname,
133 Teuchos::ParameterList &params,
134 const bool useBlock
135 )
136 {
137 int ierr = 0;
138
139 // Pick matrix depending on useBlock flag
140 Teuchos::RCP<matrix_t> J = (useBlock ? JBlock : JCyclic);
141 int me = J->getRowMap()->getComm()->getRank();
142
143 std::cout << params.get("library", "zoltan2") << " Running " << testname << " with "
144 << (useBlock ? "Block maps" : "Cyclic maps")
145 << std::endl;
146
147 // Create a colorer
149 colorer.computeColoring(params);
150
151 // Check coloring
152 if (!colorer.checkColoring()) {
153 std::cout << testname << " with "
154 << (useBlock ? "Block maps" : "Cyclic maps")
155 << " FAILED: invalid coloring returned"
156 << std::endl;
157 return false;
158 }
159
160 // Compute seed matrix V -- the application wants this matrix
161 // Dense matrix of 0/1 indicating the compression via coloring
162
163 const int numColors = colorer.getNumColors();
164
165 // Compute the seed matrix; applications want this seed matrix
166
167 multivector_t V(J->getDomainMap(), numColors);
168 colorer.computeSeedMatrix(V);
169
170 // To test the result...
171 // Compute the compressed matrix W
172 multivector_t W(J->getRangeMap(), numColors);
173
174 J->apply(V, W);
175
176 // Reconstruct matrix from compression vector
177 Teuchos::RCP<matrix_t> Jp = rcp(new matrix_t(*J, Teuchos::Copy));
178 Jp->setAllToScalar(static_cast<zscalar_t>(-1.));
179
180 colorer.reconstructMatrix(W, *Jp);
181
182 // Check that values of J = values of Jp
183 auto J_local_matrix = J->getLocalMatrixDevice();
184 auto Jp_local_matrix = Jp->getLocalMatrixDevice();
185 const size_t num_local_nz = J->getLocalNumEntries();
186
187 Kokkos::parallel_reduce(
188 "TpetraCrsColorer::testReconstructedMatrix()",
189 Kokkos::RangePolicy<execution_space_t>(0, num_local_nz),
190 KOKKOS_LAMBDA(const size_t nz, int &errorcnt) {
191 if (J_local_matrix.values(nz) != Jp_local_matrix.values(nz)) {
192 printf("Error in nonzero comparison %zu: %g != %g",
193 nz, J_local_matrix.values(nz), Jp_local_matrix.values(nz));
194 errorcnt++;
195 }
196 },
197 ierr);
198
199
200 if (ierr > 0) {
201 std::cout << testname << " FAILED on rank " << me << " with "
202 << (useBlock ? "Block maps" : "Cyclic maps")
203 << std::endl;
204 params.print();
205 }
206
207 return (ierr == 0);
208 }
209
210private:
211
213 // Return a map that is cyclic (like dealing rows to processors)
214 Teuchos::RCP<const map_t> getCyclicMap(
215 size_t nIndices,
216 Teuchos::Array<gno_t> &indices,
217 int mapNumProc,
218 const Teuchos::RCP<const Teuchos::Comm<int> > &comm)
219 {
220 size_t cnt = 0;
221 int me = comm->getRank();
222 int np = comm->getSize();
223 if (mapNumProc > np) mapNumProc = np; // corner case: bad input
224 if (mapNumProc <= 0) mapNumProc = 1; // corner case: np is too small
225
226 for (size_t i = 0; i < nIndices; i++)
227 if (me == int(i % np)) indices[cnt++] = i;
228
229 Tpetra::global_size_t dummy =
230 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
231
232 return rcp(new map_t(dummy, indices(0,cnt), 0, comm));
233 }
234
236 // Input matrix -- built in Constructor
237 bool symmetric; // User can specify whether matrix is symmetric
238 Teuchos::RCP<matrix_t> JBlock; // has Trilinos default domain and range maps
239 Teuchos::RCP<matrix_t> JCyclic; // has cyclic domain and range maps
240 std::string matrixFileName;
241};
242
243
245int main(int narg, char **arg)
246{
247 Tpetra::ScopeGuard scope(&narg, &arg);
248 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
249 bool ok = true;
250 int ierr = 0;
251
252 ColorerTest testColorer(comm, narg, arg);
253
254 // Set parameters and compute coloring
255 {
256 Teuchos::ParameterList coloring_params;
257 std::string matrixType = "Jacobian";
258 bool symmetrize = true; // Zoltan's TRANSPOSE symmetrization, if needed
259
260 coloring_params.set("MatrixType", matrixType);
261 coloring_params.set("symmetrize", symmetrize);
262
263 ok = testColorer.run("Test One", coloring_params);
264 if (!ok) ierr++;
265 }
266
267 {
268 Teuchos::ParameterList coloring_params;
269 std::string matrixType = "Jacobian";
270 bool symmetrize = false; // colorer's BIPARTITE symmetrization, if needed
271
272 coloring_params.set("MatrixType", matrixType);
273 coloring_params.set("symmetrize", symmetrize);
274
275 ok = testColorer.run("Test Two", coloring_params);
276 if (!ok) ierr++;
277 }
278
279 {
280 Teuchos::ParameterList coloring_params;
281 std::string matrixType = "Jacobian";
282
283 coloring_params.set("MatrixType", matrixType);
284
285 ok = testColorer.run("Test Three", coloring_params);
286 if (!ok) ierr++;
287 }
288
289 int gerr;
290 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_SUM, 1, &ierr, &gerr);
291 if (comm->getRank() == 0) {
292 if (gerr == 0)
293 std::cout << "TEST PASSED" << std::endl;
294 else
295 std::cout << "TEST FAILED" << std::endl;
296 }
297
298//Through cmake...
299//Test cases -- UserInputForTests can generate Galeri or read files:
300//- tri-diagonal matrix -- can check the number of colors
301//- galeri matrix
302//- read from file: symmetric matrix and non-symmetric matrix
303
304//Through code ...
305//Test with fitted and non-fitted maps
306//Call regular and fitted versions of functions
307
308//Through code ...
309//Test both with and without Symmetrize --
310//test both to exercise both sets of callbacks in Zoltan
311// --matrixType = Jacobian/Hessian
312// --symmetric, --no-symmetric
313// --symmetrize, --no-symmetrize
314
315//Through cmake
316//Test both with and without distributeInput
317// --distribute, --no-distribute
318
319}
common code used by tests
float zscalar_t
int main()
ColorerTest(Teuchos::RCP< const Teuchos::Comm< int > > &comm, int narg, char **arg)
bool run(const char *testname, Teuchos::ParameterList &params)
Tpetra::CrsMatrix< zscalar_t > matrix_t
Definition Bug9500.cpp:13
typename map_t::global_ordinal_type gno_t
Definition Bug9500.cpp:11
bool buildAndCheckSeedMatrix(const char *testname, Teuchos::ParameterList &params, const bool useBlock)
Definition Bug9500.cpp:114
Tpetra::MultiVector< zscalar_t > multivector_t
Definition Bug9500.cpp:14
typename matrix_t::device_type::execution_space execution_space_t
Definition Bug9500.cpp:15
Tpetra::CrsGraph<> graph_t
Definition Bug9500.cpp:12
Tpetra::Map<> map_t
Definition Bug9500.cpp:10
RCP< tcrsMatrix_t > getUITpetraCrsMatrix()