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

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

Solve issues for grid mask on server side.

YM

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