548 typedef LO local_ordinal_type;
549 typedef GO global_ordinal_type;
550 typedef NT node_type;
551 typedef typename NT::device_type device_type;
553 typedef ::Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type>
map_type;
558 global_ordinal_type, node_type> base_type;
570 base_type (::Teuchos::null),
571 localError_ (new bool (false)),
572 errs_ (new std::shared_ptr<std::ostringstream> ())
584 localError_ (new bool (false)),
585 errs_ (new std::shared_ptr<std::ostringstream> ())
615 const GO gblColInds[],
617 const std::size_t numEnt)
625 std::initializer_list<GO> gblColInds,
626 std::initializer_list<SC> vals,
627 const std::size_t numEnt)
630 vals.begin (), numEnt);
640 template<
class OffsetType>
642 buildCrs (::Kokkos::View<OffsetType*, device_type>& rowOffsets,
643 ::Kokkos::View<GO*, device_type>& gblColInds,
644 ::Kokkos::View<typename ::Kokkos::ArithTraits<SC>::val_type*,
device_type>& vals)
646 static_assert (std::is_integral<OffsetType>::value,
647 "OffsetType must be a built-in integer type.");
648 using ::Kokkos::create_mirror_view;
649 using ::Kokkos::deep_copy;
650 using ::Kokkos::View;
651 typedef typename ::Kokkos::ArithTraits<SC>::val_type ISC;
655 gblColInds = View<GO*, device_type> (
"gblColInds", numEnt);
656 vals = View<ISC*, device_type> (
"vals", numEnt);
657 auto gblColInds_h = create_mirror_view (gblColInds);
658 auto vals_h = create_mirror_view (vals);
660 std::vector<std::size_t> rowOffsetsSV;
661 this->impl_.buildCrs (rowOffsetsSV,
662 gblColInds_h.data (),
665 View<OffsetType*, device_type> (
"rowOffsets", rowOffsetsSV.size ());
666 typename View<OffsetType*, device_type>::HostMirror
667 rowOffsets_h (rowOffsetsSV.data (), rowOffsetsSV.size ());
687 if (comm.is_null ()) {
688 this->
map_ = ::Teuchos::null;
691 this->
map_ = this->buildMap (comm);
706 TEUCHOS_TEST_FOR_EXCEPTION
707 (this->
getMap ().is_null (), std::runtime_error,
"Tpetra::Details::"
708 "CooMatrix::fillComplete: This object does not yet have a Map. "
709 "You must call the version of fillComplete "
710 "that takes an input communicator.");
750 return ((*errs_).get () == NULL) ? std::string (
"") : (*errs_)->str ();
766 std::shared_ptr<bool> localError_;
775 std::shared_ptr<std::shared_ptr<std::ostringstream> > errs_;
779 markLocalErrorAndGetStream ()
781 * (this->localError_) =
true;
782 if ((*errs_).get () == NULL) {
783 *errs_ = std::shared_ptr<std::ostringstream> (
new std::ostringstream ());
792 using Teuchos::TypeNameTraits;
794 std::ostringstream os;
795 os <<
"\"Tpetra::Details::CooMatrix\": {"
796 <<
"SC: " << TypeNameTraits<SC>::name ()
797 <<
", LO: " << TypeNameTraits<LO>::name ()
798 <<
", GO: " << TypeNameTraits<GO>::name ()
799 <<
", NT: " << TypeNameTraits<NT>::name ();
800 if (this->getObjectLabel () !=
"") {
801 os <<
", Label: \"" << this->getObjectLabel () <<
"\"";
803 os <<
", Has Map: " << (this->
map_.is_null () ?
"false" :
"true")
812 const Teuchos::EVerbosityLevel verbLevel =
813 Teuchos::Describable::verbLevel_default)
const
816 using ::Teuchos::EVerbosityLevel;
817 using ::Teuchos::OSTab;
818 using ::Teuchos::TypeNameTraits;
819 using ::Teuchos::VERB_DEFAULT;
820 using ::Teuchos::VERB_LOW;
821 using ::Teuchos::VERB_MEDIUM;
824 const auto vl = (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
826 auto comm = this->
getMap ().is_null () ?
827 Teuchos::null : this->
getMap ()->getComm ();
828 const int myRank = comm.is_null () ? 0 : comm->getRank ();
831 if (vl != Teuchos::VERB_NONE) {
835 out <<
"\"Tpetra::Details::CooMatrix\":" << endl;
839 out <<
"Template parameters:" << endl;
842 out <<
"SC: " << TypeNameTraits<SC>::name () << endl
843 <<
"LO: " << TypeNameTraits<LO>::name () << endl
844 <<
"GO: " << TypeNameTraits<GO>::name () << endl
845 <<
"NT: " << TypeNameTraits<NT>::name () << endl;
847 if (this->getObjectLabel () !=
"") {
848 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
850 out <<
"Has Map: " << (this->
map_.is_null () ?
"false" :
"true") << endl;
854 if (! this->
map_.is_null ()) {
856 out <<
"Map:" << endl;
859 this->
map_->describe (out, vl);
864 std::ostringstream os;
865 os <<
"Process " << myRank <<
":" << endl;
869 os <<
" Local number of entries: " << numEnt << endl;
870 if (vl > VERB_MEDIUM) {
871 os <<
" Local entries:" << endl;
873 this->impl_.
forAllEntries ([&os] (
const GO row,
const GO col,
const SC& val) {
895 Teuchos::RCP<const map_type>
896 buildMap (const ::Teuchos::RCP<const ::Teuchos::Comm<int> >& comm)
898 using ::Teuchos::outArg;
899 using ::Teuchos::rcp;
900 using ::Teuchos::REDUCE_MIN;
901 using ::Teuchos::reduceAll;
906 if (comm.is_null ()) {
907 return ::Teuchos::null;
918 std::vector<GO> rowInds;
922 GO gblMinGblRowInd = 0;
923 reduceAll<int, GO> (*comm, REDUCE_MIN, lclMinGblRowInd,
924 outArg (gblMinGblRowInd));
925 const GO indexBase = gblMinGblRowInd;
926 const GST INV = Tpetra::Details::OrdinalTraits<GST>::invalid ();
927 return rcp (
new map_type (INV, rowInds.data (), rowInds.size (),
936 return static_cast<size_t> (0);
947 const char prefix[] =
"Tpetra::Details::CooMatrix::checkSizes: ";
949 const this_COO_type* src =
dynamic_cast<const this_COO_type*
> (&source);
952 std::ostream& err = markLocalErrorAndGetStream ();
953 err << prefix <<
"The source object of the Import or Export "
954 "must be a CooMatrix with the same template parameters as the "
955 "target object." << endl;
957 else if (this->
map_.is_null ()) {
958 std::ostream& err = markLocalErrorAndGetStream ();
959 err << prefix <<
"The target object of the Import or Export "
960 "must be a CooMatrix with a nonnull Map." << endl;
962 return ! (* (this->localError_));
967 typename ::Tpetra::DistObject<char, LO, GO, NT>::buffer_device_type;
971 (const ::Tpetra::SrcDistObject& sourceObject,
972 const size_t numSameIDs,
973 const Kokkos::DualView<
const LO*,
975 const Kokkos::DualView<
const LO*,
981 const char prefix[] =
"Tpetra::Details::CooMatrix::copyAndPermute: ";
986 if (* (this->localError_)) {
987 std::ostream& err = this->markLocalErrorAndGetStream ();
988 err << prefix <<
"The target object of the Import or Export is "
989 "already in an error state." << endl;
993 const this_COO_type* src =
dynamic_cast<const this_COO_type*
> (&sourceObject);
994 if (src ==
nullptr) {
995 std::ostream& err = this->markLocalErrorAndGetStream ();
996 err << prefix <<
"Input argument 'sourceObject' is not a CooMatrix."
1001 const size_t numPermuteIDs =
1002 static_cast<size_t> (permuteToLIDs.extent (0));
1003 if (numPermuteIDs !=
static_cast<size_t> (permuteFromLIDs.extent (0))) {
1004 std::ostream& err = this->markLocalErrorAndGetStream ();
1005 err << prefix <<
"permuteToLIDs.extent(0) = "
1006 << numPermuteIDs <<
" != permuteFromLIDs.extent(0) = "
1007 << permuteFromLIDs.extent (0) <<
"." << endl;
1010 if (
sizeof (
int) <=
sizeof (
size_t) &&
1011 numPermuteIDs >
static_cast<size_t> (std::numeric_limits<int>::max ())) {
1012 std::ostream& err = this->markLocalErrorAndGetStream ();
1013 err << prefix <<
"numPermuteIDs = " << numPermuteIDs
1014 <<
", a size_t, overflows int." << endl;
1021 if (
sizeof (
int) <=
sizeof (
size_t) &&
1022 numSameIDs >
static_cast<size_t> (std::numeric_limits<int>::max ())) {
1023 std::ostream& err = this->markLocalErrorAndGetStream ();
1024 err << prefix <<
"numSameIDs = " << numSameIDs
1025 <<
", a size_t, overflows int." << endl;
1032 const LO numSame =
static_cast<int> (numSameIDs);
1037 LO numInvalidSameRows = 0;
1038 for (LO lclRow = 0; lclRow < numSame; ++lclRow) {
1042 const GO gblRow = this->
map_->getGlobalElement (lclRow);
1043 if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1044 ++numInvalidSameRows;
1057 const LO numPermute =
static_cast<int> (numPermuteIDs);
1062 LO numInvalidRowsFrom = 0;
1067 LO numInvalidRowsTo = 0;
1069 TEUCHOS_ASSERT( ! permuteFromLIDs.need_sync_host () );
1070 TEUCHOS_ASSERT( ! permuteToLIDs.need_sync_host () );
1071 auto permuteFromLIDs_h = permuteFromLIDs.view_host ();
1072 auto permuteToLIDs_h = permuteToLIDs.view_host ();
1074 for (LO k = 0; k < numPermute; ++k) {
1075 const LO lclRowFrom = permuteFromLIDs_h[k];
1076 const LO lclRowTo = permuteToLIDs_h[k];
1077 const GO gblRowFrom = src->
map_->getGlobalElement (lclRowFrom);
1078 const GO gblRowTo = this->
map_->getGlobalElement (lclRowTo);
1080 bool bothConversionsValid =
true;
1081 if (gblRowFrom == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1082 ++numInvalidRowsFrom;
1083 bothConversionsValid =
false;
1085 if (gblRowTo == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1087 bothConversionsValid =
false;
1089 if (bothConversionsValid) {
1090 this->impl_.
mergeIntoRow (gblRowTo, src->impl_, gblRowFrom);
1095 if (numInvalidSameRows != 0 || numInvalidRowsFrom != 0 ||
1096 numInvalidRowsTo != 0) {
1099 std::vector<std::pair<LO, GO> > invalidSameRows;
1100 invalidSameRows.reserve (numInvalidSameRows);
1101 std::vector<std::pair<LO, GO> > invalidRowsFrom;
1102 invalidRowsFrom.reserve (numInvalidRowsFrom);
1103 std::vector<std::pair<LO, GO> > invalidRowsTo;
1104 invalidRowsTo.reserve (numInvalidRowsTo);
1106 for (LO lclRow = 0; lclRow < numSame; ++lclRow) {
1110 const GO gblRow = this->
map_->getGlobalElement (lclRow);
1111 if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1112 invalidSameRows.push_back ({lclRow, gblRow});
1116 for (LO k = 0; k < numPermute; ++k) {
1117 const LO lclRowFrom = permuteFromLIDs_h[k];
1118 const LO lclRowTo = permuteToLIDs_h[k];
1119 const GO gblRowFrom = src->
map_->getGlobalElement (lclRowFrom);
1120 const GO gblRowTo = this->
map_->getGlobalElement (lclRowTo);
1122 if (gblRowFrom == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1123 invalidRowsFrom.push_back ({lclRowFrom, gblRowFrom});
1125 if (gblRowTo == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1126 invalidRowsTo.push_back ({lclRowTo, gblRowTo});
1130 std::ostringstream os;
1131 if (numInvalidSameRows != 0) {
1132 os <<
"Invalid permute \"same\" (local, global) index pairs: [";
1133 for (std::size_t k = 0; k < invalidSameRows.size (); ++k) {
1134 const auto& p = invalidSameRows[k];
1135 os <<
"(" << p.first <<
"," << p.second <<
")";
1136 if (k + 1 < invalidSameRows.size ()) {
1140 os <<
"]" << std::endl;
1142 if (numInvalidRowsFrom != 0) {
1143 os <<
"Invalid permute \"from\" (local, global) index pairs: [";
1144 for (std::size_t k = 0; k < invalidRowsFrom.size (); ++k) {
1145 const auto& p = invalidRowsFrom[k];
1146 os <<
"(" << p.first <<
"," << p.second <<
")";
1147 if (k + 1 < invalidRowsFrom.size ()) {
1151 os <<
"]" << std::endl;
1153 if (numInvalidRowsTo != 0) {
1154 os <<
"Invalid permute \"to\" (local, global) index pairs: [";
1155 for (std::size_t k = 0; k < invalidRowsTo.size (); ++k) {
1156 const auto& p = invalidRowsTo[k];
1157 os <<
"(" << p.first <<
"," << p.second <<
")";
1158 if (k + 1 < invalidRowsTo.size ()) {
1162 os <<
"]" << std::endl;
1165 std::ostream& err = this->markLocalErrorAndGetStream ();
1166 err << prefix << os.str ();
1173 (const ::Tpetra::SrcDistObject& sourceObject,
1178 Kokkos::DualView<
size_t*,
1180 size_t& constantNumPackets)
1182 using Teuchos::Comm;
1186 const char prefix[] =
"Tpetra::Details::CooMatrix::packAndPrepare: ";
1187 const char suffix[] =
" This should never happen. "
1188 "Please report this bug to the Tpetra developers.";
1192 constantNumPackets = 0;
1194 const this_COO_type* src =
dynamic_cast<const this_COO_type*
> (&sourceObject);
1195 if (src ==
nullptr) {
1196 std::ostream& err = this->markLocalErrorAndGetStream ();
1197 err << prefix <<
"Input argument 'sourceObject' is not a CooMatrix."
1200 else if (* (src->localError_)) {
1201 std::ostream& err = this->markLocalErrorAndGetStream ();
1202 err << prefix <<
"The source (input) object of the Import or Export "
1203 "is already in an error state on this process."
1206 else if (* (this->localError_)) {
1207 std::ostream& err = this->markLocalErrorAndGetStream ();
1208 err << prefix <<
"The target (output, \"this\") object of the Import "
1209 "or Export is already in an error state on this process." << endl;
1214 if (* (this->localError_)) {
1219 auto numPacketsPerLID_tmp = numPacketsPerLID;
1220 numPacketsPerLID_tmp.sync_host ();
1221 numPacketsPerLID_tmp.modify_host ();
1224 Kokkos::deep_copy (numPacketsPerLID.view_host(),
static_cast<size_t> (0));
1228 const size_t numExports = exportLIDs.extent (0);
1229 if (numExports == 0) {
1233 RCP<const Comm<int> > comm = src->
getMap ().is_null () ?
1234 Teuchos::null : src->getMap ()->getComm ();
1235 if (comm.is_null () || comm->getSize () == 1) {
1236 if (numExports !=
static_cast<size_t> (0)) {
1237 std::ostream& err = this->markLocalErrorAndGetStream ();
1238 err << prefix <<
"The input communicator is either null or "
1239 "has only one process, but numExports = " << numExports <<
" != 0."
1250 numPacketsPerLID.sync_host ();
1251 numPacketsPerLID.modify_host ();
1253 TEUCHOS_ASSERT( ! exportLIDs.need_sync_host () );
1254 auto exportLIDs_h = exportLIDs.view_host ();
1256 int totalNumPackets = 0;
1257 size_t numInvalidRowInds = 0;
1258 std::ostringstream errStrm;
1259 for (
size_t k = 0; k < numExports; ++k) {
1260 const LO lclRow = exportLIDs_h[k];
1263 const GO gblRow = src->
map_->getGlobalElement (lclRow);
1264 if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1266 ++numInvalidRowInds;
1267 numPacketsPerLID.view_host()[k] = 0;
1275 src->impl_.countPackRow (numPackets, gblRow, *comm, &errStrm);
1277 std::ostream& err = this->markLocalErrorAndGetStream ();
1278 err << prefix << errStrm.str () << endl;
1279 numPacketsPerLID.view_host()[k] = 0;
1285 const long long newTotalNumPackets =
1286 static_cast<long long> (totalNumPackets) +
1287 static_cast<long long> (numPackets);
1288 if (newTotalNumPackets >
1289 static_cast<long long> (std::numeric_limits<int>::max ())) {
1290 std::ostream& err = this->markLocalErrorAndGetStream ();
1291 err << prefix <<
"The new total number of packets "
1292 << newTotalNumPackets <<
" does not fit in int." << endl;
1296 for (
size_t k2 = k; k2 < numExports; ++k2) {
1297 numPacketsPerLID.view_host()[k2] = 0;
1301 numPacketsPerLID.view_host()[k] =
static_cast<size_t> (numPackets);
1302 totalNumPackets =
static_cast<int> (newTotalNumPackets);
1307 if (numInvalidRowInds != 0) {
1308 std::vector<std::pair<LO, GO> > invalidRowInds;
1309 for (
size_t k = 0; k < numExports; ++k) {
1310 const LO lclRow = exportLIDs_h[k];
1314 const GO gblRow = src->
map_->getGlobalElement (lclRow);
1315 if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1316 invalidRowInds.push_back ({lclRow, gblRow});
1319 std::ostringstream os;
1320 os << prefix <<
"We found " << numInvalidRowInds <<
" invalid row ind"
1321 << (numInvalidRowInds !=
static_cast<size_t> (1) ?
"ices" :
"ex")
1322 <<
" out of " << numExports <<
" in exportLIDs. Here is the list "
1323 <<
" of invalid row indices: [";
1324 for (
size_t k = 0; k < invalidRowInds.size (); ++k) {
1325 os <<
"(LID: " << invalidRowInds[k].first <<
", GID: "
1326 << invalidRowInds[k].second <<
")";
1327 if (k + 1 < invalidRowInds.size ()) {
1333 std::ostream& err = this->markLocalErrorAndGetStream ();
1334 err << prefix << os.str () << std::endl;
1339 const bool reallocated =
1341 "CooMatrix exports");
1343 exports.sync_host ();
1346 exports.modify_host ();
1350 std::vector<GO> gblRowInds;
1351 std::vector<GO> gblColInds;
1352 std::vector<SC> vals;
1354 int outBufCurPos = 0;
1355 packet_type* outBuf = exports.view_host().data ();
1356 for (
size_t k = 0; k < numExports; ++k) {
1357 const LO lclRow = exportLIDs.view_host()[k];
1360 const GO gblRow = src->
map_->getGlobalElement (lclRow);
1362 src->impl_.packRow (outBuf, totalNumPackets, outBufCurPos, *comm,
1363 gblRowInds, gblColInds, vals, gblRow);
1369 (
const Kokkos::DualView<
const local_ordinal_type*,
1373 Kokkos::DualView<
size_t*,
1376 const ::Tpetra::CombineMode )
1378 using Teuchos::Comm;
1381 const char prefix[] =
"Tpetra::Details::CooMatrix::unpackAndCombine: ";
1382 const char suffix[] =
" This should never happen. "
1383 "Please report this bug to the Tpetra developers.";
1385 TEUCHOS_ASSERT( ! importLIDs.need_sync_host () );
1386 auto importLIDs_h = importLIDs.view_host ();
1388 const std::size_t numImports = importLIDs.extent (0);
1389 if (numImports == 0) {
1392 else if (imports.extent (0) == 0) {
1393 std::ostream& err = this->markLocalErrorAndGetStream ();
1394 err << prefix <<
"importLIDs.extent(0) = " << numImports <<
" != 0, "
1395 <<
"but imports.extent(0) = 0. This doesn't make sense, because "
1396 <<
"for every incoming LID, CooMatrix packs at least the count of "
1397 <<
"triples associated with that LID, even if the count is zero. "
1398 <<
"importLIDs = [";
1399 for (std::size_t k = 0; k < numImports; ++k) {
1400 err << importLIDs_h[k];
1401 if (k + 1 < numImports) {
1405 err <<
"]. " << suffix << endl;
1409 RCP<const Comm<int> > comm = this->
getMap ().is_null () ?
1410 Teuchos::null : this->
getMap ()->getComm ();
1411 if (comm.is_null () || comm->getSize () == 1) {
1412 if (numImports !=
static_cast<size_t> (0)) {
1413 std::ostream& err = this->markLocalErrorAndGetStream ();
1414 err << prefix <<
"The input communicator is either null or "
1415 "has only one process, but numImports = " << numImports <<
" != 0."
1428 if (
static_cast<size_t> (imports.extent (0)) >
1429 static_cast<size_t> (std::numeric_limits<int>::max ())) {
1430 std::ostream& err = this->markLocalErrorAndGetStream ();
1431 err << prefix <<
"imports.extent(0) = "
1432 << imports.extent (0) <<
" does not fit in int." << endl;
1435 const int inBufSize =
static_cast<int> (imports.extent (0));
1437 if (imports.need_sync_host ()) {
1438 imports.sync_host ();
1440 if (numPacketsPerLID.need_sync_host ()) {
1441 numPacketsPerLID.sync_host ();
1443 auto imports_h = imports.view_host ();
1444 auto numPacketsPerLID_h = numPacketsPerLID.view_host ();
1448 std::vector<GO> gblRowInds;
1449 std::vector<GO> gblColInds;
1450 std::vector<SC> vals;
1453 int inBufCurPos = 0;
1454 size_t numInvalidRowInds = 0;
1456 std::ostringstream errStrm;
1457 for (
size_t k = 0; k < numImports; ++k) {
1458 const LO lclRow = importLIDs_h(k);
1459 const GO gblRow = this->
map_->getGlobalElement (lclRow);
1460 if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1461 ++numInvalidRowInds;
1467 const int origInBufCurPos = inBufCurPos;
1471 numEnt, *comm, &errStrm);
1472 if (errCode != 0 || numEnt < 0 || inBufCurPos < origInBufCurPos) {
1473 std::ostream& err = this->markLocalErrorAndGetStream ();
1475 err << prefix <<
"In unpack loop, k=" << k <<
": ";
1477 err <<
" unpackTriplesCount returned errCode = " << errCode
1478 <<
" != 0." << endl;
1481 err <<
" unpackTriplesCount returned errCode = 0, but numEnt = "
1482 << numEnt <<
" < 0." << endl;
1484 if (inBufCurPos < origInBufCurPos) {
1485 err <<
" After unpackTriplesCount, inBufCurPos = " << inBufCurPos
1486 <<
" < origInBufCurPos = " << origInBufCurPos <<
"." << endl;
1488 err <<
" unpackTriplesCount report: " << errStrm.str () << endl;
1489 err << suffix << endl;
1496#ifdef HAVE_TPETRA_DEBUG
1508 gblRowInds.resize (numEnt);
1509 gblColInds.resize (numEnt);
1510 vals.resize (numEnt);
1513 gblRowInds.data (), gblColInds.data (),
1514 vals.data (), numEnt, *comm, &errStrm);
1516 std::ostream& err = this->markLocalErrorAndGetStream ();
1517 err << prefix <<
"unpackTriples returned errCode = "
1518 << errCode <<
" != 0. It reports: " << errStrm.str ()
1525#ifdef HAVE_TPETRA_DEBUG
1535 vals.data (), numEnt);
1540 if (numInvalidRowInds != 0) {
1544 std::ostream& err = this->markLocalErrorAndGetStream ();
1546 std::vector<std::pair<LO, GO> > invalidRowInds;
1547 for (
size_t k = 0; k < numImports; ++k) {
1548 const LO lclRow = importLIDs_h(k);
1549 const GO gblRow = this->
map_->getGlobalElement (lclRow);
1550 if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid ()) {
1551 invalidRowInds.push_back ({lclRow, gblRow});
1555 err << prefix <<
"We found " << numInvalidRowInds <<
" invalid row ind"
1556 << (numInvalidRowInds !=
static_cast<size_t> (1) ?
"ices" :
"ex")
1557 <<
" out of " << numImports <<
" in importLIDs. Here is the list "
1558 <<
" of invalid row indices: [";
1559 for (
size_t k = 0; k < invalidRowInds.size (); ++k) {
1560 err <<
"(LID: " << invalidRowInds[k].first <<
", GID: "
1561 << invalidRowInds[k].second <<
")";
1562 if (k + 1 < invalidRowInds.size ()) {