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

Last change on this file since 2270 was 2267, checked in by ymipsl, 3 years ago

tracking memory leak
Elements, views, and connectors are now managed with shared pointer.
YM

  • Property svn:executable set to *
File size: 7.2 KB
RevLine 
[1918]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_ ;
[1943]23      int remoteCommSize_ ;
[1918]24
[2267]25      shared_ptr<CLocalView> srcView_ ;
26      shared_ptr<CDistributedView> dstView_ ;
[1918]27      map<int,int> nbSenders_ ; // number of participant when sending remote buffer
28      int srcSize_ ;
29      map<int,int> dstSize_ ;
30
31    public:
32
[2267]33    CScattererConnector(shared_ptr<CLocalView> srcView, shared_ptr<CDistributedView> dstView, MPI_Comm localComm, int remoteCommSize) 
[1943]34                       : srcView_(srcView), dstView_(dstView), localComm_(localComm), remoteCommSize_(remoteCommSize) {}
[1918]35    void computeConnector(void) ;
36   
[1930]37    template<typename T, int n>
38    void transfer(const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut)
[1918]39    {
[1984]40      transfer(1,1, dataIn, dataOut) ;
[1930]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    {
[1984]46      transfer(1, 1, dataIn, dataOut, missingValue) ;
[1930]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    {
[2118]52      transfer(1, sizeT, dataIn, dataOut);
[1984]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    {
[1930]58      // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
[1984]59      size_t srcSlice = sizeT*srcSize_ ;
[1918]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] ;
[1984]67        size_t dstSlice = dstSize*sizeT ;
68        data.resize(repeat*dstSlice) ;
[1918]69        T* dstData = data.dataFirst() ;
70        const T* srcData = dataIn.dataFirst() ;
[1984]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        }
[1918]82      }
83    }
[1930]84
85    template<typename T, int n>
[1984]86    void transfer(int repeat, int sizeT, const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut, T missingValue)
[1930]87    {
88      // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
[1984]89      size_t srcSlice = sizeT*srcSize_ ;
[1930]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] ;
[1984]97        size_t dstSlice = dstSize*sizeT ;
98        data.resize(repeat * dstSlice) ;
[1930]99        T* dstData = data.dataFirst() ;
100        const T* srcData = dataIn.dataFirst() ;
[1984]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        }
[1930]117      }
118    }
[1918]119   
[1930]120    template<typename T,int n>
121    void transfer(const CArray<T,n>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
[1918]122    {
[1984]123      transfer( 1, dataIn, client, event, messageHeader) ;
[1930]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    {
[1984]129      transfer( 1, dataIn, missingValue, client, event, messageHeader) ;
[1930]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    {
[1918]135      map<int, CArray<T,1>> dataOut ;
[1984]136      transfer(1, sizeT, dataIn, dataOut) ;
[1918]137      sendToServer(dataOut, client, event, messageHeader) ;
138    }
139
[1930]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 ;
[1984]144      transfer(1, sizeT, dataIn, dataOut, missingValue) ;
[1930]145      sendToServer(dataOut, client, event, messageHeader) ;
146    }
147
[1918]148    template<typename T> 
[2267]149    void transfer(int rank, shared_ptr<CScattererConnector>* connectors, int nConnectors, const T* input, T* output)
[1918]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
[2267]199    int getSrcSliceSize(shared_ptr<CScattererConnector>* connectors, int nConnectors) 
[1918]200    { if (nConnectors==0) return srcSize_ ; else return srcSize_ * (*(connectors-1))->getSrcSliceSize(connectors-1,nConnectors-1) ; }
201
[2267]202    int getDstSliceSize(int rank, shared_ptr<CScattererConnector>* connectors, int nConnectors) 
[1918]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
[2118]210#endif
Note: See TracBrowser for help on using the repository browser.