5#ifndef DUNE_COMMON_PARALLEL_VARIABLESIZECOMMUNICATOR_HH 
    6#define DUNE_COMMON_PARALLEL_VARIABLESIZECOMMUNICATOR_HH 
   43  template <
typename H> 
auto require(H &&h) -> 
decltype(h.fixedSize());
 
   51          std::enable_if_t<models<Concept::HasFixedSize, H>(), 
int> = 0>
 
   52constexpr bool callFixedSize(H &&handle) {
 
   53  return handle.fixedSize();
 
   64template<
class T, 
class Allocator=std::allocator<T> >
 
   72  explicit MessageBuffer(
int size)
 
   73    : buffer_(new T[
size]), size_(
size), position_(0)
 
   79  explicit MessageBuffer(
const MessageBuffer& o)
 
   80  : buffer_(new T[o.size_]), size_(o.size_), position_(o.position_)
 
   92  void write(
const T& data)
 
   94    buffer_[position_++]=data;
 
  103    data=buffer_[position_++];
 
  122    return position_==size_;
 
  130  bool hasSpaceForItems(
int noItems)
 
  132    return position_+noItems<=size_;
 
  138  std::size_t 
size()
 const 
  163  std::size_t position_;
 
  169class InterfaceTracker
 
  177  InterfaceTracker(
int rank, InterfaceInformation info, std::size_t fixedsize=0,
 
  178                   bool allocateSizes=
false)
 
  179    : 
fixedSize(fixedsize),rank_(rank), index_(), interface_(info), sizes_()
 
  183      sizes_.resize(info.size());
 
  190  void moveToNextIndex()
 
  193    assert(index_<=interface_.size());
 
  200  void increment(std::size_t i)
 
  203    assert(index_<=interface_.size());
 
  209  bool finished()
 const 
  211    return index_==interface_.size();
 
  214  void skipZeroIndices()
 
  217    while(sizes_.size() && index_!=interface_.size() &&!
size())
 
  225  std::size_t index()
 const 
  227    return interface_[index_];
 
  232  std::size_t 
size()
 const 
  234    assert(sizes_.size());
 
  235    return sizes_[index_];
 
  240  std::size_t* getSizesPointer()
 
  250    return !interface_.size();
 
  257  std::size_t indicesLeft()
 const 
  259    return interface_.size()-index_;
 
  275  std::size_t offset()
 const 
  285  InterfaceInformation interface_;
 
  286  std::vector<std::size_t> sizes_;
 
  329template<
class Allocator=std::allocator<std::pair<InterfaceInformation,InterfaceInformation> > >
 
  337  typedef std::map<int,std::pair<InterfaceInformation,InterfaceInformation>,
 
  339                   typename std::allocator_traits<Allocator>::template rebind_alloc< std::pair<const int,std::pair<InterfaceInformation,InterfaceInformation> > > > 
InterfaceMap;
 
  341#ifndef DUNE_PARALLEL_MAX_COMMUNICATION_BUFFER_SIZE 
  349    : maxBufferSize_(32768), interface_(&inf)
 
  351    MPI_Comm_dup(comm, &communicator_);
 
  358  : maxBufferSize_(32768), interface_(&inf.interfaces())
 
  370    : maxBufferSize_(DUNE_PARALLEL_MAX_COMMUNICATION_BUFFER_SIZE),
 
  373    MPI_Comm_dup(comm, &communicator_);
 
  380  : maxBufferSize_(DUNE_PARALLEL_MAX_COMMUNICATION_BUFFER_SIZE),
 
  381    interface_(&inf.interfaces())
 
  383    MPI_Comm_dup(inf.communicator(), &communicator_);
 
  393    : maxBufferSize_(max_buffer_size), interface_(&inf)
 
  395    MPI_Comm_dup(comm, &communicator_);
 
  404    : maxBufferSize_(max_buffer_size), interface_(&inf.interfaces())
 
  411    MPI_Comm_free(&communicator_);
 
  419    maxBufferSize_ = other.maxBufferSize_;
 
  420    interface_ = other.interface_;
 
  421    MPI_Comm_dup(other.communicator_, &communicator_);
 
  432    maxBufferSize_ = other.maxBufferSize_;
 
  433    interface_ = other.interface_;
 
  434    MPI_Comm_free(&communicator_);
 
  435    MPI_Comm_dup(other.communicator_, &communicator_);
 
  459  template<
class DataHandle>
 
  462    communicate<true>(handle);
 
  484  template<
class DataHandle>
 
  487    communicate<false>(handle);
 
  491  template<
bool FORWARD, 
class DataHandle>
 
  492  void communicateSizes(DataHandle& handle,
 
  493                        std::vector<InterfaceTracker>& recv_trackers);
 
  501  template<
bool forward,
class DataHandle>
 
  502  void communicate(DataHandle& handle);
 
  512  template<
bool FORWARD, 
class DataHandle>
 
  513  void setupInterfaceTrackers(DataHandle& handle,
 
  514                              std::vector<InterfaceTracker>& send_trackers,
 
  515                              std::vector<InterfaceTracker>& recv_trackers);
 
  523  template<
bool FORWARD, 
class DataHandle>
 
  524  void communicateFixedSize(DataHandle& handle);
 
  532  template<
bool FORWARD, 
class DataHandle>
 
  533  void communicateVariableSize(DataHandle& handle);
 
  540  std::size_t maxBufferSize_;
 
  554  MPI_Comm communicator_;
 
  563template<
class DataHandle>
 
  567  typedef std::size_t DataType;
 
  569  SizeDataHandle(DataHandle& data,
 
  570                 std::vector<InterfaceTracker>& trackers)
 
  571    : data_(data), trackers_(trackers), index_()
 
  577  std::size_t 
size([[maybe_unused]] std::size_t i)
 
  582  void gather(B& buf, 
int  i)
 
  584    buf.write(data_.size(i));
 
  586  void setReceivingIndex(std::size_t i)
 
  590  std::size_t* getSizesPointer()
 
  592    return trackers_[index_].getSizesPointer();
 
  597  std::vector<InterfaceTracker>& trackers_;
 
  602void setReceivingIndex(T&, 
int)
 
  606void setReceivingIndex(SizeDataHandle<T>& t, 
int i)
 
  608  t.setReceivingIndex(i);
 
  617template<
bool FORWARD>
 
  618struct InterfaceInformationChooser
 
  623  static const InterfaceInformation&
 
  624  getSend(
const std::pair<InterfaceInformation,InterfaceInformation>& info)
 
  632  static const InterfaceInformation&
 
  633  getReceive(
const std::pair<InterfaceInformation,InterfaceInformation>& info)
 
  640struct InterfaceInformationChooser<false>
 
  642  static const InterfaceInformation&
 
  643  getSend(
const std::pair<InterfaceInformation,InterfaceInformation>& info)
 
  648  static const InterfaceInformation&
 
  649  getReceive(
const std::pair<InterfaceInformation,InterfaceInformation>& info)
 
  660template<
class DataHandle>
 
  664  int operator()(DataHandle& handle, InterfaceTracker& tracker,
 
  665                 MessageBuffer<typename DataHandle::DataType>& buffer,
 
  666                 [[maybe_unused]] 
int i)
 const 
  668    return operator()(handle,tracker,buffer);
 
  678  int operator()(DataHandle& handle, InterfaceTracker& tracker,
 
  679                 MessageBuffer<typename DataHandle::DataType>& buffer)
 const 
  681    if(tracker.fixedSize) 
 
  684      std::size_t noIndices=std::min<std::size_t>(buffer.size()/tracker.fixedSize, tracker.indicesLeft());
 
  685      for(std::size_t i=0; i< noIndices; ++i)
 
  687        handle.gather(buffer, tracker.index());
 
  688        tracker.moveToNextIndex();
 
  690      return noIndices*tracker.fixedSize;
 
  695      tracker.skipZeroIndices();
 
  696      while(!tracker.finished())
 
  697        if(buffer.hasSpaceForItems(handle.size(tracker.index())))
 
  699          handle.gather(buffer, tracker.index());
 
  700          packed+=handle.size(tracker.index());
 
  701          tracker.moveToNextIndex();
 
  715template<
class DataHandle>
 
  725  bool operator()(DataHandle& handle, InterfaceTracker& tracker,
 
  726                  MessageBuffer<typename DataHandle::DataType>& buffer,
 
  729    if(tracker.fixedSize) 
 
  731      std::size_t noIndices=std::min<std::size_t>(buffer.size()/tracker.fixedSize, tracker.indicesLeft());
 
  733      for(std::size_t i=0; i< noIndices; ++i)
 
  735        handle.scatter(buffer, tracker.index(), tracker.fixedSize);
 
  736        tracker.moveToNextIndex();
 
  738      return tracker.finished();
 
  743      for(
int unpacked=0;unpacked<count;)
 
  745        assert(!tracker.finished());
 
  746        assert(buffer.hasSpaceForItems(tracker.size()));
 
  747        handle.scatter(buffer, tracker.index(), tracker.size());
 
  748        unpacked+=tracker.size();
 
  749        tracker.moveToNextIndex();
 
  751      return tracker.finished();
 
  760template<
class DataHandle>
 
  761struct UnpackSizeEntries{
 
  770  bool operator()(SizeDataHandle<DataHandle>& handle, InterfaceTracker& tracker,
 
  771                  MessageBuffer<
typename SizeDataHandle<DataHandle>::DataType>& buffer)
 const 
  773    std::size_t noIndices=std::min<std::size_t>(buffer.size(), tracker.indicesLeft());
 
  774    std::copy(
static_cast<std::size_t*
>(buffer), 
static_cast<std::size_t*
>(buffer)+noIndices,
 
  775              handle.getSizesPointer()+tracker.offset());
 
  776    tracker.increment(noIndices);
 
  779   bool operator()(SizeDataHandle<DataHandle>& handle, InterfaceTracker& tracker,
 
  780                   MessageBuffer<
typename SizeDataHandle<DataHandle>::DataType>& buffer, 
int)
 const 
  782    return operator()(handle,tracker,buffer);
 
  793void sendFixedSize(std::vector<InterfaceTracker>& send_trackers,
 
  794                   std::vector<MPI_Request>& send_requests,
 
  795                   std::vector<InterfaceTracker>& recv_trackers,
 
  796                   std::vector<MPI_Request>& recv_requests,
 
  797                   MPI_Comm communicator)
 
  799  typedef std::vector<InterfaceTracker>::iterator TIter;
 
  800  std::vector<MPI_Request>::iterator mIter=recv_requests.begin();
 
  802  for(TIter iter=recv_trackers.begin(), end=recv_trackers.end(); iter!=end;
 
  805    MPI_Irecv(&(iter->fixedSize), 1, MPITraits<std::size_t>::getType(),
 
  806              iter->rank(), 933881, communicator, &(*mIter));
 
  810  std::vector<MPI_Request>::iterator mIter1=send_requests.begin();
 
  811  for(TIter iter=send_trackers.begin(), end=send_trackers.end();
 
  815    MPI_Issend(&(iter->fixedSize), 1, MPITraits<std::size_t>::getType(),
 
  816               iter->rank(), 933881, communicator, &(*mIter1));
 
  825template<
class DataHandle>
 
  826struct SetupSendRequest{
 
  827  void operator()(DataHandle& handle,
 
  828                  InterfaceTracker& tracker,
 
  829                  MessageBuffer<typename DataHandle::DataType>& buffer,
 
  830                  MPI_Request& request,
 
  834    int size=PackEntries<DataHandle>()(handle, tracker, buffer);
 
  836    while(!tracker.finished() &&  !handle.size(tracker.index()))
 
  837      tracker.moveToNextIndex();
 
  839      MPI_Issend(buffer, 
size, MPITraits<typename DataHandle::DataType>::getType(),
 
  840                 tracker.rank(), 933399, comm, &request);
 
  849template<
class DataHandle>
 
  850struct SetupRecvRequest{
 
  851  void operator()(DataHandle& ,
 
  852                  InterfaceTracker& tracker,
 
  853                  MessageBuffer<typename DataHandle::DataType>& buffer,
 
  854                  MPI_Request& request,
 
  858    if(tracker.indicesLeft())
 
  859      MPI_Irecv(buffer, buffer.size(), MPITraits<typename DataHandle::DataType>::getType(),
 
  860                tracker.rank(), 933399, comm, &request);
 
  867template<
class DataHandle>
 
  868struct NullPackUnpackFunctor
 
  870  int operator()(DataHandle&, InterfaceTracker&,
 
  871                 MessageBuffer<typename DataHandle::DataType>&, 
int)
 
  875  int operator()(DataHandle&, InterfaceTracker&,
 
  876                 MessageBuffer<typename DataHandle::DataType>&)
 
  896template<
class DataHandle, 
class BufferFunctor, 
class CommunicationFunctor>
 
  897std::size_t checkAndContinue(DataHandle& handle,
 
  898                             std::vector<InterfaceTracker>& trackers,
 
  899                             std::vector<MPI_Request>& requests,
 
  900                             std::vector<MPI_Request>& requests2,
 
  901                             std::vector<MessageBuffer<typename DataHandle::DataType> >& buffers,
 
  903                             BufferFunctor buffer_func,
 
  904                             CommunicationFunctor comm_func,
 
  908  std::size_t 
size=requests.size();
 
  909  std::vector<MPI_Status> statuses(
size);
 
  911  std::vector<int> indices(
size, -1); 
 
  913  MPI_Testsome(
size, &(requests[0]), &no_completed, &(indices[0]), &(statuses[0]));
 
  914  indices.resize(no_completed);
 
  915  for(std::vector<int>::iterator index=indices.begin(), end=indices.end();
 
  918    InterfaceTracker& tracker=trackers[*index];
 
  919    setReceivingIndex(handle, *index);
 
  924      MPI_Get_count(&(statuses[index-indices.begin()]),
 
  925                    MPITraits<typename DataHandle::DataType>::getType(),
 
  928      buffer_func(handle, tracker, buffers[*index], count);
 
  930      buffer_func(handle, tracker, buffers[*index]);
 
  931    tracker.skipZeroIndices();
 
  932    if(!tracker.finished()){
 
  934      comm_func(handle, tracker, buffers[*index], requests2[*index], comm);
 
  935      tracker.skipZeroIndices();
 
  953template<
class DataHandle>
 
  954std::size_t receiveSizeAndSetupReceive(DataHandle& handle,
 
  955                                       std::vector<InterfaceTracker>& trackers,
 
  956                                       std::vector<MPI_Request>& size_requests,
 
  957                                       std::vector<MPI_Request>& data_requests,
 
  958                                       std::vector<MessageBuffer<typename DataHandle::DataType> >& buffers,
 
  961  return checkAndContinue(handle, trackers, size_requests, data_requests, buffers, comm,
 
  962                   NullPackUnpackFunctor<DataHandle>(), SetupRecvRequest<DataHandle>(), 
false);
 
  973template<
class DataHandle>
 
  974std::size_t checkSendAndContinueSending(DataHandle& handle,
 
  975                                        std::vector<InterfaceTracker>& trackers,
 
  976                                        std::vector<MPI_Request>& requests,
 
  977                                        std::vector<MessageBuffer<typename DataHandle::DataType> >& buffers,
 
  980  return checkAndContinue(handle, trackers, requests, requests, buffers, comm,
 
  981                          NullPackUnpackFunctor<DataHandle>(), SetupSendRequest<DataHandle>());
 
  992template<
class DataHandle>
 
  993std::size_t checkReceiveAndContinueReceiving(DataHandle& handle,
 
  994                                             std::vector<InterfaceTracker>& trackers,
 
  995                                             std::vector<MPI_Request>& requests,
 
  996                                             std::vector<MessageBuffer<typename DataHandle::DataType> >& buffers,
 
  999  return checkAndContinue(handle, trackers, requests, requests, buffers, comm,
 
 1000                          UnpackEntries<DataHandle>(), SetupRecvRequest<DataHandle>(),
 
 1001                          true, !Impl::callFixedSize(handle));
 
 1005bool validRecvRequests(
const std::vector<MPI_Request>& reqs)
 
 1007  for(std::vector<MPI_Request>::const_iterator i=reqs.begin(), end=reqs.end();
 
 1009    if(*i!=MPI_REQUEST_NULL)
 
 1024template<
class DataHandle, 
class Functor>
 
 1025std::size_t setupRequests(DataHandle& handle,
 
 1026                   std::vector<InterfaceTracker>& trackers,
 
 1027                   std::vector<MessageBuffer<typename DataHandle::DataType> >& buffers,
 
 1028                   std::vector<MPI_Request>& requests,
 
 1029                   const Functor& setupFunctor,
 
 1030                   MPI_Comm communicator)
 
 1032  typedef typename std::vector<InterfaceTracker>::iterator TIter;
 
 1033  typename std::vector<MessageBuffer<typename DataHandle::DataType> >::iterator
 
 1034    biter=buffers.begin();
 
 1035  typename std::vector<MPI_Request>::iterator riter=requests.begin();
 
 1036  std::size_t complete=0;
 
 1037  for(TIter titer=trackers.begin(), end=trackers.end(); titer!=end; ++titer, ++biter, ++riter)
 
 1039    setupFunctor(handle, *titer, *biter, *riter, communicator);
 
 1040    complete+=titer->finished();
 
 1046template<
class Allocator>
 
 1047template<
bool FORWARD, 
class DataHandle>
 
 1048void VariableSizeCommunicator<Allocator>::setupInterfaceTrackers(DataHandle& handle,
 
 1049                            std::vector<InterfaceTracker>& send_trackers,
 
 1050                            std::vector<InterfaceTracker>& recv_trackers)
 
 1052  if(interface_->
size()==0)
 
 1054  send_trackers.reserve(interface_->
size());
 
 1055  recv_trackers.reserve(interface_->
size());
 
 1058  if(Impl::callFixedSize(handle))
 
 1062  typedef typename InterfaceMap::const_iterator IIter;
 
 1063  for(IIter inf=interface_->begin(), end=interface_->end(); inf!=end; ++inf)
 
 1066    if(Impl::callFixedSize(handle) && InterfaceInformationChooser<FORWARD>::getSend(inf->second).size())
 
 1067      fixedsize=handle.size(InterfaceInformationChooser<FORWARD>::getSend(inf->second)[0]);
 
 1068    assert(!Impl::callFixedSize(handle)||fixedsize>0);
 
 1069    send_trackers.push_back(InterfaceTracker(inf->first,
 
 1070                                             InterfaceInformationChooser<FORWARD>::getSend(inf->second), fixedsize));
 
 1071    recv_trackers.push_back(InterfaceTracker(inf->first,
 
 1072                                             InterfaceInformationChooser<FORWARD>::getReceive(inf->second), fixedsize, fixedsize==0));
 
 1076template<
class Allocator>
 
 1077template<
bool FORWARD, 
class DataHandle>
 
 1078void VariableSizeCommunicator<Allocator>::communicateFixedSize(DataHandle& handle)
 
 1080  std::vector<MPI_Request> size_send_req(interface_->
size());
 
 1081  std::vector<MPI_Request> size_recv_req(interface_->
size());
 
 1083  std::vector<InterfaceTracker> send_trackers;
 
 1084  std::vector<InterfaceTracker> recv_trackers;
 
 1085  setupInterfaceTrackers<FORWARD>(handle,send_trackers, recv_trackers);
 
 1086  sendFixedSize(send_trackers,  size_send_req, recv_trackers, size_recv_req, communicator_);
 
 1088  std::vector<MPI_Request> data_send_req(interface_->
size(), MPI_REQUEST_NULL);
 
 1089  std::vector<MPI_Request> data_recv_req(interface_->
size(), MPI_REQUEST_NULL);
 
 1090  typedef typename DataHandle::DataType DataType;
 
 1091  std::vector<MessageBuffer<DataType> > send_buffers(interface_->
size(), MessageBuffer<DataType>(maxBufferSize_)),
 
 1092    recv_buffers(interface_->
size(), MessageBuffer<DataType>(maxBufferSize_));
 
 1095  setupRequests(handle, send_trackers, send_buffers, data_send_req,
 
 1096                SetupSendRequest<DataHandle>(), communicator_);
 
 1098  std::size_t no_size_to_recv,  no_to_send, no_to_recv, old_size;
 
 1099  no_size_to_recv = no_to_send = no_to_recv = old_size = interface_->
size();
 
 1102  typedef typename std::vector<InterfaceTracker>::const_iterator Iter;
 
 1103  for(Iter i=recv_trackers.begin(), end=recv_trackers.end(); i!=end; ++i)
 
 1106  for(Iter i=send_trackers.begin(), end=send_trackers.end(); i!=end; ++i)
 
 1110  while(no_size_to_recv+no_to_send+no_to_recv)
 
 1114      no_size_to_recv -= receiveSizeAndSetupReceive(handle,recv_trackers, size_recv_req,
 
 1115                                                  data_recv_req, recv_buffers,
 
 1120      no_to_send -= checkSendAndContinueSending(handle, send_trackers, data_send_req,
 
 1121                                              send_buffers, communicator_);
 
 1122    if(validRecvRequests(data_recv_req))
 
 1124      no_to_recv -= checkReceiveAndContinueReceiving(handle, recv_trackers, data_recv_req,
 
 1125                                                     recv_buffers, communicator_);
 
 1130  MPI_Waitall(size_send_req.size(), &(size_send_req[0]), MPI_STATUSES_IGNORE);
 
 1134template<
class Allocator>
 
 1135template<
bool FORWARD, 
class DataHandle>
 
 1136void VariableSizeCommunicator<Allocator>::communicateSizes(DataHandle& handle,
 
 1137                                                           std::vector<InterfaceTracker>& data_recv_trackers)
 
 1139  std::vector<InterfaceTracker> send_trackers;
 
 1140  std::vector<InterfaceTracker> recv_trackers;
 
 1141  std::size_t 
size = interface_->
size();
 
 1142  std::vector<MPI_Request> send_requests(
size, MPI_REQUEST_NULL);
 
 1143  std::vector<MPI_Request> recv_requests(
size, MPI_REQUEST_NULL);
 
 1144  std::vector<MessageBuffer<std::size_t> >
 
 1145    send_buffers(
size, MessageBuffer<std::size_t>(maxBufferSize_)),
 
 1146    recv_buffers(
size, MessageBuffer<std::size_t>(maxBufferSize_));
 
 1147  SizeDataHandle<DataHandle> size_handle(handle,data_recv_trackers);
 
 1148  setupInterfaceTrackers<FORWARD>(size_handle,send_trackers, recv_trackers);
 
 1149  setupRequests(size_handle, send_trackers, send_buffers, send_requests,
 
 1150                                SetupSendRequest<SizeDataHandle<DataHandle> >(), communicator_);
 
 1151  setupRequests(size_handle, recv_trackers, recv_buffers, recv_requests,
 
 1152                SetupRecvRequest<SizeDataHandle<DataHandle> >(), communicator_);
 
 1155  auto valid_req_func =
 
 1156    [](
const MPI_Request& req) { 
return req != MPI_REQUEST_NULL; };
 
 1158  auto size_to_send = std::count_if(send_requests.begin(), send_requests.end(),
 
 1160  auto size_to_recv = std::count_if(recv_requests.begin(), recv_requests.end(),
 
 1163  while(size_to_send+size_to_recv)
 
 1167        checkSendAndContinueSending(size_handle, send_trackers, send_requests,
 
 1168                                    send_buffers, communicator_);
 
 1174        checkAndContinue(size_handle, recv_trackers, recv_requests, recv_requests,
 
 1175                         recv_buffers, communicator_, UnpackSizeEntries<DataHandle>(),
 
 1176                         SetupRecvRequest<SizeDataHandle<DataHandle> >());
 
 1180template<
class Allocator>
 
 1181template<
bool FORWARD, 
class DataHandle>
 
 1182void VariableSizeCommunicator<Allocator>::communicateVariableSize(DataHandle& handle)
 
 1185  std::vector<InterfaceTracker> send_trackers;
 
 1186  std::vector<InterfaceTracker> recv_trackers;
 
 1187  setupInterfaceTrackers<FORWARD>(handle, send_trackers, recv_trackers);
 
 1189  std::vector<MPI_Request> send_requests(interface_->
size(), MPI_REQUEST_NULL);
 
 1190  std::vector<MPI_Request> recv_requests(interface_->
size(), MPI_REQUEST_NULL);
 
 1191  typedef typename DataHandle::DataType DataType;
 
 1192  std::vector<MessageBuffer<DataType> >
 
 1193    send_buffers(interface_->
size(), MessageBuffer<DataType>(maxBufferSize_)),
 
 1194    recv_buffers(interface_->
size(), MessageBuffer<DataType>(maxBufferSize_));
 
 1196  communicateSizes<FORWARD>(handle, recv_trackers);
 
 1198  setupRequests(handle, send_trackers, send_buffers, send_requests,
 
 1199                SetupSendRequest<DataHandle>(), communicator_);
 
 1200  setupRequests(handle, recv_trackers, recv_buffers, recv_requests,
 
 1201                SetupRecvRequest<DataHandle>(), communicator_);
 
 1204  auto valid_req_func =
 
 1205    [](
const MPI_Request& req) { 
return req != MPI_REQUEST_NULL;};
 
 1207  auto no_to_send = std::count_if(send_requests.begin(), send_requests.end(),
 
 1209  auto no_to_recv = std::count_if(recv_requests.begin(), recv_requests.end(),
 
 1211  while(no_to_send+no_to_recv)
 
 1215      no_to_send -= checkSendAndContinueSending(handle, send_trackers, send_requests,
 
 1216                                              send_buffers, communicator_);
 
 1219      no_to_recv -= checkReceiveAndContinueReceiving(handle, recv_trackers, recv_requests,
 
 1220                                                     recv_buffers, communicator_);
 
 1224template<
class Allocator>
 
 1225template<
bool FORWARD, 
class DataHandle>
 
 1226void VariableSizeCommunicator<Allocator>::communicate(DataHandle& handle)
 
 1228  if( interface_->
size() == 0)
 
 1233  if(Impl::callFixedSize(handle))
 
 1234    communicateFixedSize<FORWARD>(handle);
 
 1236    communicateVariableSize<FORWARD>(handle);
 
Communication interface between remote and local indices.
Definition: interface.hh:218
 
A buffered communicator where the amount of data sent does not have to be known a priori.
Definition: variablesizecommunicator.hh:331
 
VariableSizeCommunicator(const Interface &inf, std::size_t max_buffer_size)
Creates a communicator with a specific maximum buffer size.
Definition: variablesizecommunicator.hh:403
 
void backward(DataHandle &handle)
Communicate backwards.
Definition: variablesizecommunicator.hh:485
 
VariableSizeCommunicator(MPI_Comm comm, const InterfaceMap &inf, std::size_t max_buffer_size)
Creates a communicator with a specific maximum buffer size.
Definition: variablesizecommunicator.hh:392
 
VariableSizeCommunicator(const VariableSizeCommunicator &other)
Copy-constructs a communicator.
Definition: variablesizecommunicator.hh:418
 
void forward(DataHandle &handle)
Communicate forward.
Definition: variablesizecommunicator.hh:460
 
VariableSizeCommunicator & operator=(const VariableSizeCommunicator &other)
Copy-assignes a communicator.
Definition: variablesizecommunicator.hh:428
 
std::map< int, std::pair< InterfaceInformation, InterfaceInformation >, std::less< int >, typename std::allocator_traits< Allocator >::template rebind_alloc< std::pair< const int, std::pair< InterfaceInformation, InterfaceInformation > > > > InterfaceMap
The type of the map from process number to InterfaceInformation for sending and receiving to and from...
Definition: variablesizecommunicator.hh:339
 
VariableSizeCommunicator(MPI_Comm comm, const InterfaceMap &inf)
Creates a communicator with the default maximum buffer size.
Definition: variablesizecommunicator.hh:348
 
VariableSizeCommunicator(const Interface &inf)
Creates a communicator with the default maximum buffer size.
Definition: variablesizecommunicator.hh:357
 
Infrastructure for concepts.
 
Provides classes for building the communication interface between remote indices.
 
MPI_Comm communicator() const
Get the MPI Communicator.
Definition: interface.hh:426
 
Traits classes for mapping types onto MPI_Datatype.
 
Dune namespace.
Definition: alignedallocator.hh:13
 
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
 
constexpr std::bool_constant<(sizeof...(II)==0)> empty(std::integer_sequence< T, II... >)
Checks whether the sequence is empty.
Definition: integersequence.hh:80
 
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:264