5#ifndef DUNE_COMMUNICATOR
6#define DUNE_COMMUNICATOR
177 template<
class K,
class A,
int n>
255 DatatypeCommunicator();
260 ~DatatypeCommunicator();
288 template<
class T1,
class T2,
class V>
289 void build(
const RemoteIndices& remoteIndices,
const T1& sourceFlags, V& sendData,
const T2& destFlags, V& receiveData);
309 constexpr static int commTag_ = 234;
316 typedef std::map<int,std::pair<MPI_Datatype,MPI_Datatype> >
322 MessageTypeMap messageTypes;
329 MPI_Request* requests_[2];
339 template<
class V,
bool FORWARD>
340 void createRequests(V& sendData, V& receiveData);
345 template<
class T1,
class T2,
class V,
bool send>
346 void createDataTypes(
const T1& source,
const T2& destination, V& data);
351 void sendRecv(MPI_Request* req);
356 struct IndexedTypeInformation
366 displ =
new MPI_Aint[i];
400 struct MPIDatatypeInformation
406 MPIDatatypeInformation(
const V& data) : data_(data)
414 void reserve(
int proc,
int size)
416 information_[proc].build(size);
424 void add(
int proc,
int local)
426 IndexedTypeInformation& info=information_[proc];
427 assert((info.elements)<info.size);
428 MPI_Get_address(
const_cast<void*
>(CommPolicy<V>::getAddress(data_, local)),
429 info.displ+info.elements);
430 info.length[info.elements]=CommPolicy<V>::getSize(data_, local);
438 std::map<int,IndexedTypeInformation> information_;
472 template<
class Data,
class Interface>
473 typename std::enable_if<std::is_same<SizeOne,typename CommPolicy<Data>::IndexedTypeFlag>::value,
void>::type
483 template<
class Data,
class Interface>
514 template<
class GatherScatter,
class Data>
545 template<
class GatherScatter,
class Data>
573 template<
class GatherScatter,
class Data>
601 template<
class GatherScatter,
class Data>
619 typedef std::map<int,std::pair<InterfaceInformation,InterfaceInformation> >
626 template<
class Data,
typename IndexedTypeFlag>
627 struct MessageSizeCalculator
635 struct MessageSizeCalculator<Data,
SizeOne>
660 struct MessageSizeCalculator<Data,VariableSize>
670 inline int operator()(
const Data& data,
const InterfaceInformation& info)
const;
676 template<
class Data,
class GatherScatter,
bool send,
typename IndexedTypeFlag>
677 struct MessageGatherer
684 template<
class Data,
class GatherScatter,
bool send>
685 struct MessageGatherer<Data,GatherScatter,send,SizeOne>
694 typedef GatherScatter Gatherer;
701 constexpr static bool forward = send;
710 inline void operator()(
const InterfaceMap& interface,
const Data& data, Type* buffer,
size_t bufferSize)
const;
717 template<
class Data,
class GatherScatter,
bool send>
718 struct MessageGatherer<Data,GatherScatter,send,VariableSize>
727 typedef GatherScatter Gatherer;
734 constexpr static bool forward = send;
743 inline void operator()(
const InterfaceMap& interface,
const Data& data, Type* buffer,
size_t bufferSize)
const;
749 template<
class Data,
class GatherScatter,
bool send,
typename IndexedTypeFlag>
750 struct MessageScatterer
757 template<
class Data,
class GatherScatter,
bool send>
758 struct MessageScatterer<Data,GatherScatter,send,SizeOne>
767 typedef GatherScatter Scatterer;
774 constexpr static bool forward = send;
783 inline void operator()(
const InterfaceMap& interface, Data& data, Type* buffer,
const int& proc)
const;
789 template<
class Data,
class GatherScatter,
bool send>
790 struct MessageScatterer<Data,GatherScatter,send,VariableSize>
799 typedef GatherScatter Scatterer;
806 constexpr static bool forward = send;
815 inline void operator()(
const InterfaceMap& interface, Data& data, Type* buffer,
const int& proc)
const;
821 struct MessageInformation
825 : start_(0), size_(0)
835 MessageInformation(
size_t start,
size_t size)
836 : start_(start), size_(size)
854 typedef std::map<int,std::pair<MessageInformation,MessageInformation> >
859 InformationMap messageInformation_;
867 size_t bufferSize_[2];
872 constexpr static int commTag_ = 0;
877 std::map<int,std::pair<InterfaceInformation,InterfaceInformation> > interfaces_;
879 MPI_Comm communicator_;
884 template<
class GatherScatter,
bool FORWARD,
class Data>
885 void sendRecv(
const Data& source, Data& target);
903 template<
class K,
class A,
int n>
904 inline const void* CommPolicy<VariableBlockVector<FieldVector<K, n>, A> >::getAddress(
const Type& v,
int index)
906 return &(v[index][0]);
909 template<
class K,
class A,
int n>
910 inline int CommPolicy<VariableBlockVector<FieldVector<K, n>, A> >::getSize(
const Type& v,
int index)
912 return v[index].getsize();
916 inline const typename CopyGatherScatter<T>::IndexedType& CopyGatherScatter<T>::gather(
const T & vec, std::size_t i)
922 inline void CopyGatherScatter<T>::scatter(T& vec,
const IndexedType& v, std::size_t i)
928 DatatypeCommunicator<T>::DatatypeCommunicator()
929 : remoteIndices_(0), created_(false)
938 DatatypeCommunicator<T>::~DatatypeCommunicator()
944 template<
class T1,
class T2,
class V>
945 inline void DatatypeCommunicator<T>::build(
const RemoteIndices& remoteIndices,
946 const T1& source, V& sendData,
947 const T2& destination, V& receiveData)
949 remoteIndices_ = &remoteIndices;
951 createDataTypes<T1,T2,V,false>(source,destination, receiveData);
952 createDataTypes<T1,T2,V,true>(source,destination, sendData);
953 createRequests<V,true>(sendData, receiveData);
954 createRequests<V,false>(receiveData, sendData);
959 void DatatypeCommunicator<T>::free()
962 delete[] requests_[0];
963 delete[] requests_[1];
964 typedef MessageTypeMap::iterator iterator;
965 typedef MessageTypeMap::const_iterator const_iterator;
967 const const_iterator end=messageTypes.end();
969 for(iterator process = messageTypes.begin(); process != end; ++process) {
970 MPI_Datatype *type = &(process->second.first);
972 MPI_Finalized(&finalized);
973 if(*type!=MPI_DATATYPE_NULL && !finalized)
975 type = &(process->second.second);
976 if(*type!=MPI_DATATYPE_NULL && !finalized)
979 messageTypes.clear();
986 template<
class T1,
class T2,
class V,
bool send>
987 void DatatypeCommunicator<T>::createDataTypes(
const T1& sourceFlags,
const T2& destFlags, V& data)
990 MPIDatatypeInformation<V> dataInfo(data);
991 this->
template buildInterface<RemoteIndices,T1,T2,MPIDatatypeInformation<V>,send>(*remoteIndices_,sourceFlags, destFlags, dataInfo);
993 typedef typename RemoteIndices::RemoteIndexMap::const_iterator const_iterator;
994 const const_iterator end=this->remoteIndices_->end();
997 for(const_iterator process=this->remoteIndices_->begin(); process != end; ++process) {
998 IndexedTypeInformation& info=dataInfo.information_[process->first];
1003 for(
int i=0; i< info.elements; i++) {
1004 info.displ[i]-=base;
1008 MPI_Datatype* type = &( send ? messageTypes[process->first].first : messageTypes[process->first].second);
1009 MPI_Type_create_hindexed(info.elements, info.length, info.displ,
1011 MPI_Type_commit(type);
1017 template<
typename T>
1018 template<
class V,
bool createForward>
1019 void DatatypeCommunicator<T>::createRequests(V& sendData, V& receiveData)
1021 typedef std::map<int,std::pair<MPI_Datatype,MPI_Datatype> >::const_iterator MapIterator;
1023 static int index = createForward ? 1 : 0;
1024 int noMessages = messageTypes.size();
1026 requests_[index] =
new MPI_Request[2*noMessages];
1027 const MapIterator end = messageTypes.end();
1029 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1032 for(MapIterator process = messageTypes.begin(); process != end;
1033 ++process, ++request) {
1034 MPI_Datatype type = createForward ? process->second.second : process->second.first;
1036 MPI_Recv_init(address, 1, type, process->first, commTag_, this->remoteIndices_->communicator(), requests_[index]+request);
1041 for(MapIterator process = messageTypes.begin(); process != end;
1042 ++process, ++request) {
1043 MPI_Datatype type = createForward ? process->second.first : process->second.second;
1045 MPI_Ssend_init(address, 1, type, process->first, commTag_, this->remoteIndices_->communicator(), requests_[index]+request);
1049 template<
typename T>
1050 void DatatypeCommunicator<T>::forward()
1052 sendRecv(requests_[1]);
1055 template<
typename T>
1056 void DatatypeCommunicator<T>::backward()
1058 sendRecv(requests_[0]);
1061 template<
typename T>
1062 void DatatypeCommunicator<T>::sendRecv(MPI_Request* requests)
1064 int noMessages = messageTypes.size();
1066 MPI_Startall(noMessages, requests);
1068 MPI_Startall(noMessages, requests+noMessages);
1071 MPI_Status* status=
new MPI_Status[2*noMessages];
1072 for(
int i=0; i<2*noMessages; i++)
1073 status[i].MPI_ERROR=MPI_SUCCESS;
1075 int send = MPI_Waitall(noMessages, requests+noMessages, status+noMessages);
1076 int receive = MPI_Waitall(noMessages, requests, status);
1079 int success=1, globalSuccess=0;
1080 if(send==MPI_ERR_IN_STATUS) {
1082 MPI_Comm_rank(this->remoteIndices_->communicator(), &rank);
1083 std::cerr<<rank<<
": Error in sending :"<<std::endl;
1085 for(
int i=noMessages; i< 2*noMessages; i++)
1086 if(status[i].MPI_ERROR!=MPI_SUCCESS) {
1089 MPI_Error_string(status[i].MPI_ERROR, message, &messageLength);
1090 std::cerr<<
" source="<<status[i].MPI_SOURCE<<
" message: ";
1091 for(
int j = 0; j < messageLength; j++)
1092 std::cout << message[j];
1094 std::cerr<<std::endl;
1098 if(receive==MPI_ERR_IN_STATUS) {
1100 MPI_Comm_rank(this->remoteIndices_->communicator(), &rank);
1101 std::cerr<<rank<<
": Error in receiving!"<<std::endl;
1103 for(
int i=0; i< noMessages; i++)
1104 if(status[i].MPI_ERROR!=MPI_SUCCESS) {
1107 MPI_Error_string(status[i].MPI_ERROR, message, &messageLength);
1108 std::cerr<<
" source="<<status[i].MPI_SOURCE<<
" message: ";
1109 for(
int j = 0; j < messageLength; j++)
1110 std::cerr << message[j];
1112 std::cerr<<std::endl;
1116 MPI_Allreduce(&success, &globalSuccess, 1, MPI_INT, MPI_MIN, this->remoteIndices_->communicator());
1121 DUNE_THROW(CommunicationError,
"A communication error occurred!");
1133 template<
class Data,
class Interface>
1134 typename std::enable_if<std::is_same<SizeOne, typename CommPolicy<Data>::IndexedTypeFlag>::value,
void>::type
1137 interfaces_=interface.interfaces();
1138 communicator_=interface.communicator();
1139 typedef typename std::map<int,std::pair<InterfaceInformation,InterfaceInformation> >
1140 ::const_iterator const_iterator;
1142 const const_iterator end = interfaces_.end();
1144 MPI_Comm_rank(communicator_, &lrank);
1149 for(const_iterator interfacePair = interfaces_.begin();
1150 interfacePair != end; ++interfacePair) {
1151 int noSend = MessageSizeCalculator<Data,Flag>() (interfacePair->second.first);
1152 int noRecv = MessageSizeCalculator<Data,Flag>() (interfacePair->second.second);
1153 if (noSend + noRecv > 0)
1154 messageInformation_.insert(std::make_pair(interfacePair->first,
1155 std::make_pair(MessageInformation(bufferSize_[0],
1157 MessageInformation(bufferSize_[1],
1159 bufferSize_[0] += noSend;
1160 bufferSize_[1] += noRecv;
1167 buffers_[0] =
new char[bufferSize_[0]];
1168 buffers_[1] =
new char[bufferSize_[1]];
1171 template<
class Data,
class Interface>
1175 interfaces_=interface.interfaces();
1176 communicator_=interface.communicator();
1177 typedef typename std::map<int,std::pair<InterfaceInformation,InterfaceInformation> >
1178 ::const_iterator const_iterator;
1180 const const_iterator end = interfaces_.end();
1185 for(const_iterator interfacePair = interfaces_.begin();
1186 interfacePair != end; ++interfacePair) {
1187 int noSend = MessageSizeCalculator<Data,Flag>() (source, interfacePair->second.first);
1188 int noRecv = MessageSizeCalculator<Data,Flag>() (dest, interfacePair->second.second);
1189 if (noSend + noRecv > 0)
1190 messageInformation_.insert(std::make_pair(interfacePair->first,
1191 std::make_pair(MessageInformation(bufferSize_[0],
1193 MessageInformation(bufferSize_[1],
1195 bufferSize_[0] += noSend;
1196 bufferSize_[1] += noRecv;
1202 buffers_[0] =
new char[bufferSize_[0]];
1203 buffers_[1] =
new char[bufferSize_[1]];
1208 messageInformation_.clear();
1210 delete[] buffers_[0];
1213 delete[] buffers_[1];
1214 buffers_[0]=buffers_[1]=0;
1222 template<
class Data>
1223 inline int BufferedCommunicator::MessageSizeCalculator<Data,SizeOne>::operator()
1224 (
const InterfaceInformation& info)
const
1230 template<
class Data>
1231 inline int BufferedCommunicator::MessageSizeCalculator<Data,SizeOne>::operator()
1232 (
const Data&,
const InterfaceInformation& info)
const
1234 return operator()(info);
1238 template<
class Data>
1239 inline int BufferedCommunicator::MessageSizeCalculator<Data, VariableSize>::operator()
1240 (
const Data& data,
const InterfaceInformation& info)
const
1244 for(
size_t i=0; i < info.size(); i++)
1251 template<
class Data,
class GatherScatter,
bool FORWARD>
1252 inline void BufferedCommunicator::MessageGatherer<Data,GatherScatter,FORWARD,VariableSize>::operator()(
const InterfaceMap& interfaces,
const Data& data, Type* buffer, [[maybe_unused]]
size_t bufferSize)
const
1254 typedef typename InterfaceMap::const_iterator
1258 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1259 const const_iterator end = interfaces.end();
1262 for(const_iterator interfacePair = interfaces.begin();
1263 interfacePair != end; ++interfacePair) {
1264 int size = forward ? interfacePair->second.first.size() :
1265 interfacePair->second.second.size();
1267 for(
int i=0; i < size; i++) {
1268 int local = forward ? interfacePair->second.first[i] :
1269 interfacePair->second.second[i];
1270 for(std::size_t j=0; j < CommPolicy<Data>::getSize(data, local); j++, index++) {
1272#ifdef DUNE_ISTL_WITH_CHECKING
1275 buffer[index]=GatherScatter::gather(data, local, j);
1284 template<
class Data,
class GatherScatter,
bool FORWARD>
1285 inline void BufferedCommunicator::MessageGatherer<Data,GatherScatter,FORWARD,SizeOne>::operator()(
1286 const InterfaceMap& interfaces,
const Data& data, Type* buffer, [[maybe_unused]]
size_t bufferSize)
const
1288 typedef typename InterfaceMap::const_iterator
1290 const const_iterator end = interfaces.end();
1294 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1296 for(const_iterator interfacePair = interfaces.begin();
1297 interfacePair != end; ++interfacePair) {
1298 size_t size = FORWARD ? interfacePair->second.first.size() :
1299 interfacePair->second.second.size();
1301 for(
size_t i=0; i < size; i++) {
1303#ifdef DUNE_ISTL_WITH_CHECKING
1307 buffer[index++] = GatherScatter::gather(data, FORWARD ? interfacePair->second.first[i] :
1308 interfacePair->second.second[i]);
1315 template<
class Data,
class GatherScatter,
bool FORWARD>
1316 inline void BufferedCommunicator::MessageScatterer<Data,GatherScatter,FORWARD,VariableSize>::operator()(
const InterfaceMap& interfaces, Data& data, Type* buffer,
const int& proc)
const
1318 typedef typename InterfaceMap::value_type::second_type::first_type Information;
1319 const typename InterfaceMap::const_iterator infoPair = interfaces.find(proc);
1321 assert(infoPair!=interfaces.end());
1323 const Information& info = FORWARD ? infoPair->second.second :
1324 infoPair->second.first;
1326 for(
size_t i=0, index=0; i < info.size(); i++) {
1327 for(
size_t j=0; j < CommPolicy<Data>::getSize(data, info[i]); j++)
1328 GatherScatter::scatter(data, buffer[index++], info[i], j);
1333 template<
class Data,
class GatherScatter,
bool FORWARD>
1334 inline void BufferedCommunicator::MessageScatterer<Data,GatherScatter,FORWARD,SizeOne>::operator()(
const InterfaceMap& interfaces, Data& data, Type* buffer,
const int& proc)
const
1336 typedef typename InterfaceMap::value_type::second_type::first_type Information;
1337 const typename InterfaceMap::const_iterator infoPair = interfaces.find(proc);
1339 assert(infoPair!=interfaces.end());
1341 const Information& info = FORWARD ? infoPair->second.second :
1342 infoPair->second.first;
1344 for(
size_t i=0; i < info.size(); i++) {
1345 GatherScatter::scatter(data, buffer[i], info[i]);
1350 template<
class GatherScatter,
class Data>
1353 this->
template sendRecv<GatherScatter,true>(data, data);
1357 template<
class GatherScatter,
class Data>
1360 this->
template sendRecv<GatherScatter,false>(data, data);
1364 template<
class GatherScatter,
class Data>
1367 this->
template sendRecv<GatherScatter,true>(source, dest);
1371 template<
class GatherScatter,
class Data>
1374 this->
template sendRecv<GatherScatter,false>(dest, source);
1378 template<
class GatherScatter,
bool FORWARD,
class Data>
1379 void BufferedCommunicator::sendRecv(
const Data& source, Data& dest)
1383 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
1384 MPI_Comm_rank(MPI_COMM_WORLD,&lrank);
1387 Type *sendBuffer, *recvBuffer;
1388 size_t sendBufferSize;
1390 size_t recvBufferSize;
1394 sendBuffer =
reinterpret_cast<Type*
>(buffers_[0]);
1395 sendBufferSize = bufferSize_[0];
1396 recvBuffer =
reinterpret_cast<Type*
>(buffers_[1]);
1398 recvBufferSize = bufferSize_[1];
1401 sendBuffer =
reinterpret_cast<Type*
>(buffers_[1]);
1402 sendBufferSize = bufferSize_[1];
1403 recvBuffer =
reinterpret_cast<Type*
>(buffers_[0]);
1405 recvBufferSize = bufferSize_[0];
1410 MessageGatherer<Data,GatherScatter,FORWARD,Flag>() (interfaces_, source, sendBuffer, sendBufferSize);
1412 MPI_Request* sendRequests =
new MPI_Request[messageInformation_.size()];
1413 MPI_Request* recvRequests =
new MPI_Request[messageInformation_.size()];
1415 size_t numberOfRealRecvRequests = 0;
1418 typedef typename InformationMap::const_iterator const_iterator;
1420 const const_iterator end = messageInformation_.end();
1422 int* processMap =
new int[messageInformation_.size()];
1424 for(const_iterator info = messageInformation_.begin(); info != end; ++info, ++i) {
1425 processMap[i]=info->first;
1428 Dune::dvverb<<rank<<
": receiving "<<info->second.second.size_<<
" from "<<info->first<<std::endl;
1429 if(info->second.second.size_) {
1430 MPI_Irecv(recvBuffer+info->second.second.start_, info->second.second.size_,
1431 MPI_BYTE, info->first, commTag_, communicator_,
1433 numberOfRealRecvRequests += 1;
1436 recvRequests[i]=MPI_REQUEST_NULL;
1440 Dune::dvverb<<rank<<
": receiving "<<info->second.first.size_<<
" to "<<info->first<<std::endl;
1441 if(info->second.first.size_) {
1442 MPI_Irecv(recvBuffer+info->second.first.start_, info->second.first.size_,
1443 MPI_BYTE, info->first, commTag_, communicator_,
1445 numberOfRealRecvRequests += 1;
1448 recvRequests[i]=MPI_REQUEST_NULL;
1455 for(const_iterator info = messageInformation_.begin(); info != end; ++info, ++i)
1458 Dune::dvverb<<rank<<
": sending "<<info->second.first.size_<<
" to "<<info->first<<std::endl;
1460 if(info->second.first.size_)
1461 MPI_Issend(sendBuffer+info->second.first.start_, info->second.first.size_,
1462 MPI_BYTE, info->first, commTag_, communicator_,
1466 sendRequests[i]=MPI_REQUEST_NULL;
1469 Dune::dvverb<<rank<<
": sending "<<info->second.second.size_<<
" to "<<info->first<<std::endl;
1470 if(info->second.second.size_)
1471 MPI_Issend(sendBuffer+info->second.second.start_, info->second.second.size_,
1472 MPI_BYTE, info->first, commTag_, communicator_,
1476 sendRequests[i]=MPI_REQUEST_NULL;
1482 int finished = MPI_UNDEFINED;
1486 for(i=0; i< numberOfRealRecvRequests; i++) {
1487 status.MPI_ERROR=MPI_SUCCESS;
1488 MPI_Waitany(messageInformation_.size(), recvRequests, &finished, &status);
1489 assert(finished != MPI_UNDEFINED);
1491 if(status.MPI_ERROR==MPI_SUCCESS) {
1492 int& proc = processMap[finished];
1493 typename InformationMap::const_iterator infoIter = messageInformation_.find(proc);
1494 assert(infoIter != messageInformation_.end());
1496 MessageInformation info = (FORWARD) ? infoIter->second.second : infoIter->second.first;
1497 assert(info.start_+info.size_ <= recvBufferSize);
1499 MessageScatterer<Data,GatherScatter,FORWARD,Flag>() (interfaces_, dest, recvBuffer+info.start_, proc);
1501 std::cerr<<rank<<
": MPI_Error occurred while receiving message from "<<processMap[finished]<<std::endl;
1506 MPI_Status recvStatus;
1509 for(i=0; i< messageInformation_.size(); i++)
1510 if(MPI_SUCCESS!=MPI_Wait(sendRequests+i, &recvStatus)) {
1511 std::cerr<<rank<<
": MPI_Error occurred while sending message to "<<processMap[finished]<<std::endl;
1521 delete[] processMap;
1522 delete[] sendRequests;
1523 delete[] recvRequests;
A few common exception classes.
Standard Dune debug streams.
Classes describing a distributed indexset.
#define DUNE_THROW(E, m)
Definition exceptions.hh:218
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition stdstreams.hh:95
Dune namespace.
Definition alignedallocator.hh:13
Default exception class for I/O errors.
Definition exceptions.hh:231
Flag for marking indexed data structures where data at each index is of the same size.
Definition communicator.hh:110
Flag for marking indexed data structures where the data at each index may be a variable multiple of a...
Definition communicator.hh:118
Default policy used for communicating an indexed type.
Definition communicator.hh:128
V::value_type IndexedType
The type we get at each index with operator[].
Definition communicator.hh:147
static int getSize(const V &, int index)
Get the number of primitive elements at that index.
SizeOne IndexedTypeFlag
Whether the indexed type has variable size or there is always one value at each index.
Definition communicator.hh:153
static const void * getAddress(const V &v, int index)
Get the address of entry at an index.
V Type
The type the policy is for.
Definition communicator.hh:140
Definition communicator.hh:173
Definition communicator.hh:175
static int getSize(const Type &v, int i)
VariableSize IndexedTypeFlag
Definition communicator.hh:184
VariableBlockVector< FieldVector< K, n >, A > Type
Definition communicator.hh:180
static const void * getAddress(const Type &v, int i)
Type::B IndexedType
Definition communicator.hh:182
Error thrown if there was a problem with the communication.
Definition communicator.hh:195
GatherScatter default implementation that just copies data.
Definition communicator.hh:202
static void scatter(T &vec, const IndexedType &v, std::size_t i)
CommPolicy< T >::IndexedType IndexedType
Definition communicator.hh:203
static const IndexedType & gather(const T &vec, std::size_t i)
A communicator that uses buffers to gather and scatter the data to be send or received.
Definition communicator.hh:458
void backward(Data &data)
Backward send where target and source are the same.
BufferedCommunicator()
Constructor.
~BufferedCommunicator()
Destructor.
void forward(const Data &source, Data &dest)
Send from source to target.
void free()
Free the allocated memory (i.e. buffers and message information.
std::enable_if< std::is_same< SizeOne, typenameCommPolicy< Data >::IndexedTypeFlag >::value, void >::type build(const Interface &interface)
Build the buffers and information for the communication process.
void backward(Data &source, const Data &dest)
Communicate in the reverse direction, i.e. send from target to source.
void build(const Data &source, const Data &target, const Interface &interface)
Build the buffers and information for the communication process.
void forward(Data &data)
Forward send where target and source are the same.
Manager class for the mapping between local indices and globally unique indices.
Definition indexset.hh:218
Base class of all classes representing a communication interface.
Definition parallel/interface.hh:35
Information describing an interface.
Definition parallel/interface.hh:101
Communication interface between remote and local indices.
Definition parallel/interface.hh:209
An index present on the local process.
Definition localindex.hh:35
The indices present on remote processes.
Definition remoteindices.hh:189
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition remoteindices.hh:215
LocalIndex::Attribute Attribute
The type of the attribute.
Definition remoteindices.hh:226
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition remoteindices.hh:221
Provides classes for building the communication interface between remote indices.