1 #ifndef TPETRA_DETAILS_MAKECOLMAP_DEF_HPP
2 #define TPETRA_DETAILS_MAKECOLMAP_DEF_HPP
56 #include "Tpetra_RowGraph.hpp"
58 #include "Teuchos_Array.hpp"
65 template <
class LO,
class GO,
class NT>
68 Teuchos::Array<int>& remotePIDs,
71 const bool sortEachProcsGids,
72 std::ostream* errStrm)
75 using Teuchos::ArrayView;
78 typedef ::Tpetra::Map<LO, GO, NT> map_type;
79 const char prefix[] =
"Tpetra::Details::makeColMap: ";
89 if (domMap.is_null () || domMap->getComm ().is_null ()) {
90 colMap = Teuchos::null;
103 if (colMap.is_null () || ! graph.
hasColMap ()) {
105 if (errStrm != NULL) {
106 *errStrm << prefix <<
"The graph is locally indexed on the calling "
107 "process, but has no column Map (either getColMap() returns null, "
108 "or hasColMap() returns false)." << endl;
120 if (colMap->isContiguous ()) {
122 const LO numCurGids =
static_cast<LO
> (colMap->getNodeNumElements ());
123 myColumns.resize (numCurGids);
124 const GO myFirstGblInd = colMap->getMinGlobalIndex ();
125 for (LO k = 0; k < numCurGids; ++k) {
126 myColumns[k] = myFirstGblInd +
static_cast<GO
> (k);
130 ArrayView<const GO> curGids = graph.
getColMap ()->getNodeElementList ();
132 const LO numCurGids =
static_cast<LO
> (curGids.size ());
133 myColumns.resize (numCurGids);
134 for (LO k = 0; k < numCurGids; ++k) {
135 myColumns[k] = curGids[k];
164 const LO LINV = Tpetra::Details::OrdinalTraits<LO>::invalid ();
165 size_t numLocalColGIDs = 0;
166 size_t numRemoteColGIDs = 0;
170 std::vector<bool> GIDisLocal (domMap->getNodeNumElements (),
false);
171 std::set<GO> RemoteGIDSet;
174 std::vector<GO> RemoteGIDUnorderedVector;
179 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
181 Teuchos::ArrayView<const GO> rowGids;
184 const LO numEnt =
static_cast<LO
> (rowGids.size ());
186 for (LO k = 0; k < numEnt; ++k) {
187 const GO gid = rowGids[k];
188 const LO lid = domMap->getLocalElement (gid);
190 const bool alreadyFound = GIDisLocal[lid];
191 if (! alreadyFound) {
192 GIDisLocal[lid] =
true;
197 const bool notAlreadyFound = RemoteGIDSet.insert (gid).second;
198 if (notAlreadyFound) {
199 if (! sortEachProcsGids) {
206 RemoteGIDUnorderedVector.push_back (gid);
245 if (domMap->getComm ()->getSize () == 1) {
246 if (numRemoteColGIDs != 0) {
248 if (errStrm != NULL) {
249 *errStrm << prefix <<
"The domain Map only has one process, but "
250 << numRemoteColGIDs <<
" column "
251 << (numRemoteColGIDs != 1 ?
"indices are" :
"index is")
252 <<
" not in the domain Map. Either these indices are "
253 "invalid or the domain Map is invalid. Remember that nonsquare "
254 "matrices, or matrices where the row and range Maps differ, "
255 "require calling the version of fillComplete that takes the "
256 "domain and range Maps as input." << endl;
259 if (numLocalColGIDs == domMap->getNodeNumElements ()) {
269 myColumns.resize (numLocalColGIDs + numRemoteColGIDs);
271 ArrayView<GO> LocalColGIDs = myColumns (0, numLocalColGIDs);
272 ArrayView<GO> remoteColGIDs = myColumns (numLocalColGIDs, numRemoteColGIDs);
275 if (sortEachProcsGids) {
277 std::copy (RemoteGIDSet.begin(), RemoteGIDSet.end(),
278 remoteColGIDs.begin());
282 std::copy (RemoteGIDUnorderedVector.begin(),
283 RemoteGIDUnorderedVector.end(), remoteColGIDs.begin());
289 if (static_cast<size_t> (remotePIDs.size ()) != numRemoteColGIDs) {
290 remotePIDs.resize (numRemoteColGIDs);
295 domMap->getRemoteIndexList (remoteColGIDs, remotePIDs ());
305 if (errStrm != NULL) {
306 *errStrm << prefix <<
"Some column indices are not in the domain Map."
307 "Either these column indices are invalid or the domain Map is "
308 "invalid. Likely cause: For a nonsquare matrix, you must give the "
309 "domain and range Maps as input to fillComplete." << endl;
328 sort2 (remotePIDs.begin (), remotePIDs.end (), remoteColGIDs.begin ());
340 const size_t numDomainElts = domMap->getNodeNumElements ();
341 if (numLocalColGIDs == numDomainElts) {
345 if (domMap->isContiguous ()) {
350 GO curColMapGid = domMap->getMinGlobalIndex ();
351 for (
size_t k = 0; k < numLocalColGIDs; ++k, ++curColMapGid) {
352 LocalColGIDs[k] = curColMapGid;
356 ArrayView<const GO> domainElts = domMap->getNodeElementList ();
357 std::copy (domainElts.begin(), domainElts.end(), LocalColGIDs.begin());
363 size_t numLocalCount = 0;
364 if (domMap->isContiguous ()) {
369 GO curColMapGid = domMap->getMinGlobalIndex ();
370 for (
size_t i = 0; i < numDomainElts; ++i, ++curColMapGid) {
372 LocalColGIDs[numLocalCount++] = curColMapGid;
377 ArrayView<const GO> domainElts = domMap->getNodeElementList ();
378 for (
size_t i = 0; i < numDomainElts; ++i) {
380 LocalColGIDs[numLocalCount++] = domainElts[i];
384 if (numLocalCount != numLocalColGIDs) {
385 if (errStrm != NULL) {
386 *errStrm << prefix <<
"numLocalCount = " << numLocalCount
387 <<
" != numLocalColGIDs = " << numLocalColGIDs
388 <<
". This should never happen. "
389 "Please report this bug to the Tpetra developers." << endl;
454 Tpetra::Details::OrdinalTraits<global_size_t>::invalid ();
459 const GO indexBase = domMap->getIndexBase ();
460 colMap = rcp (
new map_type (INV, myColumns, indexBase, domMap->getComm ()));
472 #define TPETRA_DETAILS_MAKECOLMAP_INSTANT(LO,GO,NT) template int makeColMap (Teuchos::RCP<const Tpetra::Map<LO, GO, NT> >&, Teuchos::Array<int>&, const Teuchos::RCP<const Tpetra::Map<LO, GO, NT> >&, const RowGraph<LO, GO, NT>&, const bool, std::ostream*);
474 #endif // TPETRA_DETAILS_MAKECOLMAP_DEF_HPP
virtual bool hasColMap() const =0
Whether the graph has a well-defined column Map.
An abstract interface for graphs accessed by rows.
virtual void getGlobalRowView(const GlobalOrdinal gblRow, Teuchos::ArrayView< const GlobalOrdinal > &gblColInds) const
Get a const, non-persisting view of the given global row's global column indices, as a Teuchos::Array...
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getColMap() const =0
The Map that describes this graph's distribution of columns over processes.
size_t global_size_t
Global size_t object.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getRowMap() const =0
The Map that describes this graph's distribution of rows over processes.
GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
virtual bool isGloballyIndexed() const =0
If graph indices are in the global range, this function returns true. Otherwise, this function return...
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
A parallel distribution of indices over processes.
int makeColMap(Teuchos::RCP< const Tpetra::Map< LO, GO, NT > > &colMap, Teuchos::Array< int > &remotePIDs, const Teuchos::RCP< const Tpetra::Map< LO, GO, NT > > &domMap, const RowGraph< LO, GO, NT > &graph, const bool sortEachProcsGids=true, std::ostream *errStrm=NULL)
Make the graph's column Map.
Stand-alone utility functions and macros.
virtual bool isLocallyIndexed() const =0
If graph indices are in the local range, this function returns true. Otherwise, this function returns...