Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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
8 class ColorerTest {
9 public:
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  Kokkos::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 
210 private:
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 
245 int 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 }
Tpetra::CrsMatrix< zscalar_t > matrix_t
Definition: Bug9500.cpp:13
typename matrix_t::device_type::execution_space execution_space_t
Definition: Bug9500.cpp:15
RCP< tcrsMatrix_t > getUITpetraCrsMatrix()
ColorerTest(Teuchos::RCP< const Teuchos::Comm< int > > &comm, int narg, char **arg)
int main(int narg, char **arg)
Definition: coloring1.cpp:199
common code used by tests
Tpetra::MultiVector< zscalar_t > multivector_t
Definition: Bug9500.cpp:14
bool run(const char *testname, Teuchos::ParameterList &params)
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::global_size_t global_size_t
Tpetra::CrsGraph<> graph_t
Definition: Bug9500.cpp:12
Tpetra::Map<> map_t
Definition: Bug9500.cpp:10