Zoltan2
Loading...
Searching...
No Matches
Bug9500.cpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Zoltan2: A package of combinatorial algorithms for scientific computing
4//
5// Copyright 2012 NTESS and the Zoltan2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Tpetra_Core.hpp"
11#include "Kokkos_Random.hpp"
14
15// Class to test the Colorer utility
17public:
18 using map_t = Tpetra::Map<>;
19 using gno_t = typename map_t::global_ordinal_type;
20 using graph_t = Tpetra::CrsGraph<>;
21 using matrix_t = Tpetra::CrsMatrix<zscalar_t>;
22 using multivector_t = Tpetra::MultiVector<zscalar_t>;
23 using execution_space_t = typename matrix_t::device_type::execution_space;
24
26 // Construct the test:
27
28 ColorerTest(const Teuchos::RCP<const Teuchos::Comm<int> > &comm, int multiple)
29 {
30 int me = comm->getRank();
31 int np = comm->getSize();
32
33 // Create non-symmetrix matrix with non-contiguous row map -- only even GIDs
34 size_t myNrows = 4;
35 Teuchos::Array<gno_t> myRows(myNrows);
36 for (size_t i = 0; i < myNrows; i++) {
37 myRows[i] = multiple * (me * myNrows + i);
38 }
39
40 Tpetra::global_size_t dummy =
41 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
42 Teuchos::RCP<const map_t> map = rcp(new map_t(dummy, myRows, 0, comm));
43
44 size_t nnz = 2;
45 JBlock = rcp(new matrix_t(map, nnz));
46 Teuchos::Array<gno_t> myCols(nnz);
47 Teuchos::Array<zscalar_t> myVals(nnz);
48
49 for (size_t i = 0; i < myNrows; i++) {
50 auto gid = map->getGlobalElement(i);
51 size_t cnt = 0;
52 myCols[cnt++] = gid;
53 if (gid+multiple <= map->getMaxAllGlobalIndex())
54 myCols[cnt++] = gid+multiple;
55 JBlock->insertGlobalValues(gid, myCols(0,cnt), myVals(0, cnt));
56 }
57 JBlock->fillComplete();
58
59 // Fill JBlock with random numbers for a better test.
60#if KOKKOS_VERSION >= 40799
61 using IST = typename KokkosKernels::ArithTraits<zscalar_t>::val_type;
62#else
63 using IST = typename Kokkos::ArithTraits<zscalar_t>::val_type;
64#endif
65 using pool_type =
66 Kokkos::Random_XorShift64_Pool<execution_space_t>;
67 pool_type rand_pool(static_cast<uint64_t>(me));
68
69 Kokkos::fill_random(JBlock->getLocalMatrixDevice().values, rand_pool,
70 static_cast<IST>(1.), static_cast<IST>(9999.));
71
72 Teuchos::FancyOStream foo(Teuchos::rcp(&std::cout,false));
73 JBlock->describe(foo, Teuchos::VERB_EXTREME);
74
75 // Build same matrix with cyclic domain and range maps
76 // To make range and domain maps differ for square matrices,
77 // keep some processors empty in the cyclic maps
78
79 size_t nIndices = std::max(JBlock->getGlobalNumCols(),
80 JBlock->getGlobalNumRows());
81 Teuchos::Array<gno_t> indices(nIndices);
82
83 Teuchos::RCP<const map_t> vMapCyclic =
84 getCyclicMap(JBlock->getGlobalNumCols(), indices, np-1,
85 multiple, comm);
86 Teuchos::RCP<const map_t> wMapCyclic =
87 getCyclicMap(JBlock->getGlobalNumRows(), indices, np-2,
88 multiple, comm);
89
90 // Make JCyclic: same matrix with different Domain and Range maps
91 RCP<const graph_t> block_graph = JBlock->getCrsGraph();
92 RCP<graph_t> cyclic_graph = rcp(new graph_t(*block_graph));
93 cyclic_graph->resumeFill();
94 cyclic_graph->fillComplete(vMapCyclic, wMapCyclic);
95 JCyclic = rcp(new matrix_t(cyclic_graph));
96 JCyclic->resumeFill();
97 TEUCHOS_ASSERT(block_graph->getLocalNumRows() ==
98 cyclic_graph->getLocalNumRows());
99 {
100 auto val_s = JBlock->getLocalMatrixHost().values;
101 auto val_d = JCyclic->getLocalMatrixHost().values;
102 TEUCHOS_ASSERT(val_s.extent(0) == val_d.extent(0));
103 Kokkos::deep_copy(val_d, val_s);
104 }
105 JCyclic->fillComplete();
106 JCyclic->describe(foo, Teuchos::VERB_EXTREME);
107 }
108
110 bool run(const char* testname, Teuchos::ParameterList &params) {
111
112 bool ok = true;
113
114 params.set("symmetric", false);
115
116 // test with default maps
117 ok = buildAndCheckSeedMatrix(testname, params, true);
118
119 // test with cyclic maps
120 ok &= buildAndCheckSeedMatrix(testname, params, false);
121
122 return ok;
123 }
124
127 const char *testname,
128 Teuchos::ParameterList &params,
129 const bool useBlock
130 )
131 {
132 int ierr = 0;
133
134 // Pick matrix depending on useBlock flag
135 Teuchos::RCP<matrix_t> J = (useBlock ? JBlock : JCyclic);
136 int me = J->getRowMap()->getComm()->getRank();
137
138 std::cout << "Running " << testname << " with "
139 << (useBlock ? "Block maps" : "Cyclic maps")
140 << std::endl;
141
142 // Create a colorer
144 colorer.computeColoring(params);
145
146 // Check coloring
147 if (!colorer.checkColoring()) {
148 std::cout << testname << " with "
149 << (useBlock ? "Block maps" : "Cyclic maps")
150 << " FAILED: invalid coloring returned"
151 << std::endl;
152 return false;
153 }
154
155 // Compute seed matrix V -- the application wants this matrix
156 // Dense matrix of 0/1 indicating the compression via coloring
157
158 const int numColors = colorer.getNumColors();
159
160 // Compute the seed matrix; applications want this seed matrix
161
162 multivector_t V(J->getDomainMap(), numColors);
163 colorer.computeSeedMatrix(V);
164
165 // To test the result...
166 // Compute the compressed matrix W
167 multivector_t W(J->getRangeMap(), numColors);
168
169 J->apply(V, W);
170
171 // Reconstruct matrix from compression vector
172 Teuchos::RCP<matrix_t> Jp = rcp(new matrix_t(*J, Teuchos::Copy));
173 Jp->setAllToScalar(static_cast<zscalar_t>(-1.));
174
175 colorer.reconstructMatrix(W, *Jp);
176
177 // Check that values of J = values of Jp
178 auto J_local_matrix = J->getLocalMatrixDevice();
179 auto Jp_local_matrix = Jp->getLocalMatrixDevice();
180 const size_t num_local_nz = J->getLocalNumEntries();
181
182 Kokkos::parallel_reduce(
183 "TpetraCrsColorer::testReconstructedMatrix()",
184 Kokkos::RangePolicy<execution_space_t>(0, num_local_nz),
185 KOKKOS_LAMBDA(const size_t nz, int &errorcnt) {
186 if (J_local_matrix.values(nz) != Jp_local_matrix.values(nz)) {
187 Kokkos::printf("Error in nonzero comparison %zu: %g != %g",
188 nz, J_local_matrix.values(nz), Jp_local_matrix.values(nz));
189 errorcnt++;
190 }
191 },
192 ierr);
193
194
195 if (ierr > 0) {
196 std::cout << testname << " FAILED on rank " << me << " with "
197 << (useBlock ? "Block maps" : "Cyclic maps")
198 << std::endl;
199 params.print();
200 }
201
202 return (ierr == 0);
203 }
204
205private:
206
208 // Return a map that is cyclic (like dealing rows to processors)
209 Teuchos::RCP<const map_t> getCyclicMap(
210 size_t nIndices,
211 Teuchos::Array<gno_t> &indices,
212 int mapNumProc,
213 int multiple,
214 const Teuchos::RCP<const Teuchos::Comm<int> > &comm)
215 {
216 size_t cnt = 0;
217 int me = comm->getRank();
218 int np = comm->getSize();
219 if (mapNumProc > np) mapNumProc = np; // corner case: bad input
220 if (mapNumProc <= 0) mapNumProc = 1; // corner case: np is too small
221
222 for (size_t i = 0; i < nIndices; i++)
223 if (me == int(i % np)) indices[cnt++] = multiple*i;
224
225 Tpetra::global_size_t dummy =
226 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
227
228 return rcp(new map_t(dummy, indices(0,cnt), 0, comm));
229 }
230
232 // Input matrix -- built in Constructor
233 bool symmetric; // User can specify whether matrix is symmetric
234 Teuchos::RCP<matrix_t> JBlock; // has Trilinos default domain and range maps
235 Teuchos::RCP<matrix_t> JCyclic; // has cyclic domain and range maps
236};
237
238
240int doTheTest(const Teuchos::RCP<const Teuchos::Comm<int> > &comm, int multiple)
241{
242 bool ok = true;
243 int ierr = 0;
244
245 ColorerTest testColorer(comm, multiple);
246
247 // Set parameters and compute coloring
248 {
249 Teuchos::ParameterList coloring_params;
250 std::string matrixType = "Jacobian";
251 bool symmetrize = true; // Zoltan's TRANSPOSE symmetrization, if needed
252
253 coloring_params.set("MatrixType", matrixType);
254 coloring_params.set("symmetrize", symmetrize);
255
256 ok = testColorer.run("Test One", coloring_params);
257 if (!ok) ierr++;
258 }
259
260 {
261 Teuchos::ParameterList coloring_params;
262 std::string matrixType = "Jacobian";
263 bool symmetrize = false; // colorer's BIPARTITE symmetrization, if needed
264
265 coloring_params.set("MatrixType", matrixType);
266 coloring_params.set("symmetrize", symmetrize);
267
268 ok = testColorer.run("Test Two", coloring_params);
269 if (!ok) ierr++;
270 }
271
272 {
273 Teuchos::ParameterList coloring_params;
274 std::string matrixType = "Jacobian";
275
276 coloring_params.set("MatrixType", matrixType);
277
278 ok = testColorer.run("Test Three", coloring_params);
279 if (!ok) ierr++;
280 }
281 return ierr;
282}
283
285int main(int narg, char **arg)
286{
287 Tpetra::ScopeGuard scope(&narg, &arg);
288 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
289 int ierr = 0;
290
291 ierr += doTheTest(comm, 1); // Contiguous row map
292 ierr += doTheTest(comm, 2); // Non-contiguous row map --
293 // only even-numbered indices
294 ierr += doTheTest(comm, 5); // Indices spaced wider than rows/proc
295
296 int gerr;
297 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_SUM, 1, &ierr, &gerr);
298 if (comm->getRank() == 0) {
299 if (gerr == 0)
300 std::cout << "TEST PASSED" << std::endl;
301 else
302 std::cout << "TEST FAILED" << std::endl;
303 }
304}
int doTheTest(const Teuchos::RCP< const Teuchos::Comm< int > > &comm, int multiple)
Definition Bug9500.cpp:240
common code used by tests
float zscalar_t
int main()
ColorerTest(const Teuchos::RCP< const Teuchos::Comm< int > > &comm, int multiple)
Definition Bug9500.cpp:28
bool run(const char *testname, Teuchos::ParameterList &params)
Definition Bug9500.cpp:110
Tpetra::CrsMatrix< zscalar_t > matrix_t
Definition Bug9500.cpp:21
typename map_t::global_ordinal_type gno_t
Definition Bug9500.cpp:19
bool buildAndCheckSeedMatrix(const char *testname, Teuchos::ParameterList &params, const bool useBlock)
Definition Bug9500.cpp:126
Tpetra::MultiVector< zscalar_t > multivector_t
Definition Bug9500.cpp:22
typename matrix_t::device_type::execution_space execution_space_t
Definition Bug9500.cpp:23
Tpetra::CrsGraph<> graph_t
Definition Bug9500.cpp:20
Tpetra::Map<> map_t
Definition Bug9500.cpp:18