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
47namespace Tpetra {
48
49template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
50FECrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
51FECrsMatrix(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
88template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
89void 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
99template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
100void 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
104template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
105void 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
118template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
119void 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
128template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
129void 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
139template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
140void 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
154template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
155void 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
169template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
170void 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
184template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
185void 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
198template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
199LocalOrdinal
200FECrsMatrix<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
220template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
221LocalOrdinal
222FECrsMatrix<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
241template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
242LocalOrdinal
243FECrsMatrix<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
266template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
267LocalOrdinal
268FECrsMatrix<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
291template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
292void
293FECrsMatrix<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.