MueLu  Version of the Day
MueLu_CoalesceDropFactory_kokkos_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef MUELU_COALESCEDROPFACTORY_KOKKOS_DEF_HPP
47 #define MUELU_COALESCEDROPFACTORY_KOKKOS_DEF_HPP
48 
49 #include <Kokkos_CrsMatrix.hpp>
50 
52 
53 #include "MueLu_AmalgamationInfo.hpp"
54 #include "MueLu_Exceptions.hpp"
55 #include "MueLu_Level.hpp"
56 #include "MueLu_LWGraph_kokkos.hpp"
57 #include "MueLu_MasterList.hpp"
58 #include "MueLu_Monitor.hpp"
59 #include "MueLu_Utilities_kokkos.hpp"
60 
61 namespace MueLu {
62 
63  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
64  RCP<const ParameterList> CoalesceDropFactory_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetValidParameterList() const {
65  RCP<ParameterList> validParamList = rcp(new ParameterList());
66 
67 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
68  SET_VALID_ENTRY("aggregation: drop tol");
69  SET_VALID_ENTRY("aggregation: Dirichlet threshold");
70  SET_VALID_ENTRY("aggregation: drop scheme");
71  {
72  typedef Teuchos::StringToIntegralParameterEntryValidator<int> validatorType;
73  validParamList->getEntry("aggregation: drop scheme").setValidator(
74  rcp(new validatorType(Teuchos::tuple<std::string>("classical", "distance laplacian"), "aggregation: drop scheme")));
75  }
76 #undef SET_VALID_ENTRY
77  validParamList->set< bool > ("lightweight wrap", true, "Experimental option for lightweight graph access");
78 
79  validParamList->set< RCP<const FactoryBase> >("A", Teuchos::null, "Generating factory of the matrix A");
80  validParamList->set< RCP<const FactoryBase> >("UnAmalgamationInfo", Teuchos::null, "Generating factory for UnAmalgamationInfo");
81  validParamList->set< RCP<const FactoryBase> >("Coordinates", Teuchos::null, "Generating factory for Coordinates");
82 
83  return validParamList;
84  }
85 
86  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
87  void CoalesceDropFactory_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::DeclareInput(Level &currentLevel) const {
88  Input(currentLevel, "A");
89  Input(currentLevel, "UnAmalgamationInfo");
90 
91  const ParameterList& pL = GetParameterList();
92  if (pL.get<bool>("lightweight wrap") == true) {
93  if (pL.get<std::string>("aggregation: drop scheme") == "distance laplacian")
94  Input(currentLevel, "Coordinates");
95  }
96  }
97 
98  template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
99  void CoalesceDropFactory_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(Level& currentLevel) const {
100  FactoryMonitor m(*this, "Build", currentLevel);
101 
102  typedef Teuchos::ScalarTraits<SC> STS;
103  SC zero = STS::zero(), one = STS::one();
104 
105  RCP<Matrix> A = Get< RCP<Matrix> >(currentLevel, "A");
106  RCP<AmalgamationInfo> amalInfo = Get< RCP<AmalgamationInfo> >(currentLevel, "UnAmalgamationInfo");
107 
108  const ParameterList& pL = GetParameterList();
109 
110  // bool doLightWeightWrap = pL.get<bool>("lightweight wrap");
111  GetOStream(Warnings0) << "lightweight wrap is deprecated" << std::endl;
112 
113  std::string algo = pL.get<std::string>("aggregation: drop scheme");
114 
115  SC threshold = as<SC>(pL.get<double>("aggregation: drop tol"));
116  GetOStream(Runtime0) << "algorithm = \"" << algo << "\": threshold = " << threshold << ", blocksize = " << A->GetFixedBlockSize() << std::endl;
117 
118  Set(currentLevel, "Filtering", (threshold != STS::zero()));
119 
120  const typename STS::magnitudeType dirichletThreshold = STS::magnitude(as<SC>(pL.get<double>("aggregation: Dirichlet threshold")));
121 
122  GO numDropped = 0, numTotal = 0;
123  std::string graphType = "unamalgamated"; //for description purposes only
124 
125  if (algo == "classical") {
126  if (A->GetFixedBlockSize() == 1 && threshold == STS::zero()) {
127  //
128  // Case 1: scalar problem, no dropping => just use matrix graph
129  //
130  RCP<LWGraph_kokkos> graph = rcp(new LWGraph_kokkos(A->getLocalMatrix().graph, A->getDomainMap(), A->getRangeMap(), "graph of A"));
131 
132  // Detect and record rows that correspond to Dirichlet boundary conditions
133  ArrayRCP<const bool> boundaryNodes = Utils_kokkos::DetectDirichletRows(*A, dirichletThreshold);
134  graph->SetBoundaryNodeMap(boundaryNodes);
135 
136  numTotal = A->getNodeNumEntries();
137 
138  if (GetVerbLevel() & Statistics0) {
139  GO numLocalBoundaryNodes = 0;
140  GO numGlobalBoundaryNodes = 0;
141  Kokkos::parallel_reduce(boundaryNodes.size(), KOKKOS_LAMBDA(const LO i, GO& n) {
142  if (boundaryNodes[i])
143  n++;
144  }, numLocalBoundaryNodes, "CoalesceDropF:Build:case1_bnd");
145 
146  RCP<const Teuchos::Comm<int> > comm = A->getRowMap()->getComm();
147  MueLu_sumAll(comm, numLocalBoundaryNodes, numGlobalBoundaryNodes);
148  GetOStream(Statistics0) << "Detected " << numGlobalBoundaryNodes << " Dirichlet nodes" << std::endl;
149  }
150 
151  Set(currentLevel, "DofsPerNode", 1);
152  Set(currentLevel, "Graph", graph);
153  }
154  }
155 
156  }
157 }
158 
159 #endif // MUELU_COALESCEDROPFACTORY_KOKKOS_DEF_HPP
Important warning messages (one line)
One-liner description of what is happening.
Namespace for MueLu classes and methods.
void parallel_reduce(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename Impl::enable_if< !Impl::is_integral< ExecPolicy >::value >::type *=0)
Print statistics that do not involve significant additional computation.
#define MueLu_sumAll(rcpComm, in, out)
#define SET_VALID_ENTRY(name)