3#ifndef DUNE_COMMUNICATOR
4#define DUNE_COMMUNICATOR
169 template<
class K,
class A,
int n>
247 DatatypeCommunicator();
252 ~DatatypeCommunicator();
280 template<
class T1,
class T2,
class V>
281 void build(
const RemoteIndices& remoteIndices,
const T1& sourceFlags, V& sendData,
const T2& destFlags, V& receiveData);
310 typedef std::map<int,std::pair<MPI_Datatype,MPI_Datatype> >
316 MessageTypeMap messageTypes;
323 MPI_Request* requests_[2];
333 template<
class V,
bool FORWARD>
334 void createRequests(V& sendData, V& receiveData);
339 template<
class T1,
class T2,
class V,
bool send>
340 void createDataTypes(
const T1& source,
const T2& destination, V& data);
345 void sendRecv(MPI_Request* req);
350 struct IndexedTypeInformation
360 displ =
new MPI_Aint[i];
394 struct MPIDatatypeInformation
400 MPIDatatypeInformation(
const V& data) : data_(data)
408 void reserve(
int proc,
int size)
410 information_[proc].build(size);
418 void add(
int proc,
int local)
420 IndexedTypeInformation& info=information_[proc];
421 assert((info.elements)<info.size);
422 MPI_Get_address(
const_cast<void*
>(CommPolicy<V>::getAddress(data_, local)),
423 info.displ+info.elements);
424 info.length[info.elements]=CommPolicy<V>::getSize(data_, local);
432 std::map<int,IndexedTypeInformation> information_;
466 template<
class Data,
class Interface>
467 typename std::enable_if<std::is_same<SizeOne,typename CommPolicy<Data>::IndexedTypeFlag>::value,
void>::type
477 template<
class Data,
class Interface>
508 template<
class GatherScatter,
class Data>
539 template<
class GatherScatter,
class Data>
567 template<
class GatherScatter,
class Data>
595 template<
class GatherScatter,
class Data>
613 typedef std::map<int,std::pair<InterfaceInformation,InterfaceInformation> >
620 template<
class Data,
typename IndexedTypeFlag>
621 struct MessageSizeCalculator
629 struct MessageSizeCalculator<Data,
SizeOne>
654 struct MessageSizeCalculator<Data,VariableSize>
664 inline int operator()(
const Data& data,
const InterfaceInformation& info)
const;
670 template<
class Data,
class GatherScatter,
bool send,
typename IndexedTypeFlag>
671 struct MessageGatherer
678 template<
class Data,
class GatherScatter,
bool send>
679 struct MessageGatherer<Data,GatherScatter,send,SizeOne>
688 typedef GatherScatter Gatherer;
706 inline void operator()(
const InterfaceMap& interface,
const Data& data, Type* buffer,
size_t bufferSize)
const;
713 template<
class Data,
class GatherScatter,
bool send>
714 struct MessageGatherer<Data,GatherScatter,send,VariableSize>
723 typedef GatherScatter Gatherer;
741 inline void operator()(
const InterfaceMap& interface,
const Data& data, Type* buffer,
size_t bufferSize)
const;
747 template<
class Data,
class GatherScatter,
bool send,
typename IndexedTypeFlag>
748 struct MessageScatterer
755 template<
class Data,
class GatherScatter,
bool send>
756 struct MessageScatterer<Data,GatherScatter,send,SizeOne>
765 typedef GatherScatter Scatterer;
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;
817 inline void operator()(
const InterfaceMap& interface, Data& data, Type* buffer,
const int& proc)
const;
823 struct MessageInformation
827 : start_(0), size_(0)
837 MessageInformation(
size_t start,
size_t size)
838 : start_(start), size_(
size)
856 typedef std::map<int,std::pair<MessageInformation,MessageInformation> >
861 InformationMap messageInformation_;
869 size_t bufferSize_[2];
881 std::map<int,std::pair<InterfaceInformation,InterfaceInformation> > interfaces_;
883 MPI_Comm communicator_;
888 template<
class GatherScatter,
bool FORWARD,
class Data>
889 void sendRecv(
const Data& source, Data& target);
909 template<
class K,
class A,
int n>
910 inline const void* CommPolicy<VariableBlockVector<FieldVector<K, n>, A> >::getAddress(
const Type& v,
int index)
912 return &(v[index][0]);
915 template<
class K,
class A,
int n>
916 inline int CommPolicy<VariableBlockVector<FieldVector<K, n>, A> >::getSize(
const Type& v,
int index)
918 return v[index].getsize();
922 inline const typename CopyGatherScatter<T>::IndexedType& CopyGatherScatter<T>::gather(
const T & vec, std::size_t i)
928 inline void CopyGatherScatter<T>::scatter(T& vec,
const IndexedType& v, std::size_t i)
934 DatatypeCommunicator<T>::DatatypeCommunicator()
935 : remoteIndices_(0), created_(false)
944 DatatypeCommunicator<T>::~DatatypeCommunicator()
950 template<
class T1,
class T2,
class V>
951 inline void DatatypeCommunicator<T>::build(
const RemoteIndices& remoteIndices,
952 const T1& source, V& sendData,
953 const T2& destination, V& receiveData)
955 remoteIndices_ = &remoteIndices;
957 createDataTypes<T1,T2,V,false>(source,destination, receiveData);
958 createDataTypes<T1,T2,V,true>(source,destination, sendData);
959 createRequests<V,true>(sendData, receiveData);
960 createRequests<V,false>(receiveData, sendData);
965 void DatatypeCommunicator<T>::free()
968 delete[] requests_[0];
969 delete[] requests_[1];
970 typedef MessageTypeMap::iterator iterator;
971 typedef MessageTypeMap::const_iterator const_iterator;
973 const const_iterator end=messageTypes.end();
975 for(iterator process = messageTypes.begin(); process != end; ++process) {
976 MPI_Datatype *type = &(process->second.first);
978 MPI_Finalized(&finalized);
979 if(*type!=MPI_DATATYPE_NULL && !finalized)
981 type = &(process->second.second);
982 if(*type!=MPI_DATATYPE_NULL && !finalized)
985 messageTypes.clear();
992 template<
class T1,
class T2,
class V,
bool send>
993 void DatatypeCommunicator<T>::createDataTypes(
const T1& sourceFlags,
const T2& destFlags, V& data)
996 MPIDatatypeInformation<V> dataInfo(data);
997 this->
template buildInterface<RemoteIndices,T1,T2,MPIDatatypeInformation<V>,send>(*remoteIndices_,sourceFlags, destFlags, dataInfo);
999 typedef typename RemoteIndices::RemoteIndexMap::const_iterator const_iterator;
1000 const const_iterator end=this->remoteIndices_->end();
1003 for(const_iterator process=this->remoteIndices_->begin(); process != end; ++process) {
1004 IndexedTypeInformation& info=dataInfo.information_[process->first];
1009 for(
int i=0; i< info.elements; i++) {
1010 info.displ[i]-=base;
1014 MPI_Datatype* type = &( send ? messageTypes[process->first].first : messageTypes[process->first].second);
1015 MPI_Type_create_hindexed(info.elements, info.length, info.displ,
1017 MPI_Type_commit(type);
1023 template<
typename T>
1024 template<
class V,
bool createForward>
1025 void DatatypeCommunicator<T>::createRequests(V& sendData, V& receiveData)
1027 typedef std::map<int,std::pair<MPI_Datatype,MPI_Datatype> >::const_iterator MapIterator;
1029 static int index = createForward ? 1 : 0;
1030 int noMessages = messageTypes.size();
1032 requests_[index] =
new MPI_Request[2*noMessages];
1033 const MapIterator end = messageTypes.end();
1035 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1038 for(MapIterator process = messageTypes.begin(); process != end;
1039 ++process, ++request) {
1040 MPI_Datatype type = createForward ? process->second.second : process->second.first;
1042 MPI_Recv_init(address, 1, type, process->first, commTag_, this->remoteIndices_->communicator(), requests_[index]+request);
1047 for(MapIterator process = messageTypes.begin(); process != end;
1048 ++process, ++request) {
1049 MPI_Datatype type = createForward ? process->second.first : process->second.second;
1051 MPI_Ssend_init(address, 1, type, process->first, commTag_, this->remoteIndices_->communicator(), requests_[index]+request);
1055 template<
typename T>
1056 void DatatypeCommunicator<T>::forward()
1058 sendRecv(requests_[1]);
1061 template<
typename T>
1062 void DatatypeCommunicator<T>::backward()
1064 sendRecv(requests_[0]);
1067 template<
typename T>
1068 void DatatypeCommunicator<T>::sendRecv(MPI_Request* requests)
1070 int noMessages = messageTypes.size();
1072 MPI_Startall(noMessages, requests);
1074 MPI_Startall(noMessages, requests+noMessages);
1077 MPI_Status* status=
new MPI_Status[2*noMessages];
1078 for(
int i=0; i<2*noMessages; i++)
1079 status[i].MPI_ERROR=MPI_SUCCESS;
1081 int send = MPI_Waitall(noMessages, requests+noMessages, status+noMessages);
1082 int receive = MPI_Waitall(noMessages, requests, status);
1085 int success=1, globalSuccess=0;
1086 if(send==MPI_ERR_IN_STATUS) {
1088 MPI_Comm_rank(this->remoteIndices_->communicator(), &rank);
1089 std::cerr<<rank<<
": Error in sending :"<<std::endl;
1091 for(
int i=noMessages; i< 2*noMessages; i++)
1092 if(status[i].MPI_ERROR!=MPI_SUCCESS) {
1095 MPI_Error_string(status[i].MPI_ERROR, message, &messageLength);
1096 std::cerr<<
" source="<<status[i].MPI_SOURCE<<
" message: ";
1097 for(
int j = 0; j < messageLength; j++)
1098 std::cout << message[j];
1100 std::cerr<<std::endl;
1104 if(receive==MPI_ERR_IN_STATUS) {
1106 MPI_Comm_rank(this->remoteIndices_->communicator(), &rank);
1107 std::cerr<<rank<<
": Error in receiving!"<<std::endl;
1109 for(
int i=0; i< noMessages; i++)
1110 if(status[i].MPI_ERROR!=MPI_SUCCESS) {
1113 MPI_Error_string(status[i].MPI_ERROR, message, &messageLength);
1114 std::cerr<<
" source="<<status[i].MPI_SOURCE<<
" message: ";
1115 for(
int j = 0; j < messageLength; j++)
1116 std::cerr << message[j];
1118 std::cerr<<std::endl;
1122 MPI_Allreduce(&success, &globalSuccess, 1, MPI_INT, MPI_MIN, this->remoteIndices_->communicator());
1127 DUNE_THROW(CommunicationError,
"A communication error occurred!");
1139 template<
class Data,
class Interface>
1140 typename std::enable_if<std::is_same<SizeOne, typename CommPolicy<Data>::IndexedTypeFlag>::value,
void>::type
1143 interfaces_=interface.interfaces();
1144 communicator_=interface.communicator();
1145 typedef typename std::map<int,std::pair<InterfaceInformation,InterfaceInformation> >
1146 ::const_iterator const_iterator;
1148 const const_iterator end = interfaces_.end();
1150 MPI_Comm_rank(communicator_, &lrank);
1155 for(const_iterator interfacePair = interfaces_.begin();
1156 interfacePair != end; ++interfacePair) {
1157 int noSend = MessageSizeCalculator<Data,Flag>() (interfacePair->second.first);
1158 int noRecv = MessageSizeCalculator<Data,Flag>() (interfacePair->second.second);
1159 if (noSend + noRecv > 0)
1160 messageInformation_.insert(std::make_pair(interfacePair->first,
1161 std::make_pair(MessageInformation(bufferSize_[0],
1163 MessageInformation(bufferSize_[1],
1165 bufferSize_[0] += noSend;
1166 bufferSize_[1] += noRecv;
1173 buffers_[0] =
new char[bufferSize_[0]];
1174 buffers_[1] =
new char[bufferSize_[1]];
1177 template<
class Data,
class Interface>
1181 interfaces_=interface.interfaces();
1182 communicator_=interface.communicator();
1183 typedef typename std::map<int,std::pair<InterfaceInformation,InterfaceInformation> >
1184 ::const_iterator const_iterator;
1186 const const_iterator end = interfaces_.end();
1191 for(const_iterator interfacePair = interfaces_.begin();
1192 interfacePair != end; ++interfacePair) {
1193 int noSend = MessageSizeCalculator<Data,Flag>() (source, interfacePair->second.first);
1194 int noRecv = MessageSizeCalculator<Data,Flag>() (dest, interfacePair->second.second);
1195 if (noSend + noRecv > 0)
1196 messageInformation_.insert(std::make_pair(interfacePair->first,
1197 std::make_pair(MessageInformation(bufferSize_[0],
1199 MessageInformation(bufferSize_[1],
1201 bufferSize_[0] += noSend;
1202 bufferSize_[1] += noRecv;
1208 buffers_[0] =
new char[bufferSize_[0]];
1209 buffers_[1] =
new char[bufferSize_[1]];
1214 messageInformation_.clear();
1216 delete[] buffers_[0];
1219 delete[] buffers_[1];
1220 buffers_[0]=buffers_[1]=0;
1228 template<
class Data>
1229 inline int BufferedCommunicator::MessageSizeCalculator<Data,SizeOne>::operator()
1230 (
const InterfaceInformation& info)
const
1236 template<
class Data>
1237 inline int BufferedCommunicator::MessageSizeCalculator<Data,SizeOne>::operator()
1238 (
const Data&,
const InterfaceInformation& info)
const
1240 return operator()(info);
1244 template<
class Data>
1245 inline int BufferedCommunicator::MessageSizeCalculator<Data, VariableSize>::operator()
1246 (
const Data& data,
const InterfaceInformation& info)
const
1250 for(
size_t i=0; i < info.size(); i++)
1257 template<
class Data,
class GatherScatter,
bool FORWARD>
1258 inline void BufferedCommunicator::MessageGatherer<Data,GatherScatter,FORWARD,VariableSize>::operator()(
const InterfaceMap& interfaces,
const Data& data, Type* buffer,
size_t bufferSize)
const
1261 typedef typename InterfaceMap::const_iterator
1265 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1266 const const_iterator end = interfaces.end();
1269 for(const_iterator interfacePair = interfaces.begin();
1270 interfacePair != end; ++interfacePair) {
1271 int size = forward ? interfacePair->second.first.size() :
1272 interfacePair->second.second.size();
1274 for(
int i=0; i <
size; i++) {
1275 int local = forward ? interfacePair->second.first[i] :
1276 interfacePair->second.second[i];
1277 for(std::size_t j=0; j < CommPolicy<Data>::getSize(data, local); j++, index++) {
1279#ifdef DUNE_ISTL_WITH_CHECKING
1282 buffer[index]=GatherScatter::gather(data, local, j);
1291 template<
class Data,
class GatherScatter,
bool FORWARD>
1292 inline void BufferedCommunicator::MessageGatherer<Data,GatherScatter,FORWARD,SizeOne>::operator()(
const InterfaceMap& interfaces,
const Data& data, Type* buffer,
size_t bufferSize)
const
1295 typedef typename InterfaceMap::const_iterator
1297 const const_iterator end = interfaces.end();
1301 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1303 for(const_iterator interfacePair = interfaces.begin();
1304 interfacePair != end; ++interfacePair) {
1305 size_t size = FORWARD ? interfacePair->second.first.size() :
1306 interfacePair->second.second.size();
1308 for(
size_t i=0; i <
size; i++) {
1310#ifdef DUNE_ISTL_WITH_CHECKING
1314 buffer[index++] = GatherScatter::gather(data, FORWARD ? interfacePair->second.first[i] :
1315 interfacePair->second.second[i]);
1322 template<
class Data,
class GatherScatter,
bool FORWARD>
1323 inline void BufferedCommunicator::MessageScatterer<Data,GatherScatter,FORWARD,VariableSize>::operator()(
const InterfaceMap& interfaces, Data& data, Type* buffer,
const int& proc)
const
1325 typedef typename InterfaceMap::value_type::second_type::first_type Information;
1326 const typename InterfaceMap::const_iterator infoPair = interfaces.find(proc);
1328 assert(infoPair!=interfaces.end());
1330 const Information& info = FORWARD ? infoPair->second.second :
1331 infoPair->second.first;
1333 for(
size_t i=0, index=0; i < info.size(); i++) {
1334 for(
size_t j=0; j < CommPolicy<Data>::getSize(data, info[i]); j++)
1335 GatherScatter::scatter(data, buffer[index++], info[i], j);
1340 template<
class Data,
class GatherScatter,
bool FORWARD>
1341 inline void BufferedCommunicator::MessageScatterer<Data,GatherScatter,FORWARD,SizeOne>::operator()(
const InterfaceMap& interfaces, Data& data, Type* buffer,
const int& proc)
const
1343 typedef typename InterfaceMap::value_type::second_type::first_type Information;
1344 const typename InterfaceMap::const_iterator infoPair = interfaces.find(proc);
1346 assert(infoPair!=interfaces.end());
1348 const Information& info = FORWARD ? infoPair->second.second :
1349 infoPair->second.first;
1351 for(
size_t i=0; i < info.size(); i++) {
1352 GatherScatter::scatter(data, buffer[i], info[i]);
1357 template<
class GatherScatter,
class Data>
1360 this->
template sendRecv<GatherScatter,true>(data, data);
1364 template<
class GatherScatter,
class Data>
1367 this->
template sendRecv<GatherScatter,false>(data, data);
1371 template<
class GatherScatter,
class Data>
1374 this->
template sendRecv<GatherScatter,true>(source, dest);
1378 template<
class GatherScatter,
class Data>
1381 this->
template sendRecv<GatherScatter,false>(dest, source);
1385 template<
class GatherScatter,
bool FORWARD,
class Data>
1386 void BufferedCommunicator::sendRecv(
const Data& source, Data& dest)
1390 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
1391 MPI_Comm_rank(MPI_COMM_WORLD,&lrank);
1394 Type *sendBuffer, *recvBuffer;
1395 size_t sendBufferSize;
1397 size_t recvBufferSize;
1401 sendBuffer =
reinterpret_cast<Type*
>(buffers_[0]);
1402 sendBufferSize = bufferSize_[0];
1403 recvBuffer =
reinterpret_cast<Type*
>(buffers_[1]);
1405 recvBufferSize = bufferSize_[1];
1408 sendBuffer =
reinterpret_cast<Type*
>(buffers_[1]);
1409 sendBufferSize = bufferSize_[1];
1410 recvBuffer =
reinterpret_cast<Type*
>(buffers_[0]);
1412 recvBufferSize = bufferSize_[0];
1417 MessageGatherer<Data,GatherScatter,FORWARD,Flag>() (interfaces_, source, sendBuffer, sendBufferSize);
1419 MPI_Request* sendRequests =
new MPI_Request[messageInformation_.size()];
1420 MPI_Request* recvRequests =
new MPI_Request[messageInformation_.size()];
1422 size_t numberOfRealRecvRequests = 0;
1425 typedef typename InformationMap::const_iterator const_iterator;
1427 const const_iterator end = messageInformation_.end();
1429 int* processMap =
new int[messageInformation_.size()];
1431 for(const_iterator info = messageInformation_.begin(); info != end; ++info, ++i) {
1432 processMap[i]=info->first;
1435 Dune::dvverb<<rank<<
": receiving "<<info->second.second.size_<<
" from "<<info->first<<std::endl;
1436 if(info->second.second.size_) {
1437 MPI_Irecv(recvBuffer+info->second.second.start_, info->second.second.size_,
1438 MPI_BYTE, info->first, commTag_, communicator_,
1440 numberOfRealRecvRequests += 1;
1443 recvRequests[i]=MPI_REQUEST_NULL;
1447 Dune::dvverb<<rank<<
": receiving "<<info->second.first.size_<<
" to "<<info->first<<std::endl;
1448 if(info->second.first.size_) {
1449 MPI_Irecv(recvBuffer+info->second.first.start_, info->second.first.size_,
1450 MPI_BYTE, info->first, commTag_, communicator_,
1452 numberOfRealRecvRequests += 1;
1455 recvRequests[i]=MPI_REQUEST_NULL;
1462 for(const_iterator info = messageInformation_.begin(); info != end; ++info, ++i)
1465 Dune::dvverb<<rank<<
": sending "<<info->second.first.size_<<
" to "<<info->first<<std::endl;
1467 if(info->second.first.size_)
1468 MPI_Issend(sendBuffer+info->second.first.start_, info->second.first.size_,
1469 MPI_BYTE, info->first, commTag_, communicator_,
1473 sendRequests[i]=MPI_REQUEST_NULL;
1476 Dune::dvverb<<rank<<
": sending "<<info->second.second.size_<<
" to "<<info->first<<std::endl;
1477 if(info->second.second.size_)
1478 MPI_Issend(sendBuffer+info->second.second.start_, info->second.second.size_,
1479 MPI_BYTE, info->first, commTag_, communicator_,
1483 sendRequests[i]=MPI_REQUEST_NULL;
1489 int finished = MPI_UNDEFINED;
1493 for(i=0; i< numberOfRealRecvRequests; i++) {
1494 status.MPI_ERROR=MPI_SUCCESS;
1495 MPI_Waitany(messageInformation_.size(), recvRequests, &finished, &status);
1496 assert(finished != MPI_UNDEFINED);
1498 if(status.MPI_ERROR==MPI_SUCCESS) {
1499 int& proc = processMap[finished];
1500 typename InformationMap::const_iterator infoIter = messageInformation_.find(proc);
1501 assert(infoIter != messageInformation_.end());
1503 MessageInformation info = (FORWARD) ? infoIter->second.second : infoIter->second.first;
1504 assert(info.start_+info.size_ <= recvBufferSize);
1506 MessageScatterer<Data,GatherScatter,FORWARD,Flag>() (interfaces_, dest, recvBuffer+info.start_, proc);
1508 std::cerr<<rank<<
": MPI_Error occurred while receiving message from "<<processMap[finished]<<std::endl;
1513 MPI_Status recvStatus;
1516 for(i=0; i< messageInformation_.size(); i++)
1517 if(MPI_SUCCESS!=MPI_Wait(sendRequests+i, &recvStatus)) {
1518 std::cerr<<rank<<
": MPI_Error occurred while sending message to "<<processMap[finished]<<std::endl;
1528 delete[] processMap;
1529 delete[] sendRequests;
1530 delete[] recvRequests;
Provides classes for building the communication interface between remote indices.
Classes describing a distributed indexset.
Traits for type conversions and type information.
Standard Dune debug streams.
A few common exception classes.
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition unused.hh:18
#define DUNE_THROW(E, m)
Definition exceptions.hh:216
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition stdstreams.hh:93
Dune namespace.
Definition alignment.hh:11
constexpr auto size(const Dune::FieldVector< T, i > *, const PriorityTag< 5 > &) -> decltype(std::integral_constant< std::size_t, i >())
Definition hybridutilities.hh:22
Default exception class for I/O errors.
Definition exceptions.hh:229
Flag for marking indexed data structures where data at each index is of the same size.
Definition communicator.hh:102
Flag for marking indexed data structures where the data at each index may be a variable multiple of a...
Definition communicator.hh:110
Default policy used for communicating an indexed type.
Definition communicator.hh:120
V::value_type IndexedType
The type we get at each index with operator[].
Definition communicator.hh:139
static int getSize(const V &, int index)
Get the number of primitve 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:145
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:132
Definition communicator.hh:165
Definition communicator.hh:167
static int getSize(const Type &v, int i)
VariableSize IndexedTypeFlag
Definition communicator.hh:176
VariableBlockVector< FieldVector< K, n >, A > Type
Definition communicator.hh:172
static const void * getAddress(const Type &v, int i)
Type::B IndexedType
Definition communicator.hh:174
Error thrown if there was a problem with the communication.
Definition communicator.hh:187
GatherScatter default implementation that just copies data.
Definition communicator.hh:194
static void scatter(T &vec, const IndexedType &v, std::size_t i)
CommPolicy< T >::IndexedType IndexedType
Definition communicator.hh:195
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:452
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:217
Base class of all classes representing a communication interface.
Definition interface.hh:33
Information describing an interface.
Definition interface.hh:99
Communication interface between remote and local indices.
Definition interface.hh:207
An index present on the local process.
Definition localindex.hh:33
The indices present on remote processes.
Definition remoteindices.hh:181
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition remoteindices.hh:207
LocalIndex::Attribute Attribute
The type of the attribute.
Definition remoteindices.hh:218
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition remoteindices.hh:213