Commit a9c7adbb authored by Nils-Arne Dreier's avatar Nils-Arne Dreier

make the communication pattern only hold one map from process number to indices

parent e27c0833
Pipeline #21125 failed with stage
in 8 minutes and 17 seconds
......@@ -92,35 +92,42 @@ namespace Dune {
public:
typedef Attribute attribute_type;
typedef RemoteType remote_type;
typedef IndexContainer index_container;
typedef typename IndexContainer::value_type index_type;
typedef std::map<RemoteType, IndexContainer> map_remote_to_pattern;
typedef std::map<RemoteType, IndexContainer> map_remote_to_indices;
CommunicationPattern(const remote_type& me)
: me_(me)
{}
CommunicationPattern(const remote_type& me,
std::initializer_list<typename map_remote_to_pattern::value_type> sendInterface,
std::initializer_list<typename map_remote_to_pattern::value_type> recvInterface)
std::initializer_list<typename map_remote_to_indices::value_type> pattern)
: me_(me)
, sendPattern_(sendInterface)
, recvPattern_(recvInterface)
, pattern_(pattern)
{}
map_remote_to_pattern& sendPattern(){
return sendPattern_;
index_container& operator[](const remote_type& r){
return pattern_[r];
}
map_remote_to_pattern& recvPattern(){
return recvPattern_;
const index_container& operator[](const remote_type& r) const{
return pattern_[r];
}
const map_remote_to_pattern& sendPattern() const {
return sendPattern_;
auto begin(){
return pattern_.begin();
}
const map_remote_to_pattern& recvPattern() const{
return recvPattern_;
auto begin() const{
return pattern_.begin();
}
auto end(){
return pattern_.end();
}
auto end() const {
return pattern_.end();
}
const remote_type& me() const {
......@@ -128,16 +135,28 @@ namespace Dune {
}
void strip(){
stripPattern(sendPattern_);
stripPattern(recvPattern_);
stripPattern(pattern_);
}
// extracts a subset of indices with given local attribute
template<class LocalAttributeSet>
std::set<size_t> getSubSet(LocalAttributeSet localAttributeSet){
std::set<size_t> set;
for(const auto& pair : pattern_){
for(const auto& index : pair.second){
if(localAttributeSet.contains(index.localAttribute()) &&
remoteAttributeSet.contains(index.remoteAttribute()))
set.insert(index);
}
}
return set;
}
protected:
remote_type me_;
map_remote_to_pattern sendPattern_;
map_remote_to_pattern recvPattern_;
map_remote_to_indices pattern_;
static void stripPattern(map_remote_to_pattern& pattern){
static void stripPattern(map_remote_to_indices& pattern){
for(auto it = pattern.begin(); it != pattern.end();){
if(it->second.size() == 0)
it = pattern.erase(it);
......@@ -150,17 +169,7 @@ namespace Dune {
template<class RemoteType, class IndexType>
inline std::ostream& operator<<(std::ostream& os, const CommunicationPattern<RemoteType, IndexType>& pattern)
{
os << "send pattern:" << std::endl;
for(const auto& pair : pattern.sendPattern()){
os << pair.first << ": [";
for(const auto& idx : pair.second){
os << idx << " ";
}
os << "]" << std::endl;
}
os << "recv pattern:" << std::endl;
for(const auto& pair : pattern.recvPattern()){
for(const auto& pair : pattern){
os << pair.first << ": [";
for(const auto& idx : pair.second){
os << idx << " ";
......@@ -182,17 +191,18 @@ namespace Dune {
commPattern(communication.rank());
// fill the patterns
auto& sendPatterns = commPattern.sendPattern();
auto& recvPatterns = commPattern.recvPattern();
for(const auto& process : remoteIndices){
auto remote = process.first;
auto& spattern = sendPatterns[remote];
auto& rpattern = recvPatterns[remote];
for(const auto& indexPair : *process.second.first){
spattern.push_back({indexPair.localIndexPair().local().local(),indexPair.localIndexPair().local().attribute(), indexPair.attribute()});
}
for(const auto& indexPair : *process.second.second){
rpattern.push_back({indexPair.localIndexPair().local().local(),indexPair.localIndexPair().local().attribute(), indexPair.attribute()});
auto& indices = commPattern[remote];
if(remote < communication.rank()){ // the ordering of the indices that the smaller process
// sends to the larger on is the order we obtain here
for(const auto& indexPair : *process.second.first){
indices.push_back({indexPair.localIndexPair().local().local(),indexPair.localIndexPair().local().attribute(), indexPair.attribute()});
}
}else{
for(const auto& indexPair : *process.second.second){
indices.push_back({indexPair.localIndexPair().local().local(),indexPair.localIndexPair().local().attribute(), indexPair.attribute()});
}
}
}
commPattern.strip();
......
......@@ -52,7 +52,7 @@ namespace Dune {
SCATTERFUN scatter,
int tag = 4711){
// setup send futures
for(const auto& pair : pattern_->sendPattern()){
for(const auto& pair : *pattern_){
const remote_type& remote = pair.first;
auto& future = sendFutures_[remote][tag];
auto& buffer = sendBuffers_[remote][tag];
......@@ -64,7 +64,7 @@ namespace Dune {
}
future = comm_.template isend<Buffer&>(buffer, remote, tag);
}
for(const auto& pair : pattern_->recvPattern()){
for(const auto& pair : *pattern_){
const remote_type& remote = pair.first;
auto& buffer = recvBuffers_[remote][tag];
comm_.rrecv(buffer, remote, tag);
......
......@@ -23,20 +23,10 @@ int main(int argc, char** argv){
{1, {{4, A::overlap, A::owner},
{3, A::owner, A::overlap},
{1, A::owner, A::copy}}}
},
{// receive pattern:
{3, {{1, A::owner, A::overlap},
{4, A::owner, A::copy},
{7, A::overlap, A::owner}}},
{1, {{4, A::overlap, A::owner},
{3, A::owner, A::overlap},
{1, A::owner, A::copy}}}
}
);
});
// add manually
pattern.sendPattern()[3].push_back({6, A::owner, A::overlap});
pattern.recvPattern()[666].push_back({0, A::owner, A::owner});
pattern[3].push_back({6, A::owner, A::overlap});
pattern.strip();
std::cout << pattern << std::endl;
......
......@@ -21,21 +21,20 @@ int main(int argc, char** argv){
using A=CommunicationAttributes;
// setup pattern
CommunicationPattern<> ringPattern(rank,
{ // send pattern:
{(rank+1)%size,
{{0, A::owner, A::copy},
{1, A::owner, A::overlap},
{2, A::overlap, A::owner},
{3, A::copy, A::owner}}
}},
{ // recv pattern
{(rank+size-1)%size,
{{2, A::overlap, A::owner},
{3, A::copy, A::owner},
{0, A::owner, A::copy},
{1, A::owner, A::overlap}}
}});
CommunicationPattern<> ringPattern(rank);
ringPattern[(rank+1)%size] = // right neighbor
{{2, A::overlap, A::owner},
{3, A::copy, A::owner}};
// use insert to cover the case where size==1 or size==2
// (then both neighbors are the same)
auto insert_it = ringPattern[(rank-1+size)%size].begin();
if(size==2 && rank==1)
insert_it = ringPattern[(rank-1+size)%size].end();
ringPattern[(rank-1+size)%size].insert( // left neighbor
insert_it,
{{0, A::owner, A::overlap},
{1, A::owner, A::copy}
});
std::cout << ringPattern << std::endl;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment