MueLu  Version of the Day
MueLu_FactoryManager_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_FACTORYMANAGER_DEF_HPP
47 #define MUELU_FACTORYMANAGER_DEF_HPP
48 
49 #include <Teuchos_ParameterList.hpp>
50 
51 // Headers for factories used by default:
52 #include "MueLu_AmalgamationFactory.hpp"
53 #include "MueLu_CoalesceDropFactory.hpp"
54 #include "MueLu_CoarseMapFactory.hpp"
55 #include "MueLu_ConstraintFactory.hpp"
56 #include "MueLu_CoordinatesTransferFactory.hpp"
57 #include "MueLu_DirectSolver.hpp"
58 #include "MueLu_LineDetectionFactory.hpp"
59 // #include "MueLu_MultiVectorTransferFactory.hpp"
60 #include "MueLu_NoFactory.hpp"
61 #include "MueLu_NullspaceFactory.hpp"
62 #include "MueLu_PatternFactory.hpp"
63 #include "MueLu_RAPFactory.hpp"
64 #include "MueLu_RepartitionHeuristicFactory.hpp"
65 #include "MueLu_RepartitionFactory.hpp"
66 #include "MueLu_SaPFactory.hpp"
67 #include "MueLu_ScaledNullspaceFactory.hpp"
68 #include "MueLu_SmootherFactory.hpp"
69 #include "MueLu_TentativePFactory.hpp"
70 #include "MueLu_TransPFactory.hpp"
71 #include "MueLu_TrilinosSmoother.hpp"
72 #include "MueLu_UncoupledAggregationFactory.hpp"
73 #include "MueLu_HybridAggregationFactory.hpp"
74 #include "MueLu_ZoltanInterface.hpp"
75 
76 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
77 #include "MueLu_AmalgamationFactory_kokkos.hpp"
78 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
79 #include "MueLu_CoarseMapFactory_kokkos.hpp"
80 #include "MueLu_CoordinatesTransferFactory_kokkos.hpp"
81 #include "MueLu_NullspaceFactory_kokkos.hpp"
82 #include "MueLu_SaPFactory_kokkos.hpp"
83 #include "MueLu_TentativePFactory_kokkos.hpp"
84 #include "MueLu_UncoupledAggregationFactory_kokkos.hpp"
85 #endif
86 
88 
89 
90 namespace MueLu {
91 
92 #ifndef HAVE_MUELU_KOKKOS_REFACTOR
93 #define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory) \
94  SetAndReturnDefaultFactory(varName, rcp(new oldFactory()));
95 #else
96 #define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory) \
97  (!useKokkos_) ? SetAndReturnDefaultFactory(varName, rcp(new oldFactory())) : \
98  SetAndReturnDefaultFactory(varName, rcp(new newFactory()));
99 #endif
100 
101  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
102  void FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
103  factoryTable_[varName] = factory;
104  }
105 
106  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
107  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetFactory(const std::string& varName) const {
108  if (factoryTable_.count(varName)) {
109  // Search user provided factories
110  return factoryTable_.find(varName)->second;
111  }
112 
113  // Search/create default factory for this name
114  return GetDefaultFactory(varName);
115  }
116 
117  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
119  return Teuchos::rcp_const_cast<FactoryBase>(GetFactory(varName));
120  }
121 
122  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
124  if (factoryTable_.count(varName)) return true;
125  return false;
126  }
127 
128  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
130  if (defaultFactoryTable_.count(varName)) {
131  // The factory for this name was already created (possibly, for previous level, if we reuse factory manager)
132  return defaultFactoryTable_.find(varName)->second;
133 
134  } else {
135  // No factory was created for this name, but we may know which one to create
136  if (varName == "A") return SetAndReturnDefaultFactory(varName, rcp(new RAPFactory()));
137  if (varName == "RAP Pattern") return GetFactory("A");
138  if (varName == "AP Pattern") return GetFactory("A");
139  if (varName == "Ptent") return MUELU_KOKKOS_FACTORY(varName, TentativePFactory, TentativePFactory_kokkos);
140  if (varName == "P") {
141  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
142  RCP<Factory> factory;
143 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
144  if (useKokkos_)
145  factory = rcp(new SaPFactory_kokkos());
146  else
147 #endif
148  factory = rcp(new SaPFactory());
149  factory->SetFactory("P", GetFactory("Ptent"));
150  return SetAndReturnDefaultFactory(varName, factory);
151  }
152  if (varName == "Nullspace") {
153  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
154  RCP<Factory> factory;
155 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
156  if (useKokkos_)
157  factory = rcp(new NullspaceFactory_kokkos());
158  else
159 #endif
160  factory = rcp(new NullspaceFactory());
161  factory->SetFactory("Nullspace", GetFactory("Ptent"));
162  return SetAndReturnDefaultFactory(varName, factory);
163  }
164  if (varName == "Scaled Nullspace") return SetAndReturnDefaultFactory(varName, rcp(new ScaledNullspaceFactory()));
165 
166  if (varName == "Coordinates") return GetFactory("Ptent");
167  if (varName == "Node Comm") return GetFactory("Ptent");
168 
169  if (varName == "R") return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
170 #if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
171  if (varName == "Partition") return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
172 #endif //ifdef HAVE_MPI
173 
174  if (varName == "Importer") {
175 #ifdef HAVE_MPI
176  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
177 #else
178  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
179 #endif
180  }
181  if (varName == "number of partitions") {
182 #ifdef HAVE_MPI
183  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionHeuristicFactory()));
184 #else
185  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
186 #endif
187  }
188  if (varName == "repartition: heuristic target rows per process") return GetFactory("number of partitions");
189 
190  if (varName == "Graph") return MUELU_KOKKOS_FACTORY(varName, CoalesceDropFactory, CoalesceDropFactory_kokkos);
191  if (varName == "UnAmalgamationInfo") return MUELU_KOKKOS_FACTORY(varName, AmalgamationFactory, AmalgamationFactory_kokkos);
192  if (varName == "Aggregates") return MUELU_KOKKOS_FACTORY(varName, UncoupledAggregationFactory, UncoupledAggregationFactory_kokkos);
193  if (varName == "CoarseMap") return MUELU_KOKKOS_FACTORY(varName, CoarseMapFactory, CoarseMapFactory_kokkos);
194  if (varName == "DofsPerNode") return GetFactory("Graph");
195  if (varName == "Filtering") return GetFactory("Graph");
196  if (varName == "LineDetection_VertLineIds") return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
197  if (varName == "LineDetection_Layers") return GetFactory("LineDetection_VertLineIds");
198  if (varName == "CoarseNumZLayers") return GetFactory("LineDetection_VertLineIds");
199 
200  // Non-Galerkin
201  if (varName == "K") return GetFactory("A");
202  if (varName == "M") return GetFactory("A");
203  if (varName == "Mdiag") return GetFactory("A");
204  if (varName == "cfl-based shift array") return GetFactory("A");
205 
206  // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
207  if (varName == "PreSmoother") return GetFactory("Smoother");
208  if (varName == "PostSmoother") return GetFactory("Smoother");
209 
210  if (varName == "Ppattern") {
211  RCP<PatternFactory> PpFact = rcp(new PatternFactory);
212  PpFact->SetFactory("P", GetFactory("Ptent"));
213  return SetAndReturnDefaultFactory(varName, PpFact);
214  }
215  if (varName == "Constraint") return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
216 
217  if (varName == "Smoother") {
218  Teuchos::ParameterList smootherParamList;
219  smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
220  smootherParamList.set("relaxation: sweeps", Teuchos::OrdinalTraits<LO>::one());
221  smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
222  return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
223  }
224  if (varName == "CoarseSolver") return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));
225 
226 #ifdef HAVE_MUELU_INTREPID2
227  // If we're asking for it, find who made P
228  if (varName == "pcoarsen: element to node map") return GetFactory("P");
229 #endif
230 
231  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
232  }
233  }
234 
235  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
236  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetAndReturnDefaultFactory(const std::string& varName, const RCP<const FactoryBase>& factory) const {
237  TEUCHOS_TEST_FOR_EXCEPTION(factory.is_null(), Exceptions::RuntimeError, "The default factory for building '" << varName << "' is null");
238 
239  GetOStream(Runtime1) << "Using default factory (" << factory->ShortClassName() <<"["<<factory->GetID()<<"] "<< ") for building '" << varName << "'." << std::endl;
240 
241  defaultFactoryTable_[varName] = factory;
242 
243  return defaultFactoryTable_[varName];
244  }
245 
246  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
248  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
249 
250  Teuchos::FancyOStream& fancy = GetOStream(Debug);
251 
252  fancy << "Users factory table (factoryTable_):" << std::endl;
253  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++) {
254  fancy << " " << it->first << " -> ";
255  if (it->second.get() == NoFactory::get()) fancy << "NoFactory";
256  else if (!it->second.get()) fancy<< "NULL";
257  else {
258  fancy << it->second.get()->ShortClassName()<<"["<<it->second.get()->GetID()<<"]";
259 #ifdef HAVE_MUELU_DEBUG
260  fancy<<"("<<Teuchos::toString(it->second.get()) <<")";
261 #endif
262  }
263  fancy<< std::endl;
264  }
265 
266  fancy << "Default factory table (defaultFactoryTable_):" << std::endl;
267  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++) {
268  fancy << " " << it->first << " -> ";
269  if (it->second.get() == NoFactory::get()) fancy << "NoFactory";
270  else if (!it->second.get()) fancy<< "NULL";
271  else {
272  fancy << it->second.get()->ShortClassName()<<"["<<it->second.get()->GetID()<<"]";
273 #ifdef HAVE_MUELU_DEBUG
274  fancy<<"("<<Teuchos::toString(it->second.get()) <<")";
275 #endif
276  }
277  fancy<< std::endl;
278  }
279 
280  }
281 
282 #ifdef HAVE_MUELU_DEBUG
283  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
285  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
286 
287  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
288  if (!it->second.is_null())
289  it->second->ResetDebugData();
290 
291  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
292  if (!it->second.is_null())
293  it->second->ResetDebugData();
294  }
295 #endif
296 
297 
298 #undef MUELU_KOKKOS_FACTORY
299 
300 } // namespace MueLu
301 
302 //TODO: add operator[]
303 //TODO: should we use a parameterList instead of a std::map? It might be useful to tag which factory have been used and report unused factory.
304 //TODO: add an option 'NoDefault' to check if we are using any default factory.
305 //TODO: use Teuchos::ConstNonConstObjectContainer to allow user to modify factories after a GetFactory()
306 
307 #endif // MUELU_FACTORYMANAGER_DEF_HPP
MueLu::AmalgamationFactory
AmalgamationFactory for subblocks of strided map based amalgamation data.
Definition: MueLu_AmalgamationFactory_decl.hpp:78
MueLu::NullspaceFactory
Factory for generating nullspace.
Definition: MueLu_NullspaceFactory_decl.hpp:109
MueLu::ZoltanInterface
Interface to Zoltan library.
Definition: MueLu_ZoltanInterface_decl.hpp:115
MueLu::ConstraintFactory
Factory for building the constraint operator.
Definition: MueLu_ConstraintFactory_decl.hpp:69
MueLu::Runtime1
@ Runtime1
Description of what is happening (more verbose)
Definition: MueLu_VerbosityLevel.hpp:63
MueLu::toString
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
Definition: MueLu_Utilities_decl.hpp:1000
MueLu::TrilinosSmoother
Class that encapsulates external library smoothers.
Definition: MueLu_TrilinosSmoother_decl.hpp:83
MueLu::DirectSolver
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
Definition: MueLu_DirectSolver_decl.hpp:78
string
DASHPOS string(SUBSTRING ${CLASS} 0 ${DASHPOS} CLASS_NAME) set(CONDITION_NAME "") set(CONDITION_NAME_END "") string(SUBSTRING $
Definition: src/CMakeLists.txt:134
MueLu::UncoupledAggregationFactory
Factory for building uncoupled aggregates.
Definition: MueLu_UncoupledAggregationFactory_decl.hpp:145
MueLu_NoFactory.hpp
MueLu
Namespace for MueLu classes and methods.
Definition: MueLu_BrickAggregationFactory_decl.hpp:76
MueLu::Debug
@ Debug
Print additional debugging information.
Definition: MueLu_VerbosityLevel.hpp:79
MueLu::FactoryManager::Print
void Print() const
Definition: MueLu_FactoryManager_def.hpp:247
MueLu::RepartitionFactory
Factory for building permutation matrix that can be be used to shuffle data (matrices,...
Definition: MueLu_RepartitionFactory_decl.hpp:116
MueLu::FactoryManager::SetFactory
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Set Factory.
Definition: MueLu_FactoryManager_def.hpp:102
MueLu::FactoryManager::GetFactoryNonConst
const RCP< FactoryBase > GetFactoryNonConst(const std::string &varName)
Get factory associated with a particular data name (NONCONST version)
Definition: MueLu_FactoryManager_def.hpp:118
MueLu::Exceptions::RuntimeError
Exception throws to report errors in the internal logical of the program.
Definition: MueLu_Exceptions.hpp:70
MueLu_FactoryManager_decl.hpp
MueLu::LineDetectionFactory
Factory for building line detection information.
Definition: MueLu_LineDetectionFactory_decl.hpp:71
MueLu::TransPFactory
Factory for building restriction operators.
Definition: MueLu_TransPFactory_decl.hpp:73
MueLu::FactoryManager::SetAndReturnDefaultFactory
const RCP< const FactoryBase > SetAndReturnDefaultFactory(const std::string &varName, const RCP< const FactoryBase > &factory) const
Definition: MueLu_FactoryManager_def.hpp:236
MueLu::PatternFactory
Factory for building nonzero patterns for energy minimization.
Definition: MueLu_PatternFactory_decl.hpp:67
MueLu::SmootherFactory
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
Definition: MueLu_SmootherFactory_decl.hpp:91
MueLu::FactoryManager::GetDefaultFactory
const RCP< const FactoryBase > GetDefaultFactory(const std::string &varName) const
Definition: MueLu_FactoryManager_def.hpp:129
MUELU_KOKKOS_FACTORY
#define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory)
Definition: MueLu_FactoryManager_def.hpp:93
MueLu::RepartitionHeuristicFactory
Factory for determing the number of partitions for rebalancing.
Definition: MueLu_RepartitionHeuristicFactory_decl.hpp:122
MueLu::ScaledNullspaceFactory
Factory for generating a very special nullspace.
Definition: MueLu_ScaledNullspaceFactory_decl.hpp:109
MueLu::RAPFactory
Factory for building coarse matrices.
Definition: MueLu_RAPFactory_decl.hpp:76
MueLu::CoarseMapFactory
Factory for generating coarse level map. Used by TentativePFactory.
Definition: MueLu_CoarseMapFactory_decl.hpp:117
MueLu::TentativePFactory
Factory for building tentative prolongator.
Definition: MueLu_TentativePFactory_decl.hpp:122
MueLu::SaPFactory
Factory for building Smoothed Aggregation prolongators.
Definition: MueLu_SaPFactory_decl.hpp:99
MueLu::NoFactory::get
static const NoFactory * get()
Definition: MueLu_NoFactory.cpp:59
MueLu::FactoryManager::GetFactory
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Get factory associated with a particular data name.
Definition: MueLu_FactoryManager_def.hpp:107
MueLu::FactoryManager
This class specifies the default factory that should generate some data on a Level if the data does n...
Definition: MueLu_FactoryManager_decl.hpp:108
MueLu::FactoryManager::hasFactory
bool hasFactory(const std::string &varName) const
Check.
Definition: MueLu_FactoryManager_def.hpp:123
MueLu::CoalesceDropFactory
Factory for creating a graph base on a given matrix.
Definition: MueLu_CoalesceDropFactory_decl.hpp:135
MueLu::NoFactory::getRCP
static const RCP< const NoFactory > getRCP()
Static Get() functions.
Definition: MueLu_NoFactory.hpp:90