Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_FECrsMatrix_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Tpetra: Templated Linear Algebra Services Package
4 //
5 // Copyright 2008 NTESS and the Tpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TPETRA_FECRSMATRIX_DEF_HPP
11 #define TPETRA_FECRSMATRIX_DEF_HPP
12 #include <sstream>
13 #include "Tpetra_CrsMatrix.hpp"
14 
15 namespace Tpetra {
16 
17 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
19  FECrsMatrix(const Teuchos::RCP<const fe_crs_graph_type>& graph,
20  const Teuchos::RCP<Teuchos::ParameterList>& params)
21  : // We want the OWNED_PLUS_SHARED graph here
22  // NOTE: The casts below are terrible, but necesssary
23  crs_matrix_type(graph->inactiveCrsGraph_.is_null() ? Teuchos::rcp_const_cast<crs_graph_type>(Teuchos::rcp_dynamic_cast<const crs_graph_type>(graph)) : graph->inactiveCrsGraph_, params)
24  , feGraph_(graph)
25 
26 {
27  const char tfecfFuncName[] = "FECrsMatrix(RCP<const FECrsGraph>[, RCP<ParameterList>]): ";
28 
29  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(graph.is_null(), std::runtime_error, "Input graph is null.");
30  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!graph->isFillComplete(), std::runtime_error,
31  "Input graph is not "
32  "fill complete. You must call fillComplete on the graph before using "
33  "it to construct a FECrsMatrix. Note that calling resumeFill on the "
34  "graph makes it not fill complete, even if you had previously called "
35  "fillComplete. In that case, you must call fillComplete on the graph "
36  "again.");
37  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(*graph->activeCrsGraph_ != FE::ACTIVE_OWNED, std::runtime_error,
38  "Input graph must be in FE::ACTIVE_OWNED mode when this constructor is called.");
39 
40  bool start_owned = false;
41  if (!params.is_null()) {
42  if (params->isParameter("start owned")) {
43  start_owned = params->get<bool>("start owned", start_owned);
44  }
45  }
46  if (start_owned) {
47  activeCrsMatrix_ = Teuchos::rcp(new FE::WhichActive(FE::ACTIVE_OWNED));
48  } else {
49  activeCrsMatrix_ = Teuchos::rcp(new FE::WhichActive(FE::ACTIVE_OWNED_PLUS_SHARED));
50  }
51 
52  // Make an "inactive" matrix, if we need to
53  if (!graph->inactiveCrsGraph_.is_null()) {
54  // We are *requiring* memory aliasing here, so we'll grab the first chunk of the Owned+Shared matrix's values array to make the
55  // guy for the Owned matrix.
56  inactiveCrsMatrix_ = Teuchos::rcp(new crs_matrix_type(*this, graph));
57  }
58 
59  fillState_ = Teuchos::rcp(new FE::FillState(FE::FillState::closed));
60 }
61 
62 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
64  if (!inactiveCrsMatrix_.is_null() && *activeCrsMatrix_ == FE::ACTIVE_OWNED_PLUS_SHARED) {
65  // Do a self-export in "restricted mode"
66  this->doExport(*this, *feGraph_->ownedRowsImporter_, CM, true);
67  inactiveCrsMatrix_->fillComplete();
68  }
69  crs_matrix_type::fillComplete();
70 } // end doOverlapToLocal
71 
72 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
74  // This should be a no-op for all of our purposes
75 } // end doLocalToOverlap
76 
77 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
79  if (*activeCrsMatrix_ == FE::ACTIVE_OWNED_PLUS_SHARED)
80  *activeCrsMatrix_ = FE::ACTIVE_OWNED;
81  else
82  *activeCrsMatrix_ = FE::ACTIVE_OWNED_PLUS_SHARED;
83 
84  if (inactiveCrsMatrix_.is_null()) return;
85 
86  this->swap(*inactiveCrsMatrix_);
87 
88 } // end switchActiveCrsMatrix
89 
90 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92  if (*activeCrsMatrix_ == FE::ACTIVE_OWNED_PLUS_SHARED) {
93  doOwnedPlusSharedToOwned(Tpetra::ADD);
94  switchActiveCrsMatrix();
95  } else
96  throw std::runtime_error("FECrsMatrix: Local CrsMatrix already active. Cannot endFill()");
97 }
98 
99 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
100 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::beginFill() {
101  // Note: This does not throw an error since the on construction, the FECRS is in overlap mode. Ergo, calling beginFill(),
102  // like one should expect to do in a rational universe, should not cause an error.
103  if (*activeCrsMatrix_ == FE::ACTIVE_OWNED) {
104  this->resumeFill();
105  switchActiveCrsMatrix();
106  }
107  this->resumeFill();
108 }
109 
110 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
112  const char tfecfFuncName[] = "FECrsMatrix::beginAssembly: ";
113  if (*fillState_ != FE::FillState::closed) {
114  std::ostringstream errmsg;
115  errmsg << "Cannot begin assembly, matrix is not in a closed state "
116  << "but is currently open for "
117  << (*fillState_ == FE::FillState::open ? "assembly" : "modification");
118  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
119  }
120  *fillState_ = FE::FillState::open;
121  this->beginFill();
122 }
123 
124 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
126  const char tfecfFuncName[] = "FECrsMatrix::endAssembly: ";
127  if (*fillState_ != FE::FillState::open) {
128  std::ostringstream errmsg;
129  errmsg << "Cannot end assembly, matrix is not open for assembly "
130  << "but is currently "
131  << (*fillState_ == FE::FillState::closed ? "closed" : "open for modification");
132  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
133  }
134  *fillState_ = FE::FillState::closed;
135  this->endFill();
136 }
137 
138 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
140  const char tfecfFuncName[] = "FECrsMatrix::beginModify: ";
141  if (*fillState_ != FE::FillState::closed) {
142  std::ostringstream errmsg;
143  errmsg << "Cannot begin modifying, matrix is not in a closed state "
144  << "but is currently open for "
145  << (*fillState_ == FE::FillState::open ? "assembly" : "modification");
146  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
147  }
148  *fillState_ = FE::FillState::modify;
149  this->resumeFill();
150 }
151 
152 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
154  const char tfecfFuncName[] = "FECrsMatrix::endModify: ";
155  if (*fillState_ != FE::FillState::modify) {
156  std::ostringstream errmsg;
157  errmsg << "Cannot end modifying, matrix is not open to modify but is currently "
158  << (*fillState_ == FE::FillState::open ? "open for assembly" : "closed");
159  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
160  }
161  *fillState_ = FE::FillState::closed;
162  this->fillComplete();
163 }
164 
165 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
166 LocalOrdinal
168  impl_scalar_type rowVals[],
169  const crs_graph_type& graph,
170  const RowInfo& rowInfo,
171  const GlobalOrdinal inds[],
172  const impl_scalar_type newVals[],
173  const LocalOrdinal numElts) {
174  const char tfecfFuncName[] = "FECrsMatrix::replaceGlobalValues: ";
175  if (*fillState_ != FE::FillState::open) {
176  std::ostringstream errmsg;
177  errmsg << "Cannot replace global values, matrix is not open for assembly "
178  << "but is currently "
179  << (*fillState_ == FE::FillState::modify ? "open for modification" : "closed");
180  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
181  }
182  return crs_matrix_type::replaceGlobalValuesImpl(rowVals, graph, rowInfo, inds, newVals, numElts);
183 }
184 
185 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
186 LocalOrdinal
188  impl_scalar_type rowVals[],
189  const crs_graph_type& graph,
190  const RowInfo& rowInfo,
191  const LocalOrdinal inds[],
192  const impl_scalar_type newVals[],
193  const LocalOrdinal numElts) {
194  const char tfecfFuncName[] = "FECrsMatrix::replaceLocalValues: ";
195  if (*fillState_ != FE::FillState::open && *fillState_ != FE::FillState::modify) {
196  std::ostringstream errmsg;
197  errmsg << "Cannot replace local values, matrix is not open to fill/modify. "
198  << "The matrix is currently closed";
199  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
200  }
201  return crs_matrix_type::replaceLocalValuesImpl(rowVals, graph, rowInfo, inds, newVals, numElts);
202 }
203 
204 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
205 LocalOrdinal
206 FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sumIntoGlobalValuesImpl(
207  impl_scalar_type rowVals[],
208  const crs_graph_type& graph,
209  const RowInfo& rowInfo,
210  const GlobalOrdinal inds[],
211  const impl_scalar_type newVals[],
212  const LocalOrdinal numElts,
213  const bool atomic) {
214  const char tfecfFuncName[] = "FECrsMatrix::sumIntoGlobalValues: ";
215  if (*fillState_ != FE::FillState::open) {
216  std::ostringstream errmsg;
217  errmsg << "Cannot sum in to global values, matrix is not open for assembly. "
218  << "The matrix is currently "
219  << (*fillState_ == FE::FillState::modify ? "open for modification" : "closed");
220  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
221  }
222  return crs_matrix_type::sumIntoGlobalValuesImpl(
223  rowVals, graph, rowInfo, inds, newVals, numElts, atomic);
224 }
225 
226 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
227 LocalOrdinal
228 FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sumIntoLocalValuesImpl(
229  impl_scalar_type rowVals[],
230  const crs_graph_type& graph,
231  const RowInfo& rowInfo,
232  const LocalOrdinal inds[],
233  const impl_scalar_type newVals[],
234  const LocalOrdinal numElts,
235  const bool atomic) {
236  const char tfecfFuncName[] = "FECrsMatrix::sumIntoLocalValues: ";
237  if (*fillState_ != FE::FillState::open) {
238  std::ostringstream errmsg;
239  errmsg << "Cannot sum in to local values, matrix is not open for assembly. "
240  << "The matrix is currently "
241  << (*fillState_ == FE::FillState::modify ? "open for modification" : "closed");
242  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
243  }
244  return crs_matrix_type::sumIntoLocalValuesImpl(
245  rowVals, graph, rowInfo, inds, newVals, numElts, atomic);
246 }
247 
248 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
249 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::insertGlobalValuesImpl(
250  crs_graph_type& graph,
251  RowInfo& rowInfo,
252  const GlobalOrdinal gblColInds[],
253  const impl_scalar_type vals[],
254  const size_t numInputEnt) {
255  const char tfecfFuncName[] = "FECrsMatrix::insertGlobalValues: ";
256  if (*fillState_ != FE::FillState::open) {
257  std::ostringstream errmsg;
258  errmsg << "Cannot insert global values, matrix is not open for assembly. "
259  << "The matrix is currently "
260  << (*fillState_ == FE::FillState::modify ? "open for modification" : "closed");
261  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
262  }
263  return crs_matrix_type::insertGlobalValuesImpl(graph, rowInfo, gblColInds, vals, numInputEnt);
264 }
265 
266 } // end namespace Tpetra
267 
268 //
269 // Explicit instantiation macro
270 //
271 // Must be expanded from within the Tpetra namespace!
272 //
273 #define TPETRA_FECRSMATRIX_INSTANT(SCALAR, LO, GO, NODE) \
274  template class FECrsMatrix<SCALAR, LO, GO, NODE>;
275 
276 #endif // TPETRA_FECRSMATRIX_DEF
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > crs_matrix_type
Parent CrsMatrix type using the same scalars.
LocalOrdinal replaceGlobalValuesImpl(impl_scalar_type rowVals[], const crs_graph_type &graph, const RowInfo &rowInfo, const GlobalOrdinal inds[], const impl_scalar_type newVals[], const LocalOrdinal numElts)
Overloads of modification methods.
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
void doOwnedToOwnedPlusShared(const CombineMode CM=Tpetra::ADD)
Migrate data from the owned to the owned+shared matrix Precondition: Must be FE_ACTIVE_OWNED mode...
void switchActiveCrsMatrix()
Switches which CrsGraph is active (without migrating data)
CombineMode
Rule for combining data in an Import or Export.
void beginAssembly()
Activates the owned+shared mode for assembly.
Sum new values.
void endModify()
Closes modification phase.
void doOwnedPlusSharedToOwned(const CombineMode CM=Tpetra::ADD)
Migrate data from the owned+shared to the owned matrix Since this is non-unique -&gt; unique...
FECrsMatrix(const Teuchos::RCP< const fe_crs_graph_type > &graph, const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Constructor specifying one or two previously constructed graphs.
void endAssembly()
Migrates data to the owned mode.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
typename row_matrix_type::impl_scalar_type impl_scalar_type
The type used internally in place of Scalar.
void beginModify()
Activates the owned mode for modifying local values.