2 #ifndef DUNE_REMOTEINDICES_HH
3 #define DUNE_REMOTEINDICES_HH
34 template<
typename TG,
typename TA>
38 inline static MPI_Datatype
getType();
40 static MPI_Datatype type;
44 template<
typename T,
typename A>
47 template<
typename T1,
typename T2>
53 template<
typename T1,
typename T2>
54 std::ostream& operator<<(std::ostream& os, const RemoteIndex<T1,T2>& index);
57 template<
typename T,
typename A,
bool mode>
64 template<
typename T1,
typename T2>
70 template<
typename T,
typename A,
typename A1>
75 template<
typename T,
typename A,
bool mode>
146 template<
class T,
class A>
147 std::ostream& operator<<(std::ostream& os, const RemoteIndices<T,A>& indices);
151 template<
class T,
class A>
158 template<
typename T1,
typename T2>
159 class OwnerOverlapCopyCommunication;
178 template<
class T,
class A=std::allocator<
RemoteIndex<
typename T::GlobalIndex,
179 typename T::LocalIndex::Attribute> > >
184 template<
typename T1,
typename A2,
typename A1>
189 template<
class G,
class T1,
class T2>
190 friend void fillIndexSetHoles(
const G& graph, Dune::OwnerOverlapCopyCommunication<T1,T2>& oocomm);
229 typedef typename A::template rebind<RemoteIndex>::other
Allocator;
236 typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
259 const MPI_Comm& comm,
const std::vector<int>&
neighbours=std::vector<int>(),
bool includeSelf=
false);
289 const MPI_Comm& comm,
const std::vector<int>&
neighbours=std::vector<int>());
294 typedef typename C::const_iterator Iter;
295 neighbourIds.clear();
296 neighbourIds.insert(neighbours.begin(), neighbours.end());
319 template<
bool ignorePublic>
352 template<
bool mode,
bool send>
414 std::set<int> neighbourIds;
417 const static int commTag_=333;
450 typedef IndexPair<GlobalIndex, LocalIndex>
471 template<
bool ignorePublic>
472 inline void buildRemote(
bool includeSelf);
492 template<
bool ignorePublic>
493 inline void packEntries(PairType** myPairs,
const ParallelIndexSet& indexSet,
494 char* p_out, MPI_Datatype type,
int bufferSize,
495 int* position,
int n);
511 PairType** local,
int localEntries,
char* p_in,
512 MPI_Datatype type,
int* positon,
int bufferSize,
516 int remoteEntries, PairType** localSource,
517 int localSourceEntries, PairType** localDest,
518 int localDestEntries,
char* p_in,
519 MPI_Datatype type,
int* position,
int bufferSize);
521 void unpackCreateRemote(
char* p_in, PairType** sourcePairs, PairType** DestPairs,
522 int remoteProc,
int sourcePublish,
int destPublish,
523 int bufferSize,
bool sendTwo,
bool fromOurSelf=
false);
543 template<
class T,
class A,
bool mode>
547 template<
typename T1,
typename A1>
672 RemoteIndexListModifier()
700 GlobalModifyIterator giter_;
710 template<
class T,
class A>
717 typedef T ParallelIndexSet;
732 typedef typename LocalIndex::Attribute Attribute;
738 typedef typename A::template rebind<RemoteIndex>::other Allocator;
751 typedef std::map<int, std::pair<RemoteIndexList*,RemoteIndexList*> >
769 inline void advance(
const GlobalIndex& global);
780 inline void advance(
const GlobalIndex& global,
const Attribute& attribute);
804 : iter_(iter), end_(end), index_(index), hasAttribute(false)
807 while(iter_!=end_ && iter_->second.first->localIndexPair().global()!=index_)
813 : iter_(iter), end_(end), index_(index), attribute_(attribute), hasAttribute(true)
816 while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_
817 || iter_->second.first->localIndexPair().local().attribute()!=attribute))
822 : iter_(other.iter_), end_(other.end_), index_(other.index_)
830 while(iter_!=end_ && (iter_->second.first->localIndexPair().global()!=index_ ||
832 iter_->second.first->localIndexPair().local().attribute()!=attribute_)))
834 assert(iter_==end_ ||
835 (iter_->second.first->localIndexPair().global()==index_));
836 assert(iter_==end_ || !hasAttribute ||
837 (iter_->second.first->localIndexPair().local().attribute()==attribute_));
844 return *(iter_->second.first);
856 return iter_->second.first.operator->();
862 return other.iter_==iter_;
868 return other.iter_!=iter_;
877 Attribute attribute_;
889 Attribute attribute_;
893 template<
typename TG,
typename TA>
896 if(type==MPI_DATATYPE_NULL){
902 length[0]=length[1]=length[2]=length[3]=1;
903 MPI_Address(rep, disp);
904 MPI_Address(&(rep[0].global_), disp+1);
905 MPI_Address(&(rep[0].local_), disp+2);
906 MPI_Address(rep+1, disp+3);
907 for(
int i=3; i >= 0; --i)
909 MPI_Type_struct(4, length, disp, types, &type);
910 MPI_Type_commit(&type);
915 template<
typename TG,
typename TA>
918 template<
typename T1,
typename T2>
920 : localIndex_(local), attribute_(attribute)
923 template<
typename T1,
typename T2>
925 : localIndex_(0), attribute_(attribute)
928 template<
typename T1,
typename T2>
930 : localIndex_(0), attribute_()
932 template<
typename T1,
typename T2>
935 return localIndex_==ri.localIndex_ && attribute_==ri.
attribute;
938 template<
typename T1,
typename T2>
941 return localIndex_!=ri.localIndex_ || attribute_!=ri.attribute_;
944 template<
typename T1,
typename T2>
947 return T2(attribute_);
950 template<
typename T1,
typename T2>
956 template<
typename T,
typename A>
959 const MPI_Comm& comm,
960 const std::vector<int>& neighbours,
962 : source_(&source), target_(&destination), comm_(comm),
963 sourceSeqNo_(-1), destSeqNo_(-1), publicIgnored(false), firstBuild(true),
964 includeSelf(includeSelf_)
969 template<
typename T,
typename A>
975 template<
typename T,
typename A>
977 :source_(0), target_(0), sourceSeqNo_(-1),
978 destSeqNo_(-1), publicIgnored(false), firstBuild(true)
981 template<
class T,
typename A>
984 const MPI_Comm& comm,
985 const std::vector<int>& neighbours)
989 target_ = &destination;
992 setNeighbours(neighbours);
995 template<
typename T,
typename A>
1003 template<
typename T,
typename A>
1011 template<
typename T,
typename A>
1017 template<
typename T,
typename A>
1018 template<
bool ignorePublic>
1021 char* p_out, MPI_Datatype type,
1023 int *position,
int n)
1028 const const_iterator end = indexSet.end();
1032 for(const_iterator index = indexSet.begin(); index != end; ++index)
1033 if(ignorePublic || index->local().isPublic()){
1035 MPI_Pack(const_cast<PairType*>(&(*index)), 1,
1037 p_out, bufferSize, position, comm_);
1038 pairs[i++] =
const_cast<PairType*
>(&(*index));
1044 template<
typename T,
typename A>
1051 const const_iterator end=indexSet.
end();
1052 for(const_iterator index=indexSet.
begin(); index!=end; ++index)
1053 if(index->local().isPublic())
1061 template<
typename T,
typename A>
1062 inline void RemoteIndices<T,A>::unpackCreateRemote(
char* p_in, PairType** sourcePairs,
1063 PairType** destPairs,
int remoteProc,
1064 int sourcePublish,
int destPublish,
1065 int bufferSize,
bool sendTwo,
1070 int noRemoteSource=-1, noRemoteDest=-1;
1071 char twoIndexSets=0;
1074 MPI_Unpack(p_in, bufferSize, &position, &twoIndexSets, 1, MPI_CHAR, comm_);
1076 MPI_Unpack(p_in, bufferSize, &position, &noRemoteSource, 1, MPI_INT, comm_);
1078 MPI_Unpack(p_in, bufferSize, &position, &noRemoteDest, 1, MPI_INT, comm_);
1082 RemoteIndexList* receive=
new RemoteIndexList();
1084 RemoteIndexList* send=0;
1090 send =
new RemoteIndexList();
1092 unpackIndices(*send, *receive, noRemoteSource, sourcePairs, sourcePublish,
1093 destPairs, destPublish, p_in, type, &position, bufferSize);
1096 unpackIndices(*receive, noRemoteSource, sourcePairs, sourcePublish,
1097 p_in, type, &position, bufferSize, fromOurSelf);
1102 int oldPos=position;
1104 unpackIndices(*receive, noRemoteSource, destPairs, destPublish,
1105 p_in, type, &position, bufferSize, fromOurSelf);
1110 send =
new RemoteIndexList();
1111 unpackIndices(*send, noRemoteDest, sourcePairs, sourcePublish,
1112 p_in, type, &position, bufferSize, fromOurSelf);
1115 if(receive->empty() && send->empty()){
1123 remoteIndices_.insert(std::make_pair(remoteProc,
1124 std::make_pair(send,receive)));
1129 template<
typename T,
typename A>
1130 template<
bool ignorePublic>
1131 inline void RemoteIndices<T,A>::buildRemote(
bool includeSelf)
1135 MPI_Comm_rank(comm_, &rank);
1136 MPI_Comm_size(comm_, &procs);
1140 int sourcePublish, destPublish;
1143 char sendTwo = (source_ != target_);
1145 if(procs==1 && !(sendTwo || includeSelf))
1149 sourcePublish = (ignorePublic)? source_->size() : noPublic(*source_);
1152 destPublish = (ignorePublic)? target_->size() : noPublic(*target_);
1157 int maxPublish, publish=sourcePublish+destPublish;
1160 MPI_Allreduce(&publish, &maxPublish, 1, MPI_INT, MPI_MAX, comm_);
1163 typedef IndexPair<GlobalIndex,LocalIndex> PairType;
1165 PairType** destPairs;
1166 PairType** sourcePairs =
new PairType*[sourcePublish>0?sourcePublish:1];
1169 destPairs =
new PairType*[destPublish>0?destPublish:1];
1171 destPairs=sourcePairs;
1173 char** buffer =
new char*[2];
1182 MPI_Pack_size(maxPublish, type, comm_,
1184 MPI_Pack_size(1, MPI_INT, comm_,
1186 MPI_Pack_size(1, MPI_CHAR, comm_,
1192 bufferSize += 2 * intSize + charSize;
1194 if(bufferSize<=0) bufferSize=1;
1196 buffer[0] =
new char[bufferSize];
1197 buffer[1] =
new char[bufferSize];
1201 MPI_Pack(&sendTwo, 1, MPI_CHAR, buffer[0], bufferSize, &position,
1205 MPI_Pack(&sourcePublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1207 MPI_Pack(&destPublish, 1, MPI_INT, buffer[0], bufferSize, &position,
1211 packEntries<ignorePublic>(sourcePairs, *source_, buffer[0], type,
1212 bufferSize, &position, sourcePublish);
1215 packEntries<ignorePublic>(destPairs, *target_, buffer[0], type,
1216 bufferSize, &position, destPublish);
1220 if(sendTwo|| includeSelf)
1221 unpackCreateRemote(buffer[0], sourcePairs, destPairs, rank, sourcePublish,
1222 destPublish, bufferSize, sendTwo, includeSelf);
1224 neighbourIds.erase(rank);
1226 if(neighbourIds.size()==0)
1228 Dune::dvverb<<rank<<
": Sending messages in a ring"<<std::endl;
1230 for(
int proc=1; proc<procs; proc++){
1232 char* p_out = buffer[1-(proc%2)];
1233 char* p_in = buffer[proc%2];
1237 MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1239 MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1240 commTag_, comm_, &status);
1242 MPI_Recv(p_in, bufferSize, MPI_PACKED, (rank+procs-1)%procs,
1243 commTag_, comm_, &status);
1244 MPI_Ssend(p_out, bufferSize, MPI_PACKED, (rank+1)%procs,
1250 int remoteProc = (rank+procs-proc)%procs;
1252 unpackCreateRemote(p_in, sourcePairs, destPairs, remoteProc, sourcePublish,
1253 destPublish, bufferSize, sendTwo);
1260 MPI_Request* requests=
new MPI_Request[neighbourIds.size()];
1261 MPI_Request* req=requests;
1263 typedef typename std::set<int>::size_type size_type;
1264 size_type noNeighbours=neighbourIds.size();
1267 for(std::set<int>::iterator neighbour=neighbourIds.begin();
1268 neighbour!= neighbourIds.end(); ++neighbour){
1270 MPI_Issend(buffer[0], position , MPI_PACKED, *neighbour, commTag_, comm_, req++);
1275 for(size_type received=0; received <noNeighbours; ++received)
1279 MPI_Probe(MPI_ANY_SOURCE, commTag_, comm_, &status);
1280 int remoteProc=status.MPI_SOURCE;
1282 MPI_Get_count(&status, MPI_PACKED, &size);
1284 MPI_Recv(buffer[1], size, MPI_PACKED, remoteProc,
1285 commTag_, comm_, &status);
1287 unpackCreateRemote(buffer[1], sourcePairs, destPairs, remoteProc, sourcePublish,
1288 destPublish, bufferSize, sendTwo);
1291 MPI_Status* statuses =
new MPI_Status[neighbourIds.size()];
1293 if(MPI_ERR_IN_STATUS==MPI_Waitall(neighbourIds.size(), requests, statuses)){
1294 for(size_type i=0; i < neighbourIds.size(); ++i)
1295 if(statuses[i].MPI_ERROR!=MPI_SUCCESS){
1296 std::cerr<<rank<<
": MPI_Error occurred while receiving message."<<std::endl;
1297 MPI_Abort(comm_, 999);
1306 if(destPairs!=sourcePairs)
1309 delete[] sourcePairs;
1315 template<
typename T,
typename A>
1316 inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& remote,
1326 if(remoteEntries==0)
1330 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1332 GlobalIndex oldGlobal=index.global();
1333 int n_in=0, localIndex=0;
1336 while(localIndex<localEntries){
1337 if(local[localIndex]->global()==index.global()){
1338 int oldLocalIndex=localIndex;
1340 while(localIndex<localEntries &&
1341 local[localIndex]->global()==index.global()){
1342 if(!fromOurSelf || index.local().attribute() !=
1343 local[localIndex]->local().attribute())
1345 remote.push_back(RemoteIndex(index.local().attribute(),
1346 local[localIndex]));
1351 if((++n_in) < remoteEntries){
1352 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1354 if(index.global()==oldGlobal)
1356 localIndex=oldLocalIndex;
1358 oldGlobal=index.global();
1366 if (local[localIndex]->global()<index.global()){
1371 if((++n_in) < remoteEntries){
1372 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1374 oldGlobal=index.global();
1382 while(++n_in < remoteEntries)
1383 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1388 template<
typename T,
typename A>
1389 inline void RemoteIndices<T,A>::unpackIndices(RemoteIndexList& send,
1390 RemoteIndexList& receive,
1392 PairType** localSource,
1393 int localSourceEntries,
1394 PairType** localDest,
1395 int localDestEntries,
1401 int n_in=0, sourceIndex=0, destIndex=0;
1404 while(n_in<remoteEntries && (sourceIndex<localSourceEntries || destIndex<localDestEntries)){
1407 MPI_Unpack(p_in, bufferSize, position, &index, 1,
1412 while(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()<index.global())
1415 while(destIndex<localDestEntries && localDest[destIndex]->global()<index.global())
1419 if(sourceIndex<localSourceEntries && localSource[sourceIndex]->global()==index.global())
1420 send.push_back(RemoteIndex(index.local().attribute(),
1421 localSource[sourceIndex]));
1423 if(destIndex < localDestEntries && localDest[destIndex]->global() == index.global())
1424 receive.push_back(RemoteIndex(index.local().attribute(),
1425 localDest[sourceIndex]));
1430 template<
typename T,
typename A>
1433 typedef typename RemoteIndexMap::iterator Iterator;
1434 Iterator lend = remoteIndices_.end();
1435 for(Iterator lists=remoteIndices_.begin(); lists != lend; ++lists){
1436 if(lists->second.first==lists->second.second){
1438 delete lists->second.first;
1440 delete lists->second.first;
1441 delete lists->second.second;
1444 remoteIndices_.clear();
1448 template<
typename T,
typename A>
1451 return remoteIndices_.size();
1454 template<
typename T,
typename A>
1455 template<
bool ignorePublic>
1460 ignorePublic!=publicIgnored || !
1464 buildRemote<ignorePublic>(includeSelf);
1466 sourceSeqNo_ = source_->seqNo();
1467 destSeqNo_ = target_->seqNo();
1469 publicIgnored=ignorePublic;
1475 template<
typename T,
typename A>
1478 return sourceSeqNo_==source_->seqNo() && destSeqNo_ ==target_->seqNo();
1481 template<
typename T,
typename A>
1482 template<
bool mode,
bool send>
1489 sourceSeqNo_ = source_->seqNo();
1490 destSeqNo_ = target_->seqNo();
1492 typename RemoteIndexMap::iterator found = remoteIndices_.find(process);
1494 if(found == remoteIndices_.end())
1496 if(source_ != target_)
1497 remoteIndices_.insert(std::make_pair(process,
1502 remoteIndices_.insert(std::make_pair(process,
1503 std::make_pair(rlist, rlist)));
1505 found = remoteIndices_.find(process);
1517 template<
typename T,
typename A>
1521 return remoteIndices_.find(proc);
1524 template<
typename T,
typename A>
1528 return remoteIndices_.begin();
1531 template<
typename T,
typename A>
1535 return remoteIndices_.end();
1539 template<
typename T,
typename A>
1546 typedef typename std::map<int,std::pair<RList*,RList*> >
::const_iterator const_iterator;
1548 const const_iterator rend = remoteIndices_.
end();
1550 for(const_iterator rindex = remoteIndices_.begin(), rindex1=ri.remoteIndices_.begin(); rindex!=rend; ++rindex, ++rindex1){
1551 if(rindex->first != rindex1->first)
1553 if(*(rindex->second.first) != *(rindex1->second.first))
1555 if(*(rindex->second.second) != *(rindex1->second.second))
1561 template<
class T,
class A,
bool mode>
1563 RemoteIndexList& rList)
1564 : rList_(&rList), indexSet_(&indexSet), glist_(new GlobalList()), iter_(rList.beginModify()), end_(rList.end()), first_(true)
1568 for(ConstIterator iter=iter_; iter != end_; ++iter)
1569 glist_->push_back(iter->localIndexPair().global());
1570 giter_ = glist_->beginModify();
1574 template<
typename T,
typename A,
bool mode>
1576 : rList_(other.rList_), indexSet_(other.indexSet_),
1577 glist_(other.glist_), iter_(other.iter_), giter_(other.giter_), end_(other.end_),
1578 first_(other.first_), last_(other.last_)
1581 template<
typename T,
typename A,
bool mode>
1586 #ifdef DUNE_ISTL_WITH_CHECKING
1587 if(indexSet_->state()!=
GROUND)
1588 DUNE_THROW(InvalidIndexSetState,
"Index has to be in ground mode for repairing pointers to indices");
1593 GlobalIterator giter = glist_->begin();
1594 IndexIterator index = indexSet_->begin();
1596 for(Iterator iter=rList_->begin(); iter != end_; ++iter){
1597 while(index->global()<*giter){
1599 #ifdef DUNE_ISTL_WITH_CHECKING
1600 if(index == indexSet_.end())
1605 #ifdef DUNE_ISTL_WITH_CHECKING
1606 if(index->global() != *giter)
1609 iter->localIndex_ = &(*index);
1614 template<
typename T,
typename A,
bool mode>
1618 "might be added to the underlying index set. Use "
1619 "insert(const RemoteIndex&, const GlobalIndex&) instead");
1621 #ifdef DUNE_ISTL_WITH_CHECKING
1622 if(!first_ && index.localIndexPair().global()<last_)
1626 while(iter_ != end_ && iter_->localIndexPair().global() < index.localIndexPair().global()){
1631 assert(iter_==end_ || iter_->localIndexPair().global() != index.localIndexPair().global());
1632 iter_.insert(index);
1633 last_ = index.localIndexPair().global();
1637 template<
typename T,
typename A,
bool mode>
1641 "might be added to the underlying index set. Use "
1642 "insert(const RemoteIndex&) instead");
1643 #ifdef DUNE_ISTL_WITH_CHECKING
1644 if(!first_ && global<last_)
1648 while(iter_ != end_ && *giter_ < global){
1654 assert(iter_->localIndexPair().global() != global);
1655 iter_.insert(index);
1656 giter_.insert(global);
1662 template<
typename T,
typename A,
bool mode>
1665 #ifdef DUNE_ISTL_WITH_CHECKING
1666 if(!first_ && global<last_)
1674 while(iter_!=end_ && *giter_< global){
1678 if(*giter_ == global){
1684 while(iter_!=end_ && iter_->localIndexPair().global() < global)
1687 if(iter_->localIndexPair().global()==global){
1698 template<
typename T,
typename A>
1705 template<
typename T,
typename A>
1712 template<
typename T,
typename A>
1715 typedef typename RemoteIndexMap::const_iterator const_iterator;
1716 typedef typename RemoteIndexMap::iterator
iterator;
1718 const const_iterator end=pmap.end();
1719 for(const_iterator process=pmap.begin(); process != end; ++process){
1720 const RemoteIndexList* list = send? process->second.first : process->second.second;
1722 map_.insert(std::make_pair(process->first,
1723 std::pair<iterator, const iterator>(list->
begin(), list->
end())));
1727 template<
typename T,
typename A>
1730 typedef typename Map::iterator
iterator;
1731 typedef typename Map::const_iterator const_iterator;
1732 const const_iterator end = map_.end();
1734 for(iterator iter = map_.begin(); iter != end;){
1740 remoteIndex = *current;
1742 while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1743 ++(iter->second.first);
1746 if(iter->second.first == iter->second.second)
1756 template<
typename T,
typename A>
1758 const Attribute& attribute)
1760 typedef typename Map::iterator
iterator;
1761 typedef typename Map::const_iterator const_iterator;
1762 const const_iterator end = map_.end();
1764 for(iterator iter = map_.begin(); iter != end;){
1770 remoteIndex = *current;
1773 while(iter->second.first!=iter->second.second && iter->second.first->localIndexPair().global()<index)
1774 ++(iter->second.first);
1777 while(iter->second.first!=iter->second.second
1778 && iter->second.first->localIndexPair().global()==index
1779 && iter->second.first->localIndexPair().local().attribute()<attribute)
1780 ++(iter->second.first);
1783 if(iter->second.first == iter->second.second)
1790 attribute_=attribute;
1794 template<
typename T,
typename A>
1797 typedef typename Map::iterator
iterator;
1798 typedef typename Map::const_iterator const_iterator;
1799 const const_iterator end = map_.end();
1801 for(iterator iter = map_.begin(); iter != end;){
1807 if(iter->second.first->localIndexPair().global()==index_ &&
1808 (noattribute || iter->second.first->localIndexPair().local().attribute() == attribute_))
1809 ++(iter->second.first);
1812 if(iter->second.first == iter->second.second)
1821 template<
typename T,
typename A>
1824 return map_.empty();
1827 template<
typename T,
typename A>
1832 return iterator(map_.begin(), map_.end(), index_);
1834 return iterator(map_.begin(), map_.end(), index_,
1838 template<
typename T,
typename A>
1842 return iterator(map_.end(), map_.end(), index_);
1845 template<
typename TG,
typename TA>
1846 inline std::ostream& operator<<(std::ostream& os, const RemoteIndex<TG,TA>& index)
1848 os<<
"[global="<<index.localIndexPair().global()<<
", remote attribute="<<index.attribute()<<
" local attribute="<<index.localIndexPair().local().attribute()<<
"]";
1852 template<
typename T,
typename A>
1853 inline std::ostream& operator<<(std::ostream& os, const RemoteIndices<T,A>& indices)
1856 MPI_Comm_rank(indices.comm_, &rank);
1859 typedef typename std::map<int,std::pair<RList*,RList*> >::const_iterator const_iterator;
1861 const const_iterator rend = indices.remoteIndices_.
end();
1863 for(const_iterator rindex = indices.remoteIndices_.begin(); rindex!=rend; ++rindex){
1864 os<<rank<<
": Prozess "<<rindex->first<<
":";
1866 if(!rindex->second.first->empty()){
1869 const typename RList::const_iterator send= rindex->second.first->end();
1871 for(
typename RList::const_iterator index = rindex->second.first->begin();
1872 index != send; ++index)
1876 if(!rindex->second.second->empty()){
1877 os<<rank<<
": Prozess "<<rindex->first<<
": "<<
"receive: ";
1879 const typename RList::const_iterator rend= rindex->second.second->end();
1881 for(
typename RList::const_iterator index = rindex->second.second->begin();
1882 index != rend; ++index)
1885 os<<std::endl<<std::flush;