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

Last change on this file since 2230 was 2118, checked in by jderouillat, 3 years ago

Enable GNU compilation

  • Property svn:executable set to *
File size: 7.2 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,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, 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      transfer(1, sizeT, dataIn, dataOut);
53    }
54   
55    template<typename T, int n>
56    void transfer(int repeat, int sizeT, const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut)
57    {
58      // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
59      size_t srcSlice = sizeT*srcSize_ ;
60      for(auto& rankConnector : connector_)
61      {
62        int rank = rankConnector.first ;
63        auto& connector = rankConnector.second ;
64        auto& mask = mask_[rank] ;
65        int dstSize = mask.size() ;
66        auto& data = dataOut[rank] ;
67        size_t dstSlice = dstSize*sizeT ;
68        data.resize(repeat*dstSlice) ;
69        T* dstData = data.dataFirst() ;
70        const T* srcData = dataIn.dataFirst() ;
71        for(int l=0; l<repeat; l++)
72        {
73          for(int i=0, j=0; i<dstSize; i++)
74            if (mask[i]) 
75            {
76              for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = srcData[connector[j]*sizeT+k] ;
77              j++ ;
78            }
79          dstData+=dstSlice ;
80          srcData+=srcSlice ;
81        }
82      }
83    }
84
85    template<typename T, int n>
86    void transfer(int repeat, int sizeT, const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut, T missingValue)
87    {
88      // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
89      size_t srcSlice = sizeT*srcSize_ ;
90      for(auto& rankConnector : connector_)
91      {
92        int rank = rankConnector.first ;
93        auto& connector = rankConnector.second ;
94        auto& mask = mask_[rank] ;
95        int dstSize = mask.size() ;
96        auto& data = dataOut[rank] ;
97        size_t dstSlice = dstSize*sizeT ;
98        data.resize(repeat * dstSlice) ;
99        T* dstData = data.dataFirst() ;
100        const T* srcData = dataIn.dataFirst() ;
101        for(int l=0; l<repeat; l++)
102        {
103          for(int i=0, j=0; i<dstSize; i++)
104            if (mask[i]) 
105            {
106              for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = srcData[connector[j]*sizeT+k] ;
107              j++ ;
108            }
109            else 
110            {
111              for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = missingValue ;
112              j++ ;
113            }
114          dstData+=dstSlice ;
115          srcData+=srcSlice ;
116        }
117      }
118    }
119   
120    template<typename T,int n>
121    void transfer(const CArray<T,n>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
122    {
123      transfer( 1, dataIn, client, event, messageHeader) ;
124    }
125
126    template<typename T,int n>
127    void transfer(const CArray<T,n>& dataIn, T missingValue, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
128    {
129      transfer( 1, dataIn, missingValue, client, event, messageHeader) ;
130    }
131
132    template<typename T, int n>
133    void transfer(int sizeT, const CArray<T,n>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
134    {
135      map<int, CArray<T,1>> dataOut ;
136      transfer(1, sizeT, dataIn, dataOut) ;
137      sendToServer(dataOut, client, event, messageHeader) ;
138    }
139
140    template<typename T, int n>
141    void transfer(int sizeT, const CArray<T,n>& dataIn, T missingValue, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
142    {
143      map<int, CArray<T,1>> dataOut ;
144      transfer(1, sizeT, dataIn, dataOut, missingValue) ;
145      sendToServer(dataOut, client, event, messageHeader) ;
146    }
147
148    template<typename T> 
149    void transfer(int rank, CScattererConnector** connectors, int nConnectors, const T* input, T* output)
150    {
151      auto& connector = connector_[rank] ; // probably costly, find a better way to avoid the map
152      auto& mask = mask_[rank] ; 
153      int dstSize = mask.size() ;
154      if (nConnectors==0)
155      {
156        for(int i=0, j=0; i<dstSize; i++)
157          if (mask[i]) 
158          {
159            *(output+i)=*(input+connector[j]) ;
160            j++ ;
161          }
162
163      }
164      else
165      {
166        int srcSliceSize = (*(connectors-1))->getSrcSliceSize(connectors-1, nConnectors-1) ;
167        int dstSliceSize = (*(connectors-1))->getDstSliceSize(rank, connectors-1, nConnectors-1) ;
168
169        T* out = output ; 
170        for(int i=0,j=0;i<dstSize;i++) 
171        {
172          if (mask[i]) 
173          {
174            (*(connectors-1))->transfer(rank, connectors-1, nConnectors-1, input+connector[j]*srcSliceSize, out) ; // the multiplication must be avoid in further optimization
175            j++ ;
176          }
177          out += dstSliceSize ;
178        }
179      }
180    }
181
182     
183    template<typename T>
184    void sendToServer(const map<int, CArray<T,1>>& dataOut, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
185    {
186      list<CMessage> messages;
187      for(auto ranksData : dataOut)
188      {
189        int rank = ranksData.first ;
190        auto& data = ranksData.second ;
191
192        messages.push_back(CMessage(messageHeader));
193        messages.back().push(data) ;
194        event.push(rank, nbSenders_[rank], messages.back());
195      }
196      client->sendEvent(event) ;
197    }
198
199    int getSrcSliceSize(CScattererConnector** connectors, int nConnectors) 
200    { if (nConnectors==0) return srcSize_ ; else return srcSize_ * (*(connectors-1))->getSrcSliceSize(connectors-1,nConnectors-1) ; }
201
202    int getDstSliceSize(int rank, CScattererConnector** connectors, int nConnectors) 
203    { if (nConnectors==0) return dstSize_[rank] ; else return dstSize_[rank] * (*(connectors-1))->getDstSliceSize(rank, connectors-1,nConnectors-1) ; }
204
205    const map<int,int>& getNbSenders(void) {return nbSenders_ ;} 
206    const map<int,int>& getDstSize(void) { return dstSize_ ;}
207  } ;
208} 
209
210#endif
Note: See TracBrowser for help on using the repository browser.