14 #include <Teuchos_RCP.hpp>
15 #include <Teuchos_ParameterList.hpp>
16 #include <Teuchos_CommandLineProcessor.hpp>
17 #include <Tpetra_CrsMatrix.hpp>
18 #include <Tpetra_Vector.hpp>
19 #include <MatrixMarket_Tpetra.hpp>
44 typedef Tpetra::CrsMatrix<z2TestScalar, z2TestLO, z2TestGO>
SparseMatrix;
45 typedef Tpetra::Vector<z2TestScalar, z2TestLO, z2TestGO>
Vector;
46 typedef Vector::node_type
Node;
48 typedef Tpetra::Import<z2TestLO, z2TestGO>
Import;
55 if (A->getRowMap()->getComm()->getRank() == 0)
56 std::cout <<
"validate coloring: local graph, distance-one" << std::endl;
58 typename tcrsMatrix_t::local_inds_host_view_type indices;
59 typename tcrsMatrix_t::values_host_view_type values;
62 zlno_t n = A->getLocalNumRows();
63 for (
zlno_t i=0; i<n; i++) {
64 A->getLocalRowView(i, indices, values);
65 for (
zlno_t j=0; j<static_cast<zlno_t>(indices.extent(0)); j++) {
66 if ((indices[j]<n) && (indices[j]!=i) && (color[i]==color[indices[j]])){
77 if (A->getRowMap()->getComm()->getRank() == 0)
78 std::cout <<
"validate coloring: distributed, distance-one" << std::endl;
80 RCP<const SparseMatrix::map_type> rowMap = A->getRowMap();
81 RCP<const SparseMatrix::map_type> colMap = A->getColMap();
84 for(
size_t i = 0; i < A->getLocalNumRows(); i++){
85 R.replaceLocalValue(i, color[i]);
90 C.doImport(R, imp, Tpetra::REPLACE);
92 typename tcrsMatrix_t::local_inds_host_view_type indices;
93 typename tcrsMatrix_t::values_host_view_type values;
97 size_t n = A->getLocalNumRows();
98 auto colorData = C.getData();
99 for(
size_t i = 0; i < n; i++){
100 A->getLocalRowView(i, indices, values);
101 for(
size_t j = 0; j < indices.extent(0); j++){
102 if(values[j] == 0)
continue;
103 if( (rowMap->getGlobalElement(i) != colMap->getGlobalElement(indices[j])) && (color[i] == colorData[indices[j]]) ){
114 if (A->getRowMap()->getComm()->getRank() == 0)
115 std::cout <<
"validate coloring: distributed, distance-two" << std::endl;
119 RCP<SparseMatrix> S = rcp(
new SparseMatrix(A->getRowMap(), 0));
120 Tpetra::MatrixMatrix::Multiply(*A,
true, *A,
false, *S);
130 for (
zlno_t i=0; i<n; i++) {
131 if (color[i] > maxColor) maxColor = color[i];
135 Teuchos::Array<int> colorCount(maxColor+1);
136 for (
zlno_t i=0; i<n; i++) {
137 colorCount[color[i]]++;
143 zlno_t small = colorCount[1];
144 zlno_t large = colorCount[1];
145 for (
int i=1; i<=maxColor; i++){
146 if (colorCount[i] < small){
147 small = colorCount[i];
150 if (colorCount[i] > large){
151 large = colorCount[i];
157 std::cout <<
"Largest color class = " << largest <<
" with " << colorCount[largest] <<
" vertices." << std::endl;
158 std::cout <<
"Smallest color class = " << smallest <<
" with " << colorCount[smallest] <<
" vertices." << std::endl;
166 std::string inputFile =
"";
167 std::string outputFile =
"";
168 std::string colorAlg =
"SerialGreedy";
169 bool verbose =
false;
172 bool recolorDegrees =
false;
173 std::string prepartition =
"";
175 bool prepartition_rows =
false;
176 bool prepartition_nonzeros =
false;
181 Tpetra::ScopeGuard tscope(&narg, &arg);
182 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
183 int me = comm->getRank();
184 int serialThreshold = 0;
186 Teuchos::CommandLineProcessor cmdp (
false,
false);
187 cmdp.setOption(
"colorMethod", &colorAlg,
188 "Coloring algorithms supported: SerialGreedy, D1, D1-2GL, D2, PD2");
189 cmdp.setOption(
"inputFile", &inputFile,
190 "Name of a Matrix Market file in the data directory; "
191 "if not specified, a matrix will be generated by Galeri.");
192 cmdp.setOption(
"outputFile", &outputFile,
193 "Name of file to write the coloring");
194 cmdp.setOption(
"verbose",
"quiet", &verbose,
195 "Print messages and results.");
196 cmdp.setOption(
"prepartition", &prepartition,
197 "Partition the input graph for better initial distribution;"
198 "valid values are rows and nonzeros");
199 cmdp.setOption(
"serialThreshold", &serialThreshold,
200 "number of vertices to recolor in serial");
201 cmdp.setOption(
"recolorDegrees",
"recolorRandom",&recolorDegrees,
202 "recolor based on vertex degrees or random numbers");
203 cmdp.setOption(
"timing",
"notimes", &timing,
204 "report how long coloring takes");
205 std::cout <<
"Starting everything" << std::endl;
216 std::string matrixType(
"Laplace3D");
218 cmdp.setOption(
"x", &xdim,
219 "number of gridpoints in X dimension for "
220 "mesh used to generate matrix.");
221 cmdp.setOption(
"y", &ydim,
222 "number of gridpoints in Y dimension for "
223 "mesh used to generate matrix.");
224 cmdp.setOption(
"z", &zdim,
225 "number of gridpoints in Z dimension for "
226 "mesh used to generate matrix.");
227 cmdp.setOption(
"matrix", &matrixType,
228 "Matrix type: Laplace1D, Laplace2D, or Laplace3D");
233 std::string colorMethod(
"FirstFit");
235 cmdp.setOption(
"color_choice", &colorMethod,
236 "Color choice method: FirstFit, LeastUsed, Random, RandomFast");
241 cmdp.parse(narg, arg);
243 if(prepartition !=
""){
244 if(prepartition ==
"rows") prepartition_rows =
true;
245 else if (prepartition ==
"nonzeros") prepartition_nonzeros =
true;
247 std::cout <<
"Invalid value of prepartition option " << prepartition
249 std::cout <<
"No prepartitioning will be done" <<std::endl;
253 RCP<UserInputForTests> uinput;
255 if (inputFile !=
""){
260 uinput = rcp(
new UserInputForTests(xdim, ydim, zdim, matrixType, comm,
true,
true));
262 RCP<SparseMatrix> Matrix = uinput->getUITpetraCrsMatrix();
265 std::cout <<
"NumRows = " << Matrix->getGlobalNumRows() << std::endl
266 <<
"NumNonzeros = " << Matrix->getGlobalNumEntries() << std::endl
267 <<
"NumProcs = " << comm->getSize() << std::endl;
268 if(prepartition_rows || prepartition_nonzeros){
269 std::cout<<comm->getRank() <<
": Starting to pre-partition, creating adapter\n";
271 std::unique_ptr<SparseMatrixAdapter> zadapter;
272 if(prepartition_nonzeros){
274 zadapter->setRowWeightIsNumberOfNonZeros(0);
279 std::cout<<comm->getRank()<<
": created adapter, creating PartitioningProblem\n";
280 Teuchos::ParameterList zparams;
281 zparams.set(
"algorithm",
"parmetis");
282 zparams.set(
"imbalance_tolerance", 1.05);
283 zparams.set(
"partitioning_approach",
"partition");
285 zproblem(zadapter.get(), &zparams);
286 std::cout<<comm->getRank()<<
": created PartitioningProblem, starting to solve\n";
288 std::cout<<comm->getRank()<<
": solved Partitioning Problem\n";
290 std::cout<<comm->getRank()<<
": applying partition\n";
292 quality_t evalbef(zadapter.get(), &zparams, comm, NULL);
294 std::cout<<
"BEFORE PREPARTITION: Partition statistics:" << std::endl;
295 evalbef.printMetrics(std::cout);
298 quality_t evalaft(zadapter.get(), &zparams, comm, &zproblem.getSolution());
300 std::cout<<
"AFTER PREPARTITION: Partition statistics:"<<std::endl;
301 evalaft.printMetrics(std::cout);
303 std::cout<<comm->getRank()<<
": done evaluating, migrating matrix to use new partitioning\n";
305 RCP<SparseMatrix> newMatrix;
306 zadapter->applyPartitioningSolution(*Matrix, newMatrix, zproblem.getSolution());
308 std::cout<<comm->getRank()<<
": done applying, replacing old matrix with new one\n";
310 std::cout<<comm->getRank()<<
": done replacing, finished partitioning\n";
313 Teuchos::ParameterList params;
314 params.set(
"color_choice", colorMethod);
315 params.set(
"color_method", colorAlg);
316 params.set(
"verbose", verbose);
317 params.set(
"timing", timing);
318 params.set(
"serial_threshold",serialThreshold);
319 params.set(
"recolor_degrees",recolorDegrees);
330 std::cout <<
"Going to color " << colorAlg << std::endl;
335 int *checkColoring =
nullptr;
339 std::cout <<
"Going to get results" << std::endl;
348 Teuchos::reduceAll<int,int>(*comm, Teuchos::REDUCE_MAX, 1, &localColors, &totalColors);
349 if (outputFile !=
"") {
350 std::ofstream colorFile;
355 std::stringstream
fname;
356 fname << outputFile <<
"." << comm->getSize() <<
"." << me;
357 colorFile.open(fname.str().c_str());
358 for (
size_t i=0; i<checkLength; i++){
359 colorFile <<
" " << checkColoring[i] << std::endl;
365 std::cout <<
"No. of colors on proc " << me <<
" : " << localColors << std::endl;
367 std::cout <<
"Going to validate the soln" << std::endl;
368 auto rowInds = Matrix->getRowMap()->getMyGlobalIndices();
369 Matrix->resumeFill();
378 std::cout<<
"Got row indices, replacing diagonals\n";
380 for(
size_t i = 0; i < rowInds.size(); i++){
381 typename Kokkos::View<zgno_t*>::HostMirror idx(
"idx",1);
382 typename Kokkos::View<zscalar_t*>::HostMirror val(
"val",1);
383 Kokkos::deep_copy(idx,rowInds[i]);
384 Kokkos::deep_copy(val, 0.);
386 size_t numEntries = Matrix->getNumEntriesInGlobalRow(rowInds[i]);
387 typename tcrsMatrix_t::nonconst_global_inds_host_view_type inds(
"Indices", numEntries);
388 typename tcrsMatrix_t::nonconst_values_host_view_type vals(
"Values", numEntries);
389 Matrix->getGlobalRowCopy(rowInds[i], inds, vals, numEntries);
391 bool hasDiagonal =
false;
392 for(
size_t j = 0; j < inds.extent(0); j++){
393 if(inds[j] == rowInds[i]) hasDiagonal =
true;
397 if(Matrix->replaceGlobalValues(rowInds[i],idx,val) == Teuchos::OrdinalTraits<zlno_t>::invalid()){
398 std::cout<<
"Either !isFillActive() or inds.extent != vals.extent()\n";
405 Matrix->fillComplete();
407 if(colorAlg ==
"D2"){
410 }
else if (colorAlg ==
"PD2"){
412 }
else if(colorAlg ==
"D1-2GL" || colorAlg ==
"D1"){
414 }
else if (checkLength > 0){
421 }
catch (std::exception &e){
422 std::cout <<
"Exception caught in coloring" << std::endl;
423 std::cout << e.what() << std::endl;
424 std::cout <<
"FAIL" << std::endl;
428 int numGlobalConflicts = 0;
429 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, 1, &testReturn, &numGlobalConflicts);
432 if (numGlobalConflicts > 0){
433 std::cout <<
"Number of conflicts found = "<<numGlobalConflicts<<std::endl;
434 std::cout <<
"Solution is not a valid coloring; FAIL" << std::endl;
436 std::cout <<
"Used " <<totalColors<<
" colors\n";
437 std::cout <<
"PASS" << std::endl;
int * getColors()
Get (local) color array by raw pointer (no RCP).
ColoringProblem sets up coloring problems for the user.
Defines the ColoringProblem class.
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
Tpetra::CrsMatrix< z2TestScalar, z2TestLO, z2TestGO > SparseMatrix
void solve(bool updateInputData=true)
Direct the problem to create a solution.
Tpetra::Import< z2TestLO, z2TestGO > Import
ColoringSolution< Adapter > * getSolution()
Get the solution to the problem.
int getNumColors()
Get local number of colors. This is computed from the coloring each time, as this is cheap...
Zoltan2::EvaluatePartition< matrixAdapter_t > quality_t
int main(int narg, char **arg)
common code used by tests
Tpetra::Vector< z2TestScalar, z2TestLO, z2TestGO > Vector
Defines the XpetraCrsMatrixAdapter class.
int validateColoring(RCP< SparseMatrix > A, int *color)
int validateDistributedColoring(RCP< SparseMatrix > A, int *color)
Tpetra::Map::local_ordinal_type zlno_t
PartitioningProblem sets up partitioning problems for the user.
int validateDistributedDistance2Coloring(RCP< SparseMatrix > A, int *color)
Zoltan2::XpetraCrsMatrixAdapter< SparseMatrix > SparseMatrixAdapter
A class that computes and returns quality metrics.
size_t getColorsSize()
Get (local) size of color array.
Tpetra::Map::global_ordinal_type zgno_t
void solve(bool updateInputData=true)
Direct the problem to create a solution.
The class containing coloring solution.
int checkBalance(zlno_t n, int *color)
std::string testDataFilePath(".")