Tpetra parallel linear algebra  Version of the Day
Tpetra_FECrsMatrix_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_FECRSMATRIX_DEF_HPP
43 #define TPETRA_FECRSMATRIX_DEF_HPP
44 #include <sstream>
45 #include "Tpetra_CrsMatrix.hpp"
46 
47 namespace Tpetra {
48 
49 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
50 FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
51 FECrsMatrix(const Teuchos::RCP<const fe_crs_graph_type>& graph,
52  const Teuchos::RCP<Teuchos::ParameterList>& params) :
53  // We want the OWNED_PLUS_SHARED graph here
54  // NOTE: The casts below are terrible, but necesssary
55  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),
56  feGraph_(graph)
57 
58 {
59  const char tfecfFuncName[] = "FECrsMatrix(RCP<const FECrsGraph>[, RCP<ParameterList>]): ";
60 
61  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
62  (graph.is_null (), std::runtime_error, "Input graph is null.");
63  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
64  (!graph->isFillComplete (), std::runtime_error, "Input graph is not "
65  "fill complete. You must call fillComplete on the graph before using "
66  "it to construct a FECrsMatrix. Note that calling resumeFill on the "
67  "graph makes it not fill complete, even if you had previously called "
68  "fillComplete. In that case, you must call fillComplete on the graph "
69  "again.");
70  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
71  ( *graph->activeCrsGraph_!= fe_crs_graph_type::FE_ACTIVE_OWNED,std::runtime_error,
72  "Input graph must be in FE_ACTIVE_OWNED mode when this constructor is called.");
73 
74  activeCrsMatrix_ = Teuchos::rcp(new FEWhichActive(FE_ACTIVE_OWNED_PLUS_SHARED));
75 
76  // Make an "inactive" matrix, if we need to
77  if(!graph->inactiveCrsGraph_.is_null() ) {
78  // We are *requiring* memory aliasing here, so we'll grab the first chunk of the Owned+Shared matrix's values array to make the
79  // guy for the Owned matrix.
80  inactiveCrsMatrix_ = Teuchos::rcp(new crs_matrix_type(*this,graph));
81  }
82 
83  fillState_ = Teuchos::rcp(new FillState(FillState::closed));
84 }
85 
86 
87 
88 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
89 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::doOwnedPlusSharedToOwned(const CombineMode CM) {
90  if(!inactiveCrsMatrix_.is_null() && *activeCrsMatrix_ == FE_ACTIVE_OWNED_PLUS_SHARED) {
91  // Do a self-export in "restricted mode"
92  this->doExport(*this,*feGraph_->ownedRowsImporter_,CM,true);
93  inactiveCrsMatrix_->fillComplete();
94  }
95  crs_matrix_type::fillComplete();
96 }//end doOverlapToLocal
97 
98 
99 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
100 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::doOwnedToOwnedPlusShared(const CombineMode /* CM */) {
101  // This should be a no-op for all of our purposes
102 }//end doLocalToOverlap
103 
104 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
105 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::switchActiveCrsMatrix() {
106  if(*activeCrsMatrix_ == FE_ACTIVE_OWNED_PLUS_SHARED)
107  *activeCrsMatrix_ = FE_ACTIVE_OWNED;
108  else
109  *activeCrsMatrix_ = FE_ACTIVE_OWNED_PLUS_SHARED;
110 
111  if(inactiveCrsMatrix_.is_null()) return;
112 
113  this->swap(*inactiveCrsMatrix_);
114 
115 }//end switchActiveCrsMatrix
116 
117 
118 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
119 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::endFill() {
120  if(*activeCrsMatrix_ == FE_ACTIVE_OWNED_PLUS_SHARED) {
121  doOwnedPlusSharedToOwned(Tpetra::ADD);
122  switchActiveCrsMatrix();
123  }
124  else
125  throw std::runtime_error("FECrsMatrix: Local CrsMatrix already active. Cannot endFill()");
126 }
127 
128 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
129 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::beginFill() {
130  // Note: This does not throw an error since the on construction, the FECRS is in overlap mode. Ergo, calling beginFill(),
131  // like one should expect to do in a rational universe, should not cause an error.
132  if(*activeCrsMatrix_ == FE_ACTIVE_OWNED) {
133  this->resumeFill();
134  switchActiveCrsMatrix();
135  }
136  this->resumeFill();
137 }
138 
139 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
140 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::beginAssembly() {
141  const char tfecfFuncName[] = "FECrsMatrix::beginAssembly: ";
142  if (*fillState_ != FillState::closed)
143  {
144  std::ostringstream errmsg;
145  errmsg << "Cannot begin assembly, matrix is not in a closed state "
146  << "but is currently open for "
147  << (*fillState_ == FillState::open ? "assembly" : "modification");
148  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
149  }
150  *fillState_ = FillState::open;
151  this->beginFill();
152 }
153 
154 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
155 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::endAssembly() {
156  const char tfecfFuncName[] = "FECrsMatrix::endAssembly: ";
157  if (*fillState_ != FillState::open)
158  {
159  std::ostringstream errmsg;
160  errmsg << "Cannot end assembly, matrix is not open for assembly "
161  << "but is currently "
162  << (*fillState_ == FillState::closed ? "closed" : "open for modification");
163  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
164  }
165  *fillState_ = FillState::closed;
166  this->endFill();
167 }
168 
169 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
170 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::beginModify() {
171  const char tfecfFuncName[] = "FECrsMatrix::beginModify: ";
172  if (*fillState_ != FillState::closed)
173  {
174  std::ostringstream errmsg;
175  errmsg << "Cannot begin modifying, matrix is not in a closed state "
176  << "but is currently open for "
177  << (*fillState_ == FillState::open ? "assembly" : "modification");
178  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
179  }
180  *fillState_ = FillState::modify;
181  this->resumeFill();
182 }
183 
184 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
185 void FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::endModify() {
186  const char tfecfFuncName[] = "FECrsMatrix::endModify: ";
187  if (*fillState_ != FillState::modify)
188  {
189  std::ostringstream errmsg;
190  errmsg << "Cannot end modifying, matrix is not open to modify but is currently "
191  << (*fillState_ == FillState::open ? "open for assembly" : "closed");
192  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
193  }
194  *fillState_ = FillState::closed;
195  this->fillComplete();
196 }
197 
198 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
199 LocalOrdinal
200 FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::replaceGlobalValuesImpl(
201  impl_scalar_type rowVals[],
202  const crs_graph_type& graph,
203  const RowInfo& rowInfo,
204  const GlobalOrdinal inds[],
205  const impl_scalar_type newVals[],
206  const LocalOrdinal numElts)
207 {
208  const char tfecfFuncName[] = "FECrsMatrix::replaceGlobalValues: ";
209  if (*fillState_ != FillState::open)
210  {
211  std::ostringstream errmsg;
212  errmsg << "Cannot replace global values, matrix is not open for assembly "
213  << "but is currently "
214  << (*fillState_ == FillState::modify ? "open for modification" : "closed");
215  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
216  }
217  return crs_matrix_type::replaceGlobalValuesImpl(rowVals, graph, rowInfo, inds, newVals, numElts);
218 }
219 
220 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
221 LocalOrdinal
222 FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::replaceLocalValuesImpl(
223  impl_scalar_type rowVals[],
224  const crs_graph_type& graph,
225  const RowInfo& rowInfo,
226  const LocalOrdinal inds[],
227  const impl_scalar_type newVals[],
228  const LocalOrdinal numElts)
229 {
230  const char tfecfFuncName[] = "FECrsMatrix::replaceLocalValues: ";
231  if (*fillState_ != FillState::open && *fillState_ != FillState::modify)
232  {
233  std::ostringstream errmsg;
234  errmsg << "Cannot replace local values, matrix is not open to fill/modify. "
235  << "The matrix is currently closed";
236  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
237  }
238  return crs_matrix_type::replaceLocalValuesImpl(rowVals, graph, rowInfo, inds, newVals, numElts);
239 }
240 
241 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
242 LocalOrdinal
243 FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sumIntoGlobalValuesImpl(
244  impl_scalar_type rowVals[],
245  const crs_graph_type& graph,
246  const RowInfo& rowInfo,
247  const GlobalOrdinal inds[],
248  const impl_scalar_type newVals[],
249  const LocalOrdinal numElts,
250  const bool atomic)
251 {
252  const char tfecfFuncName[] = "FECrsMatrix::sumIntoGlobalValues: ";
253  if (*fillState_ != FillState::open)
254  {
255  std::ostringstream errmsg;
256  errmsg << "Cannot sum in to global values, matrix is not open for assembly. "
257  << "The matrix is currently "
258  << (*fillState_ == FillState::modify ? "open for modification" : "closed");
259  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
260  }
261  return crs_matrix_type::sumIntoGlobalValuesImpl(
262  rowVals, graph, rowInfo, inds, newVals, numElts, atomic
263  );
264 }
265 
266 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
267 LocalOrdinal
268 FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sumIntoLocalValuesImpl(
269  impl_scalar_type rowVals[],
270  const crs_graph_type& graph,
271  const RowInfo& rowInfo,
272  const LocalOrdinal inds[],
273  const impl_scalar_type newVals[],
274  const LocalOrdinal numElts,
275  const bool atomic)
276 {
277  const char tfecfFuncName[] = "FECrsMatrix::sumIntoLocalValues: ";
278  if (*fillState_ != FillState::open)
279  {
280  std::ostringstream errmsg;
281  errmsg << "Cannot sum in to local values, matrix is not open for assembly. "
282  << "The matrix is currently "
283  << (*fillState_ == FillState::modify ? "open for modification" : "closed");
284  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
285  }
286  return crs_matrix_type::sumIntoLocalValuesImpl(
287  rowVals, graph, rowInfo, inds, newVals, numElts, atomic
288  );
289 }
290 
291 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
292 void
293 FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::insertGlobalValuesImpl(
294  crs_graph_type& graph,
295  RowInfo& rowInfo,
296  const GlobalOrdinal gblColInds[],
297  const impl_scalar_type vals[],
298  const size_t numInputEnt)
299 {
300  const char tfecfFuncName[] = "FECrsMatrix::insertGlobalValues: ";
301  if (*fillState_ != FillState::open)
302  {
303  std::ostringstream errmsg;
304  errmsg << "Cannot insert global values, matrix is not open for assembly. "
305  << "The matrix is currently "
306  << (*fillState_ == FillState::modify ? "open for modification" : "closed");
307  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(true, std::logic_error, errmsg.str());
308  }
309  return crs_matrix_type::insertGlobalValuesImpl(graph, rowInfo, gblColInds, vals, numInputEnt);
310 }
311 
312 } // end namespace Tpetra
313 
314 
315 //
316 // Explicit instantiation macro
317 //
318 // Must be expanded from within the Tpetra namespace!
319 //
320 #define TPETRA_FECRSMATRIX_INSTANT(SCALAR,LO,GO,NODE) \
321  template class FECrsMatrix<SCALAR, LO, GO, NODE>;
322 
323 
324 
325 #endif // TPETRA_FECRSMATRIX_DEF
Namespace Tpetra contains the class and methods constituting the Tpetra library.
CombineMode
Rule for combining data in an Import or Export.
@ ADD
Sum new values.