source: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/scatterer_connector.hpp @ 1930

Last change on this file since 1930 was 1930, checked in by ymipsl, 4 years ago

Big update on on going work related to data distribution and transfer between clients and servers.
Revisite of the source and store filter using "connectors".

YM

  • Property svn:executable set to *
File size: 6.4 KB
Line 
1#ifndef __SCATTERER_CONNECTOR_HPP__
2#define __SCATTERER_CONNECTOR_HPP__
3
4#include "xios_spl.hpp"
5#include "array_new.hpp"
6#include "distributed_view.hpp"
7#include "mpi.hpp"
8#include "local_view.hpp"
9#include "distributed_view.hpp"
10#include "context_client.hpp"
11
12
13namespace xios
14{
15 
16  class CScattererConnector
17  {
18
19    private:
20      map<int, vector<int>> connector_ ;
21      map<int, vector<bool>> mask_ ;  // mask is on dst view
22      MPI_Comm localComm_ ;
23
24      CLocalView* srcView_ ;
25      CDistributedView* dstView_ ;
26      map<int,int> nbSenders_ ; // number of participant when sending remote buffer
27      int srcSize_ ;
28      map<int,int> dstSize_ ;
29
30    public:
31
32    CScattererConnector(CLocalView* srcView, CDistributedView* dstView, MPI_Comm localComm) 
33                       : srcView_(srcView), dstView_(dstView), localComm_(localComm) {}
34    void computeConnector(void) ;
35   
36    template<typename T, int n>
37    void transfer(const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut)
38    {
39      transfer(1, dataIn, dataOut) ;
40    }
41
42    template<typename T, int n>
43    void transfer(const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut, T missingValue)
44    {
45      transfer(1, dataIn, dataOut, missingValue) ;
46    }
47
48    template<typename T, int n>
49    void transfer(int sizeT, const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut)
50    {
51      // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
52      for(auto& rankConnector : connector_)
53      {
54        int rank = rankConnector.first ;
55        auto& connector = rankConnector.second ;
56        auto& mask = mask_[rank] ;
57        int dstSize = mask.size() ;
58        auto& data = dataOut[rank] ;
59        data.resize(dstSize * sizeT) ;
60        T* dstData = data.dataFirst() ;
61        const T* srcData = dataIn.dataFirst() ;
62        for(int i=0, j=0; i<dstSize; i++)
63          if (mask[i]) 
64          {
65            for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = srcData[connector[j]*sizeT+k] ;
66            j++ ;
67          }
68      }
69    }
70
71    template<typename T, int n>
72    void transfer(int sizeT, const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut, T missingValue)
73    {
74      // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
75      for(auto& rankConnector : connector_)
76      {
77        int rank = rankConnector.first ;
78        auto& connector = rankConnector.second ;
79        auto& mask = mask_[rank] ;
80        int dstSize = mask.size() ;
81        auto& data = dataOut[rank] ;
82        data.resize(dstSize * sizeT) ;
83        T* dstData = data.dataFirst() ;
84        const T* srcData = dataIn.dataFirst() ;
85        for(int i=0, j=0; i<dstSize; i++)
86          if (mask[i]) 
87          {
88            for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = srcData[connector[j]*sizeT+k] ;
89            j++ ;
90          }
91          else 
92          {
93            for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = missingValue ;
94            j++ ;
95          }
96      }
97    }
98   
99    template<typename T,int n>
100    void transfer(const CArray<T,n>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
101    {
102      transfer(1, dataIn, client, event, messageHeader) ;
103    }
104
105    template<typename T,int n>
106    void transfer(const CArray<T,n>& dataIn, T missingValue, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
107    {
108      transfer(1, dataIn, missingValue, client, event, messageHeader) ;
109    }
110
111    template<typename T, int n>
112    void transfer(int sizeT, const CArray<T,n>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
113    {
114      map<int, CArray<T,1>> dataOut ;
115      transfer(sizeT, dataIn, dataOut) ;
116      sendToServer(dataOut, client, event, messageHeader) ;
117    }
118
119    template<typename T, int n>
120    void transfer(int sizeT, const CArray<T,n>& dataIn, T missingValue, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
121    {
122      map<int, CArray<T,1>> dataOut ;
123      transfer(sizeT, dataIn, dataOut, missingValue) ;
124      sendToServer(dataOut, client, event, messageHeader) ;
125    }
126
127    template<typename T> 
128    void transfer(int rank, CScattererConnector** connectors, int nConnectors, const T* input, T* output)
129    {
130      auto& connector = connector_[rank] ; // probably costly, find a better way to avoid the map
131      auto& mask = mask_[rank] ; 
132      int dstSize = mask.size() ;
133      if (nConnectors==0)
134      {
135        for(int i=0, j=0; i<dstSize; i++)
136          if (mask[i]) 
137          {
138            *(output+i)=*(input+connector[j]) ;
139            j++ ;
140          }
141
142      }
143      else
144      {
145        int srcSliceSize = (*(connectors-1))->getSrcSliceSize(connectors-1, nConnectors-1) ;
146        int dstSliceSize = (*(connectors-1))->getDstSliceSize(rank, connectors-1, nConnectors-1) ;
147
148        T* out = output ; 
149        for(int i=0,j=0;i<dstSize;i++) 
150        {
151          if (mask[i]) 
152          {
153            (*(connectors-1))->transfer(rank, connectors-1, nConnectors-1, input+connector[j]*srcSliceSize, out) ; // the multiplication must be avoid in further optimization
154            j++ ;
155          }
156          out += dstSliceSize ;
157        }
158      }
159    }
160
161     
162    template<typename T>
163    void sendToServer(const map<int, CArray<T,1>>& dataOut, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
164    {
165      list<CMessage> messages;
166      for(auto ranksData : dataOut)
167      {
168        int rank = ranksData.first ;
169        auto& data = ranksData.second ;
170
171        messages.push_back(CMessage(messageHeader));
172        messages.back().push(data) ;
173        event.push(rank, nbSenders_[rank], messages.back());
174      }
175      client->sendEvent(event) ;
176    }
177
178    int getSrcSliceSize(CScattererConnector** connectors, int nConnectors) 
179    { if (nConnectors==0) return srcSize_ ; else return srcSize_ * (*(connectors-1))->getSrcSliceSize(connectors-1,nConnectors-1) ; }
180
181    int getDstSliceSize(int rank, CScattererConnector** connectors, int nConnectors) 
182    { if (nConnectors==0) return dstSize_[rank] ; else return dstSize_[rank] * (*(connectors-1))->getDstSliceSize(rank, connectors-1,nConnectors-1) ; }
183
184    const map<int,int>& getNbSenders(void) {return nbSenders_ ;} 
185    const map<int,int>& getDstSize(void) { return dstSize_ ;}
186  } ;
187} 
188
189#endif
Note: See TracBrowser for help on using the repository browser.