1#pragma GCC diagnostic ignored "-Wattributes"
2#ifndef DUNE_MMESH_MISC_COMMUNICATION_HH
3#define DUNE_MMESH_MISC_COMMUNICATION_HH
7#include <dune/common/hybridutilities.hh>
8#include <dune/grid/common/gridenums.hh>
9#include <dune/common/parallel/variablesizecommunicator.hh>
11#include "objectstream.hh"
16 template<
class Gr
id,
class MMeshType >
17 class MMeshCommunication
19 typedef MMeshCommunication< Grid, MMeshType > This;
20 typedef PartitionHelper< MMeshType > PartitionHelperType;
21 typedef typename PartitionHelperType::LinksType Links;
24 MMeshCommunication(
const This & );
25 const This &operator= (
const This & );
34 static const int dimension = Grid::dimension;
36 MMeshCommunication (
const PartitionHelperType &partitionHelper )
37 : partitionHelper_( partitionHelper ), tag_( 0 )
40 template<
class PackIterator,
class UnpackIterator,
class DataHandleImp >
41 void operator() (
const PackIterator packBegin,
const PackIterator packEnd,
42 const UnpackIterator unpackBegin,
const UnpackIterator unpackEnd,
43 DataHandleImp &dataHandle,
44 const PartitionType sendType,
const PartitionType recvType,
45 const bool packAll )
const
47 typedef MMeshImpl::ObjectStream BufferType;
48 const Links& links = partitionHelper_.links();
51 std::vector< BufferType > sendBuffers( links.size() ), recvBuffers( links.size() );
52 for(
int link = 0; link < links.size(); ++link )
54 sendBuffers[ link ].clear();
55 recvBuffers[ link ].clear();
59 for( PackIterator it = packBegin; it != packEnd; ++it )
61 const typename PackIterator::Entity &entity = *it;
62 if (entity.partitionType() == sendType && partitionHelper_.connectivity(entity).size() > 0)
64 Hybrid::forEach(std::make_index_sequence<dimension+1>{}, [&](
auto codim){
65 PackData<codim>::apply(links, partitionHelper_, dataHandle, sendBuffers, entity);
73 for( UnpackIterator it = unpackBegin; it != unpackEnd; ++it )
75 const typename UnpackIterator::Entity &entity = *it;
76 if (entity.partitionType() == recvType && partitionHelper_.connectivity(entity).size() > 0)
78 Hybrid::forEach(std::make_index_sequence<dimension+1>{}, [&](
auto codim){
79 PackData<codim>::apply(links, partitionHelper_, dataHandle, sendBuffers, entity);
86 const auto& comm = partitionHelper_.comm();
87 MPI_Request sendRequests[links.size()];
88 for (
int link = 0; link < links.size(); ++link)
90 BufferType& buf = sendBuffers[ link ];
91 int dest = links[ link ];
92 MPI_Request& request = sendRequests[ link ];
93 MPI_Isend( buf._buf, buf._wb, MPI_BYTE, dest, tag_, comm, &request );
98 std::vector<bool> received (links.size(),
false);
99 MPI_Request recvRequests[links.size()];
100 while( count < links.size() )
102 for (
int link = 0; link < links.size(); ++link)
104 if (received[ link ])
107 int source = links[ link ];
111 MPI_Iprobe( source, tag_, comm, &available, &status );
116 MPI_Get_count( &status, MPI_BYTE, &bufferSize );
118 BufferType& buf = recvBuffers[ link ];
119 buf.reserve( bufferSize );
122 MPI_Request& request = recvRequests[ link ];
123 MPI_Irecv( buf._buf, bufferSize, MPI_BYTE, source, tag_, comm, &request );
124 buf.seekp( bufferSize );
127 received[ link ] =
true;
132 MPI_Waitall( links.size(), sendRequests, MPI_STATUSES_IGNORE );
133 MPI_Waitall( links.size(), recvRequests, MPI_STATUSES_IGNORE );
136 for( UnpackIterator it = unpackBegin; it != unpackEnd; ++it )
138 const typename UnpackIterator::Entity &entity = *it;
139 if (entity.partitionType() == recvType && partitionHelper_.connectivity(entity).size() > 0)
141 Hybrid::forEach(std::make_index_sequence<dimension+1>{}, [&](
auto codim){
142 UnpackData<codim>::apply(links, partitionHelper_, dataHandle, recvBuffers, entity);
150 for( PackIterator it = packBegin; it != packEnd; ++it )
152 const typename PackIterator::Entity &entity = *it;
153 if (entity.partitionType() == sendType && partitionHelper_.connectivity(entity).size() > 0)
155 Hybrid::forEach(std::make_index_sequence<dimension+1>{}, [&](
auto codim){
156 UnpackData<codim>::apply(links, partitionHelper_, dataHandle, recvBuffers, entity);
163 if (tag_ < 0) tag_ = 0;
167 const PartitionHelperType &partitionHelper_;
174 template<
class Gr
id,
class MMeshType >
175 template<
int codim >
176 struct MMeshCommunication< Grid, MMeshType >::PackData
178 typedef typename Grid::template Codim< 0 >::Entity Element;
180 typedef typename Grid::template Codim< codim >::Entity Entity;
182 template<
class DataHandleIF,
class BufferType >
183 static void apply (
const Links& links,
184 const PartitionHelperType &partitionHelper,
185 DataHandleIF &dataHandle,
186 std::vector< BufferType > &buffer,
187 const Element &element )
190 if( !dataHandle.contains( dimension, codim ) )
193 const auto& connectivity = partitionHelper.connectivity(element);
195 const int numSubEntities = element.subEntities(codim);
196 for(
int subEntity = 0; subEntity < numSubEntities; ++subEntity )
199 const Entity &entity = element.template subEntity< codim >( subEntity );
201 for (
int link = 0; link < links.size(); ++link)
204 if (connectivity.count(links[link]) > 0 || links[link] == partitionHelper.rank(element))
206 std::size_t size = dataHandle.size( entity );
209 buffer[ link ].write( size );
212 dataHandle.gather( buffer[ link ], entity );
224 template<
class Gr
id,
class MMeshType >
225 template<
int codim >
226 struct MMeshCommunication< Grid, MMeshType >::UnpackData
228 using Element =
typename Grid::template Codim< 0 >::Entity;
230 template<
class DataHandleIF,
class BufferType >
231 static void apply (
const Links& links,
232 const PartitionHelperType &partitionHelper,
233 DataHandleIF &dataHandle,
234 std::vector< BufferType > &buffer,
235 const Element &element )
238 if( !dataHandle.contains( dimension, codim ) )
241 const auto& connectivity = partitionHelper.connectivity(element);
244 const int numSubEntities = element.subEntities(codim);
245 for(
int subEntity = 0; subEntity < numSubEntities; ++subEntity )
248 const auto& entity = element.template subEntity< codim >( subEntity );
250 for (
int link = 0; link < links.size(); ++link)
253 if (links[link] == partitionHelper.rank(element) || connectivity.count(links[link]) > 0)
256 std::size_t size( 0 );
257 buffer[ link ].read( size );
260 dataHandle.scatter( buffer[ link ], entity, size );