154 if (
alpha != STS::zero()) {
155 for (LO localRow = 0; localRow <
localNumRows; ++localRow) {
156 const size_t A_numEntries =
A.getNumEntriesInLocalRow(localRow);
161 if (beta != STS::zero()) {
162 for (LO localRow = 0; localRow < localNumRows; ++localRow) {
163 const size_t B_numEntries = B.getNumEntriesInLocalRow(localRow);
164 C_maxNumEntriesPerRow[localRow] += B_numEntries;
168 if (constructorSublist.is_null()) {
169 C = rcp(
new crs_matrix_type(C_rowMap, C_maxNumEntriesPerRow()));
171 C = rcp(
new crs_matrix_type(C_rowMap, C_maxNumEntriesPerRow(),
172 constructorSublist));
182 TEUCHOS_TEST_FOR_EXCEPTION(
true,
183 std::invalid_argument,
184 "Tpetra::RowMatrix::add: The row maps must be the same for statically "
185 "allocated matrices in order to be sure that there is sufficient space "
186 "to do the addition");
189#ifdef HAVE_TPETRA_DEBUG
190 TEUCHOS_TEST_FOR_EXCEPTION(C.is_null(), std::logic_error,
191 "Tpetra::RowMatrix::add: C should not be null at this point. "
192 "Please report this bug to the Tpetra developers.");
197 using gids_type = nonconst_global_inds_host_view_type;
198 using vals_type = nonconst_values_host_view_type;
202 if (alpha != STS::zero()) {
203 const LO A_localNumRows =
static_cast<LO
>(A_rowMap->getLocalNumElements());
204 for (LO localRow = 0; localRow < A_localNumRows; ++localRow) {
205 size_t A_numEntries = A.getNumEntriesInLocalRow(localRow);
206 const GO globalRow = A_rowMap->getGlobalElement(localRow);
207 if (A_numEntries >
static_cast<size_t>(ind.size())) {
208 Kokkos::resize(ind, A_numEntries);
209 Kokkos::resize(val, A_numEntries);
211 gids_type indView = Kokkos::subview(ind, std::make_pair((
size_t)0, A_numEntries));
212 vals_type valView = Kokkos::subview(val, std::make_pair((
size_t)0, A_numEntries));
213 A.getGlobalRowCopy(globalRow, indView, valView, A_numEntries);
215 if (alpha != STS::one()) {
216 for (
size_t k = 0; k < A_numEntries; ++k) {
220 C->insertGlobalValues(globalRow, A_numEntries,
221 reinterpret_cast<const Scalar*
>(valView.data()),
226 if (beta != STS::zero()) {
227 const LO B_localNumRows =
static_cast<LO
>(B_rowMap->getLocalNumElements());
228 for (LO localRow = 0; localRow < B_localNumRows; ++localRow) {
229 size_t B_numEntries = B.getNumEntriesInLocalRow(localRow);
230 const GO globalRow = B_rowMap->getGlobalElement(localRow);
231 if (B_numEntries >
static_cast<size_t>(ind.size())) {
232 Kokkos::resize(ind, B_numEntries);
233 Kokkos::resize(val, B_numEntries);
235 gids_type indView = Kokkos::subview(ind, std::make_pair((
size_t)0, B_numEntries));
236 vals_type valView = Kokkos::subview(val, std::make_pair((
size_t)0, B_numEntries));
237 B.getGlobalRowCopy(globalRow, indView, valView, B_numEntries);
239 if (beta != STS::one()) {
240 for (
size_t k = 0; k < B_numEntries; ++k) {
244 C->insertGlobalValues(globalRow, B_numEntries,
245 reinterpret_cast<const Scalar*
>(valView.data()),
250 if (callFillComplete) {
251 if (fillCompleteSublist.is_null()) {
252 C->fillComplete(theDomainMap, theRangeMap);
254 C->fillComplete(theDomainMap, theRangeMap, fillCompleteSublist);
258 return rcp_implicit_cast<this_type>(C);
261template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
264 Teuchos::Array<char>& exports,
267#ifdef HAVE_TPETRA_DEBUG
270 using Teuchos::reduceAll;
271 std::ostringstream
msg;
276 }
catch (std::exception&
e) {
281 const Teuchos::Comm<int>& comm = *(this->getComm());
285 const int myRank = comm.getRank();
286 const int numProcs = comm.getSize();
289 std::ostringstream
os;
290 os <<
"Proc " <<
myRank <<
": " <<
msg.str() << std::endl;
291 std::cerr <<
os.str();
298 true, std::logic_error,
299 "packImpl() threw an exception on one or "
300 "more participating processes.");
309template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
312 size_t& totalNumEntries,
313 const Teuchos::ArrayView<const LocalOrdinal>&
exportLIDs)
const {
316 typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
327 if (
curNumEntries == Teuchos::OrdinalTraits<size_t>::invalid()) {
330 totalNumEntries += curNumEntries;
341 const size_t allocSize =
342 static_cast<size_t>(numExportLIDs) *
sizeof(LO) +
343 totalNumEntries * (
sizeof(Scalar) +
sizeof(GO));
344 if (
static_cast<size_t>(exports.size()) < allocSize) {
345 exports.resize(allocSize);
349template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
350bool RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
351 packRow(
char*
const numEntOut,
355 const LocalOrdinal lclRow)
const {
356 using Teuchos::Array;
357 using Teuchos::ArrayView;
358 typedef LocalOrdinal LO;
359 typedef GlobalOrdinal GO;
362 const LO numEntLO =
static_cast<LO
>(numEnt);
363 memcpy(numEntOut, &numEntLO,
sizeof(LO));
365 if (this->supportsRowViews()) {
366 if (this->isLocallyIndexed()) {
370 local_inds_host_view_type indIn;
371 values_host_view_type valIn;
372 this->getLocalRowView(lclRow, indIn, valIn);
373 const map_type&
colMap = *(this->getColMap());
376 for (
size_t k = 0; k < numEnt; ++k) {
377 const GO gblIndIn =
colMap.getGlobalElement(indIn[k]);
378 memcpy(indOut + k *
sizeof(GO), &gblIndIn,
sizeof(GO));
380 memcpy(valOut, valIn.data(), numEnt *
sizeof(Scalar));
381 }
else if (this->isGloballyIndexed()) {
387 global_inds_host_view_type indIn;
388 values_host_view_type valIn;
389 const map_type&
rowMap = *(this->getRowMap());
390 const GO gblRow =
rowMap.getGlobalElement(lclRow);
391 this->getGlobalRowView(gblRow, indIn, valIn);
392 memcpy(indOut, indIn.data(), numEnt *
sizeof(GO));
393 memcpy(valOut, valIn.data(), numEnt *
sizeof(Scalar));
402 if (this->isLocallyIndexed()) {
403 nonconst_local_inds_host_view_type indIn(
"indIn", numEnt);
404 nonconst_values_host_view_type valIn(
"valIn", numEnt);
405 size_t theNumEnt = 0;
406 this->getLocalRowCopy(lclRow, indIn, valIn, theNumEnt);
407 if (theNumEnt != numEnt) {
410 const map_type&
colMap = *(this->getColMap());
413 for (
size_t k = 0; k < numEnt; ++k) {
414 const GO gblIndIn =
colMap.getGlobalElement(indIn[k]);
415 memcpy(indOut + k *
sizeof(GO), &gblIndIn,
sizeof(GO));
417 memcpy(valOut, valIn.data(), numEnt *
sizeof(Scalar));
418 }
else if (this->isGloballyIndexed()) {
419 nonconst_global_inds_host_view_type indIn(
"indIn", numEnt);
420 nonconst_values_host_view_type valIn(
"valIn", numEnt);
421 const map_type&
rowMap = *(this->getRowMap());
422 const GO gblRow =
rowMap.getGlobalElement(lclRow);
423 size_t theNumEnt = 0;
424 this->getGlobalRowCopy(gblRow, indIn, valIn, theNumEnt);
425 if (theNumEnt != numEnt) {
428 memcpy(indOut, indIn.data(), numEnt *
sizeof(GO));
429 memcpy(valOut, valIn.data(), numEnt *
sizeof(Scalar));
439template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
440void RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
441 packImpl(
const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
442 Teuchos::Array<char>& exports,
443 const Teuchos::ArrayView<size_t>& numPacketsPerLID,
444 size_t& constantNumPackets)
const {
445 using Teuchos::Array;
446 using Teuchos::ArrayView;
448 using Teuchos::av_reinterpret_cast;
450 typedef LocalOrdinal LO;
451 typedef GlobalOrdinal GO;
452 typedef typename ArrayView<const LO>::size_type size_type;
458 "exportLIDs.size() = " <<
numExportLIDs <<
" != numPacketsPerLID.size()"
470 size_t totalNumEntries = 0;
471 allocatePackSpace(exports, totalNumEntries,
exportLIDs);
472 const size_t bufSize =
static_cast<size_t>(exports.size());
487 bool outOfBounds =
false;
494 const size_t numEnt = this->getNumEntriesInLocalRow(
lclRow);
505 const size_t numBytes =
sizeof(LO) +
514 packErr = !packRow(numEntBeg, valBeg, indBeg, numEnt, lclRow);
517 firstBadOffset = offset;
518 firstBadNumBytes = numBytes;
524 numPacketsPerLID[i] = numBytes;
535 TEUCHOS_TEST_FOR_EXCEPTION(
536 outOfBounds, std::logic_error,
537 "First invalid offset into 'exports' "
538 "pack buffer at index i = "
539 << firstBadIndex <<
". exportLIDs[i]: "
540 << exportLIDs[firstBadIndex] <<
", bufSize: " << bufSize <<
", offset: "
541 << firstBadOffset <<
", numBytes: " << firstBadNumBytes <<
".");
542 TEUCHOS_TEST_FOR_EXCEPTION(
543 packErr, std::logic_error,
"First error in packRow() at index i = " << firstBadIndex <<
". exportLIDs[i]: " << exportLIDs[firstBadIndex] <<
", bufSize: " << bufSize <<
", offset: " << firstBadOffset <<
", numBytes: " << firstBadNumBytes <<
".");
554#define TPETRA_ROWMATRIX_INSTANT(SCALAR, LO, GO, NODE) \
555 template class RowMatrix<SCALAR, LO, GO, NODE>;