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

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

Big update on on going work related to data distribution and transfer between clients and servers.

  • move all related file into distribution directorie
  • implement the concept of data "View"
  • implement the concept of "connector" which make the data transfer between 2 differents "Views"

YM

  • Property svn:executable set to *
File size: 4.1 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>
37    void transfer(const CArray<T,1>& dataIn, map<int, CArray<T,1>>& dataOut)
38    {
39      for(auto& rankConnector : connector_)
40      {
41        int rank = rankConnector.first ;
42        auto& connector = rankConnector.second ;
43        auto& mask = mask_[rank] ;
44        int dstSize = mask.size() ;
45        auto& data = dataOut[rank] ;
46        data.resize(dstSize) ;
47        T* dstData = data.dataFirst() ;
48        const T* srcData = dataIn.dataFirst() ;
49        for(int i=0, j=0; i<dstSize; i++)
50          if (mask[i]) 
51          {
52            dstData[i] = srcData[connector[j]] ;
53            j++ ;
54          }
55      }
56    }
57   
58    template<typename T>
59    void transfer(const CArray<T,1>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
60    {
61      map<int, CArray<T,1>> dataOut ;
62      transfer(dataIn, dataOut) ;
63      sendToServer(dataOut, client, event, messageHeader) ;
64    }
65
66    template<typename T> 
67    void transfer(int rank, CScattererConnector** connectors, int nConnectors, const T* input, T* output)
68    {
69      auto& connector = connector_[rank] ; // probably costly, find a better way to avoid the map
70      auto& mask = mask_[rank] ; 
71      int dstSize = mask.size() ;
72      if (nConnectors==0)
73      {
74        for(int i=0, j=0; i<dstSize; i++)
75          if (mask[i]) 
76          {
77            *(output+i)=*(input+connector[j]) ;
78            j++ ;
79          }
80
81      }
82      else
83      {
84        int srcSliceSize = (*(connectors-1))->getSrcSliceSize(connectors-1, nConnectors-1) ;
85        int dstSliceSize = (*(connectors-1))->getDstSliceSize(rank, connectors-1, nConnectors-1) ;
86
87        T* out = output ; 
88        for(int i=0,j=0;i<dstSize;i++) 
89        {
90          if (mask[i]) 
91          {
92            (*(connectors-1))->transfer(rank, connectors-1, nConnectors-1, input+connector[j]*srcSliceSize, out) ; // the multiplication must be avoid in further optimization
93            j++ ;
94          }
95          out += dstSliceSize ;
96        }
97      }
98    }
99
100     
101    template<typename T>
102    void sendToServer(const map<int, CArray<T,1>>& dataOut, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
103    {
104      list<CMessage> messages;
105      for(auto ranksData : dataOut)
106      {
107        int rank = ranksData.first ;
108        auto& data = ranksData.second ;
109
110        messages.push_back(CMessage(messageHeader));
111        messages.back().push(data) ;
112        event.push(rank, nbSenders_[rank], messages.back());
113      }
114      client->sendEvent(event) ;
115    }
116
117    int getSrcSliceSize(CScattererConnector** connectors, int nConnectors) 
118    { if (nConnectors==0) return srcSize_ ; else return srcSize_ * (*(connectors-1))->getSrcSliceSize(connectors-1,nConnectors-1) ; }
119
120    int getDstSliceSize(int rank, CScattererConnector** connectors, int nConnectors) 
121    { if (nConnectors==0) return dstSize_[rank] ; else return dstSize_[rank] * (*(connectors-1))->getDstSliceSize(rank, connectors-1,nConnectors-1) ; }
122
123    const map<int,int>& getNbSenders(void) {return nbSenders_ ;} 
124    const map<int,int>& getDstSize(void) { return dstSize_ ;}
125  } ;
126} 
127
128#endif
Note: See TracBrowser for help on using the repository browser.