531  typedef LO local_ordinal_type;
 
  532  typedef GO global_ordinal_type;
 
  534  typedef typename NT::device_type device_type;
 
  536  typedef ::Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> 
map_type;
 
  600                      const std::size_t 
numEnt) {
 
 
  608                      std::initializer_list<SC> 
vals,
 
  609                      const std::size_t 
numEnt) {
 
 
  620  template <
class OffsetType>
 
  622  buildCrs(::Kokkos::View<OffsetType*, device_type>& 
rowOffsets,
 
  625           ::Kokkos::View<typename ::KokkosKernels::ArithTraits<SC>::val_type*, device_type>& 
vals) {
 
  627           ::Kokkos::View<typename ::Kokkos::ArithTraits<SC>::val_type*, device_type>& 
vals) {
 
  629    static_assert(std::is_integral<OffsetType>::value,
 
  630                  "OffsetType must be a built-in integer type.");
 
  631    using ::Kokkos::create_mirror_view;
 
  632    using ::Kokkos::deep_copy;
 
  633    using ::Kokkos::View;
 
  634#if KOKKOS_VERSION >= 40799 
  635    typedef typename ::KokkosKernels::ArithTraits<SC>::val_type 
ISC;
 
  637    typedef typename ::Kokkos::ArithTraits<SC>::val_type 
ISC;
 
  672  fillComplete(const ::Teuchos::RCP<const ::Teuchos::Comm<int> >& comm) {
 
  673    if (comm.is_null()) {
 
  674      this->
map_ = ::Teuchos::null;
 
  676      this->
map_ = this->buildMap(comm);
 
 
  692                               "CooMatrix::fillComplete: This object does not yet have a Map.  " 
  693                               "You must call the version of fillComplete " 
  694                               "that takes an input communicator.");
 
 
  734    return ((*errs_).get() == 
NULL) ? std::string(
"") : (*errs_)->str();
 
 
  750  std::shared_ptr<bool> localError_;
 
  759  std::shared_ptr<std::shared_ptr<std::ostringstream> > errs_;
 
  763  markLocalErrorAndGetStream() {
 
  764    *(this->localError_) = 
true;
 
  765    if ((*errs_).get() == 
NULL) {
 
  766      *errs_ = std::shared_ptr<std::ostringstream>(
new std::ostringstream());
 
  775    using Teuchos::TypeNameTraits;
 
  777    std::ostringstream 
os;
 
  778    os << 
"\"Tpetra::Details::CooMatrix\": {" 
  786    os << 
", Has Map: " << (this->
map_.is_null() ? 
"false" : 
"true")
 
 
  795           const Teuchos::EVerbosityLevel 
verbLevel =
 
  796               Teuchos::Describable::verbLevel_default)
 const {
 
  798    using ::Teuchos::EVerbosityLevel;
 
  799    using ::Teuchos::OSTab;
 
  800    using ::Teuchos::TypeNameTraits;
 
  801    using ::Teuchos::VERB_DEFAULT;
 
  802    using ::Teuchos::VERB_LOW;
 
  803    using ::Teuchos::VERB_MEDIUM;
 
  804    using ::Tpetra::Details::gathervPrint;
 
  808    auto comm        = this->
getMap().is_null() ? Teuchos::null : this->
getMap()->getComm();
 
  809    const int myRank = comm.is_null() ? 0 : comm->getRank();
 
  812    if (
vl != Teuchos::VERB_NONE) {
 
  816        out << 
"\"Tpetra::Details::CooMatrix\":" << 
endl;
 
  820        out << 
"Template parameters:" << 
endl;
 
  831        out << 
"Has Map: " << (this->
map_.is_null() ? 
"false" : 
"true") << endl;
 
  835      if (!this->
map_.is_null()) {
 
  840        this->
map_->describe(out, 
vl);
 
  845        std::ostringstream 
os;
 
  852          os << 
" Local entries:" << 
endl;
 
 
  876  Teuchos::RCP<const map_type>
 
  877  buildMap(const ::Teuchos::RCP<const ::Teuchos::Comm<int> >& comm) {
 
  878    using ::Teuchos::outArg;
 
  879    using ::Teuchos::rcp;
 
  880    using ::Teuchos::REDUCE_MIN;
 
  881    using ::Teuchos::reduceAll;
 
  886    if (comm.is_null()) {
 
  887      return ::Teuchos::null;
 
  906    const GST INV      = Tpetra::Details::OrdinalTraits<GST>::invalid();
 
  916    return static_cast<size_t>(0);
 
 
  926    const char prefix[] = 
"Tpetra::Details::CooMatrix::checkSizes: ";
 
  931      std::ostream& 
err = markLocalErrorAndGetStream();
 
  932      err << 
prefix << 
"The source object of the Import or Export " 
  933                       "must be a CooMatrix with the same template parameters as the " 
  936    } 
else if (this->
map_.is_null()) {
 
  937      std::ostream& 
err = markLocalErrorAndGetStream();
 
  938      err << 
prefix << 
"The target object of the Import or Export " 
  939                       "must be a CooMatrix with a nonnull Map." 
  942    return !(*(this->localError_));
 
 
  947      typename ::Tpetra::DistObject<char, LO, GO, NT>::buffer_device_type;
 
  950  copyAndPermute(const ::Tpetra::SrcDistObject& 
sourceObject,
 
  951                 const size_t numSameIDs,
 
  952                 const Kokkos::DualView<
const LO*,
 
  954                 const Kokkos::DualView<
const LO*,
 
  959    const char prefix[] = 
"Tpetra::Details::CooMatrix::copyAndPermute: ";
 
  964    if (*(this->localError_)) {
 
  965      std::ostream& 
err = this->markLocalErrorAndGetStream();
 
  966      err << 
prefix << 
"The target object of the Import or Export is " 
  967                       "already in an error state." 
  973    if (src == 
nullptr) {
 
  974      std::ostream& 
err = this->markLocalErrorAndGetStream();
 
  975      err << 
prefix << 
"Input argument 'sourceObject' is not a CooMatrix." 
  983      std::ostream& 
err = this->markLocalErrorAndGetStream();
 
  984      err << 
prefix << 
"permuteToLIDs.extent(0) = " 
  989    if (
sizeof(
int) <= 
sizeof(
size_t) &&
 
  990        numPermuteIDs > 
static_cast<size_t>(std::numeric_limits<int>::max())) {
 
  991      std::ostream& 
err = this->markLocalErrorAndGetStream();
 
  993          << 
", a size_t, overflows int." << 
endl;
 
 1000    if (
sizeof(
int) <= 
sizeof(
size_t) &&
 
 1001        numSameIDs > 
static_cast<size_t>(std::numeric_limits<int>::max())) {
 
 1002      std::ostream& 
err = this->markLocalErrorAndGetStream();
 
 1003      err << 
prefix << 
"numSameIDs = " << numSameIDs
 
 1004          << 
", a size_t, overflows int." << 
endl;
 
 1011    const LO 
numSame = 
static_cast<int>(numSameIDs);
 
 1022      if (
gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1056      const GO 
gblRowTo   = this->
map_->getGlobalElement(lclRowTo);
 
 1059      if (
gblRowFrom == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1063      if (
gblRowTo == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1089        if (
gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1098        const GO 
gblRowTo   = this->
map_->getGlobalElement(lclRowTo);
 
 1100        if (
gblRowFrom == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1103        if (
gblRowTo == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1108      std::ostringstream 
os;
 
 1110        os << 
"Invalid permute \"same\" (local, global) index pairs: [";
 
 1113          os << 
"(" << 
p.first << 
"," << 
p.second << 
")";
 
 1118        os << 
"]" << std::endl;
 
 1121        os << 
"Invalid permute \"from\" (local, global) index pairs: [";
 
 1124          os << 
"(" << 
p.first << 
"," << 
p.second << 
")";
 
 1129        os << 
"]" << std::endl;
 
 1132        os << 
"Invalid permute \"to\" (local, global) index pairs: [";
 
 1135          os << 
"(" << 
p.first << 
"," << 
p.second << 
")";
 
 1140        os << 
"]" << std::endl;
 
 1143      std::ostream& 
err = this->markLocalErrorAndGetStream();
 
 1150  packAndPrepare(const ::Tpetra::SrcDistObject& 
sourceObject,
 
 1151                 const Kokkos::DualView<
const local_ordinal_type*,
 
 1155                 Kokkos::DualView<
size_t*,
 
 1160    using Teuchos::Comm;
 
 1163    const char prefix[] = 
"Tpetra::Details::CooMatrix::packAndPrepare: ";
 
 1165        "  This should never happen.  " 
 1166        "Please report this bug to the Tpetra developers.";
 
 1173    if (src == 
nullptr) {
 
 1174      std::ostream& 
err = this->markLocalErrorAndGetStream();
 
 1175      err << 
prefix << 
"Input argument 'sourceObject' is not a CooMatrix." 
 1177    } 
else if (*(src->localError_)) {
 
 1178      std::ostream& 
err = this->markLocalErrorAndGetStream();
 
 1179      err << 
prefix << 
"The source (input) object of the Import or Export " 
 1180                       "is already in an error state on this process." 
 1182    } 
else if (*(this->localError_)) {
 
 1183      std::ostream& err = this->markLocalErrorAndGetStream();
 
 1184      err << prefix << 
"The target (output, \"this\") object of the Import " 
 1185                       "or Export is already in an error state on this process." 
 1191    if (*(this->localError_)) {
 
 1196        auto numPacketsPerLID_tmp = numPacketsPerLID;
 
 1197        numPacketsPerLID_tmp.sync_host();
 
 1198        numPacketsPerLID_tmp.modify_host();
 
 1201      Kokkos::deep_copy(numPacketsPerLID.view_host(), 
static_cast<size_t>(0));
 
 1205    const size_t numExports = exportLIDs.extent(0);
 
 1206    if (numExports == 0) {
 
 1210    RCP<const Comm<int> > comm = src->getMap().is_null() ? Teuchos::null : src->getMap()->getComm();
 
 1211    if (comm.is_null() || comm->getSize() == 1) {
 
 1212      if (numExports != 
static_cast<size_t>(0)) {
 
 1213        std::ostream& err = this->markLocalErrorAndGetStream();
 
 1214        err << prefix << 
"The input communicator is either null or " 
 1215                         "has only one process, but numExports = " 
 1216            << numExports << 
" != 0." 
 1227    numPacketsPerLID.sync_host();
 
 1228    numPacketsPerLID.modify_host();
 
 1230    TEUCHOS_ASSERT(!exportLIDs.need_sync_host());
 
 1231    auto exportLIDs_h = exportLIDs.view_host();
 
 1233    int totalNumPackets      = 0;
 
 1234    size_t numInvalidRowInds = 0;
 
 1235    std::ostringstream errStrm;  
 
 1236    for (
size_t k = 0; k < numExports; ++k) {
 
 1237      const LO lclRow = exportLIDs_h[k];
 
 1240      const GO gblRow = src->map_->getGlobalElement(lclRow);
 
 1241      if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1243        ++numInvalidRowInds;
 
 1244        numPacketsPerLID.view_host()[k] = 0;
 
 1252          src->impl_.countPackRow(numPackets, gblRow, *comm, &errStrm);
 
 1254        std::ostream& err = this->markLocalErrorAndGetStream();
 
 1255        err << prefix << errStrm.str() << endl;
 
 1256        numPacketsPerLID.view_host()[k] = 0;
 
 1262      const long long newTotalNumPackets =
 
 1263          static_cast<long long>(totalNumPackets) +
 
 1264          static_cast<long long>(numPackets);
 
 1265      if (newTotalNumPackets >
 
 1266          static_cast<long long>(std::numeric_limits<int>::max())) {
 
 1267        std::ostream& err = this->markLocalErrorAndGetStream();
 
 1268        err << prefix << 
"The new total number of packets " 
 1269            << newTotalNumPackets << 
" does not fit in int." << endl;
 
 1273        for (
size_t k2 = k; k2 < numExports; ++k2) {
 
 1274          numPacketsPerLID.view_host()[k2] = 0;
 
 1278      numPacketsPerLID.view_host()[k] = 
static_cast<size_t>(numPackets);
 
 1279      totalNumPackets                 = 
static_cast<int>(newTotalNumPackets);
 
 1284    if (numInvalidRowInds != 0) {
 
 1285      std::vector<std::pair<LO, GO> > invalidRowInds;
 
 1286      for (
size_t k = 0; k < numExports; ++k) {
 
 1287        const LO lclRow = exportLIDs_h[k];
 
 1291        const GO gblRow = src->map_->getGlobalElement(lclRow);
 
 1292        if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1293          invalidRowInds.push_back({lclRow, gblRow});
 
 1296      std::ostringstream os;
 
 1297      os << prefix << 
"We found " << numInvalidRowInds << 
" invalid row ind" 
 1298         << (numInvalidRowInds != 
static_cast<size_t>(1) ? 
"ices" : 
"ex")
 
 1299         << 
" out of " << numExports << 
" in exportLIDs.  Here is the list " 
 1300         << 
" of invalid row indices: [";
 
 1301      for (
size_t k = 0; k < invalidRowInds.size(); ++k) {
 
 1302        os << 
"(LID: " << invalidRowInds[k].first << 
", GID: " 
 1303           << invalidRowInds[k].second << 
")";
 
 1304        if (k + 1 < invalidRowInds.size()) {
 
 1310      std::ostream& err = this->markLocalErrorAndGetStream();
 
 1311      err << prefix << os.str() << std::endl;
 
 1316      const bool reallocated =
 
 1318                                           "CooMatrix exports");
 
 1320        exports.sync_host();  
 
 1323    exports.modify_host();
 
 1327    std::vector<GO> gblRowInds;
 
 1328    std::vector<GO> gblColInds;
 
 1329    std::vector<SC> vals;
 
 1331    int outBufCurPos    = 0;
 
 1333    for (
size_t k = 0; k < numExports; ++k) {
 
 1334      const LO lclRow = exportLIDs.view_host()[k];
 
 1337      const GO gblRow = src->map_->getGlobalElement(lclRow);
 
 1339      src->impl_.packRow(outBuf, totalNumPackets, outBufCurPos, *comm,
 
 1340                         gblRowInds, gblColInds, vals, gblRow);
 
 1345  unpackAndCombine(
const Kokkos::DualView<
const local_ordinal_type*,
 
 1350                   Kokkos::DualView<
size_t*,
 
 1354                   const ::Tpetra::CombineMode ) {
 
 1356    using Teuchos::Comm;
 
 1358    const char prefix[] = 
"Tpetra::Details::CooMatrix::unpackAndCombine: ";
 
 1359    const char suffix[] =
 
 1360        "  This should never happen.  " 
 1361        "Please report this bug to the Tpetra developers.";
 
 1363    TEUCHOS_ASSERT(!importLIDs.need_sync_host());
 
 1364    auto importLIDs_h = importLIDs.view_host();
 
 1366    const std::size_t numImports = importLIDs.extent(0);
 
 1367    if (numImports == 0) {
 
 1369    } 
else if (imports.extent(0) == 0) {
 
 1370      std::ostream& err = this->markLocalErrorAndGetStream();
 
 1371      err << prefix << 
"importLIDs.extent(0) = " << numImports << 
" != 0, " 
 1372          << 
"but imports.extent(0) = 0.  This doesn't make sense, because " 
 1373          << 
"for every incoming LID, CooMatrix packs at least the count of " 
 1374          << 
"triples associated with that LID, even if the count is zero.  " 
 1375          << 
"importLIDs = [";
 
 1376      for (std::size_t k = 0; k < numImports; ++k) {
 
 1377        err << importLIDs_h[k];
 
 1378        if (k + 1 < numImports) {
 
 1382      err << 
"].  " << suffix << endl;
 
 1386    RCP<const Comm<int> > comm = this->
getMap().is_null() ? Teuchos::null : this->
getMap()->getComm();
 
 1387    if (comm.is_null() || comm->getSize() == 1) {
 
 1388      if (numImports != 
static_cast<size_t>(0)) {
 
 1389        std::ostream& err = this->markLocalErrorAndGetStream();
 
 1390        err << prefix << 
"The input communicator is either null or " 
 1391                         "has only one process, but numImports = " 
 1392            << numImports << 
" != 0." 
 1405    if (
static_cast<size_t>(imports.extent(0)) >
 
 1406        static_cast<size_t>(std::numeric_limits<int>::max())) {
 
 1407      std::ostream& err = this->markLocalErrorAndGetStream();
 
 1408      err << prefix << 
"imports.extent(0) = " 
 1409          << imports.extent(0) << 
" does not fit in int." << endl;
 
 1412    const int inBufSize = 
static_cast<int>(imports.extent(0));
 
 1414    if (imports.need_sync_host()) {
 
 1415      imports.sync_host();
 
 1417    if (numPacketsPerLID.need_sync_host()) {
 
 1418      numPacketsPerLID.sync_host();
 
 1420    auto imports_h          = imports.view_host();
 
 1421    auto numPacketsPerLID_h = numPacketsPerLID.view_host();
 
 1425    std::vector<GO> gblRowInds;
 
 1426    std::vector<GO> gblColInds;
 
 1427    std::vector<SC> vals;
 
 1430    int inBufCurPos          = 0;
 
 1431    size_t numInvalidRowInds = 0;
 
 1433    std::ostringstream errStrm;  
 
 1434    for (
size_t k = 0; k < numImports; ++k) {
 
 1435      const LO lclRow = importLIDs_h(k);
 
 1436      const GO gblRow = this->
map_->getGlobalElement(lclRow);
 
 1437      if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1438        ++numInvalidRowInds;
 
 1444      const int origInBufCurPos = inBufCurPos;
 
 1448                                      numEnt, *comm, &errStrm);
 
 1449      if (errCode != 0 || numEnt < 0 || inBufCurPos < origInBufCurPos) {
 
 1450        std::ostream& err = this->markLocalErrorAndGetStream();
 
 1452        err << prefix << 
"In unpack loop, k=" << k << 
": ";
 
 1454          err << 
"  unpackTriplesCount returned errCode = " << errCode
 
 1455              << 
" != 0." << endl;
 
 1458          err << 
"  unpackTriplesCount returned errCode = 0, but numEnt = " 
 1459              << numEnt << 
" < 0." << endl;
 
 1461        if (inBufCurPos < origInBufCurPos) {
 
 1462          err << 
"  After unpackTriplesCount, inBufCurPos = " << inBufCurPos
 
 1463              << 
" < origInBufCurPos = " << origInBufCurPos << 
"." << endl;
 
 1465        err << 
"  unpackTriplesCount report: " << errStrm.str() << endl;
 
 1466        err << suffix << endl;
 
 1473#ifdef HAVE_TPETRA_DEBUG 
 1485      gblRowInds.resize(numEnt);
 
 1486      gblColInds.resize(numEnt);
 
 1487      vals.resize(numEnt);
 
 1490                              gblRowInds.data(), gblColInds.data(),
 
 1491                              vals.data(), numEnt, *comm, &errStrm);
 
 1493        std::ostream& err = this->markLocalErrorAndGetStream();
 
 1494        err << prefix << 
"unpackTriples returned errCode = " 
 1495            << errCode << 
" != 0.  It reports: " << errStrm.str()
 
 1502#ifdef HAVE_TPETRA_DEBUG 
 1512                                vals.data(), numEnt);
 
 1517    if (numInvalidRowInds != 0) {
 
 1521      std::ostream& err = this->markLocalErrorAndGetStream();
 
 1523      std::vector<std::pair<LO, GO> > invalidRowInds;
 
 1524      for (
size_t k = 0; k < numImports; ++k) {
 
 1525        const LO lclRow = importLIDs_h(k);
 
 1526        const GO gblRow = this->
map_->getGlobalElement(lclRow);
 
 1527        if (gblRow == ::Tpetra::Details::OrdinalTraits<GO>::invalid()) {
 
 1528          invalidRowInds.push_back({lclRow, gblRow});
 
 1532      err << prefix << 
"We found " << numInvalidRowInds << 
" invalid row ind" 
 1533          << (numInvalidRowInds != 
static_cast<size_t>(1) ? 
"ices" : 
"ex")
 
 1534          << 
" out of " << numImports << 
" in importLIDs.  Here is the list " 
 1535          << 
" of invalid row indices: [";
 
 1536      for (
size_t k = 0; k < invalidRowInds.size(); ++k) {
 
 1537        err << 
"(LID: " << invalidRowInds[k].first << 
", GID: " 
 1538            << invalidRowInds[k].second << 
")";
 
 1539        if (k + 1 < invalidRowInds.size()) {