source: XIOS/dev/dev_trunk_omp/src/registry.cpp @ 1646

Last change on this file since 1646 was 1646, checked in by yushan, 5 years ago

branch merged with trunk @1645. arch file (ep&mpi) added for ADA

  • Property svn:eol-style set to native
File size: 7.9 KB
Line 
1#include "registry.hpp"
2#include "type.hpp"
3#include <mpi.hpp>
4#include <fstream>
5#include <sstream>
6#ifdef _usingEP
7using namespace ep_lib;
8#endif
9
10namespace xios
11{
12  using namespace std;
13
14  CRegistry::CRegistry(const CRegistry& reg) : communicator(reg.communicator)
15  {
16    for(map<string,pair<size_t,char*> >::const_iterator it=reg.registry.begin() ; it!=reg.registry.end() ; ++it)
17    {
18      char* buffer=new char[it->second.first] ;
19      memcpy(buffer,it->second.second,it->second.first) ;
20      registry.insert(pair<string, pair<size_t,char*> >(it->first, pair<size_t,char*>(it->second.first,buffer))) ; 
21    }
22  }
23
24       
25  void CRegistry::reset()
26  {
27    for(map<string,pair<size_t,char*> >::const_iterator it=registry.begin() ; it!=registry.end() ; ++it)
28    {
29      if (it->second.first>0) delete[] it->second.second ;
30    }
31    registry.clear() ;
32  }
33
34  void CRegistry::setKey_(const string& key_, const CBaseType& value)
35  {
36    const string key=path+key_ ;
37    if (!value.isEmpty())
38    {
39      size_t size=value.size();
40     
41      map<string,pair<size_t,char*> >::iterator it=registry.find(key) ;
42
43      if (it!=registry.end())
44      {
45        delete[] it->second.second ;
46        registry.erase(it) ;
47      }
48
49      char* buffer=new char[size] ;
50      CBufferOut tmpBuff(buffer,size) ;
51      value.toBuffer(tmpBuff) ;
52      registry.insert(pair<string, pair<size_t,char*> >(key, pair<size_t,char*>(size,buffer))) ;
53    }
54  }
55
56  void CRegistry::getKey_(const string& key_, CBaseType& value)
57  {
58    const string key=path+key_ ;
59    size_t size=value.size();
60     
61    map<string,pair<size_t,char*> >::iterator it=registry.find(key) ;
62
63    if (it!=registry.end())
64    {
65      CBufferIn tmpBuff(it->second.second,it->second.first) ;
66      value.fromBuffer(tmpBuff) ;
67    }
68    else value.reset() ;
69  }
70
71  bool CRegistry::foundKey(const string& key_) const
72  {
73    const string key=path+key_ ;
74    map<string,pair<size_t,char*> >::const_iterator it=registry.find(key) ;
75    if (it!=registry.end()) return true ;
76    else return false ;
77  }
78 
79  bool CRegistry::toBuffer(CBufferOut& buffer) const
80  {
81    buffer<<registry.size() ;
82    for(map<string,pair<size_t,char*> >::const_iterator it=registry.begin() ; it!=registry.end() ; ++it)
83    {
84      buffer<<it->first<<it->second.first ;
85      if (!buffer.put(it->second.second,it->second.first)) ERROR("bool CRegistry::toBuffer(CBufferOut& buffer) const)",
86                                                           << "Not enough free space in buffer to queue the data."); 
87    }
88    return true ;
89  }
90
91  size_t CRegistry::size() const
92  {
93    size_t s=0;
94    size_t size_t_size=CType<size_t>(0).size() ;
95    s+=size_t_size ;
96    for(map<string,pair<size_t,char*> >::const_iterator it=registry.begin() ; it!=registry.end() ; ++it)
97      s+=(CType<string>(it->first)).size() + size_t_size + it->second.first ;
98    return s ;
99  }
100
101  void CRegistry::fromString(const string& str)
102  {
103     ERROR("void CRegistry::fromString(const string& str)",<< "This method has not been implemented"); 
104  }
105
106  string CRegistry::toString() const
107  {
108    ostringstream oss;
109   
110    for(map<string,pair<size_t,char*> >::const_iterator it=registry.begin() ; it!=registry.end() ; ++it)
111    {
112      oss<<"Key = "<< it->first  <<" , size : "<<it->second.first<<"  ASCII value : "<<string((char*) it->second.second,it->second.first)<<endl ;
113    }
114    return oss.str() ;
115  }
116
117 
118
119  bool CRegistry::fromBuffer(CBufferIn& buffer)
120  {
121    string key ;
122    size_t size ;
123    char* value ;
124    size_t nKeys ;
125    buffer >> nKeys ;
126    for(size_t i=0;i<nKeys;++i)
127    {
128      buffer>>key>>size ;
129      if (size > 0)
130      {
131        value = new char[size] ;
132        buffer.get(value,size) ;
133      }
134     
135      map<string,pair<size_t,char*> >::iterator it=registry.find(key) ;
136      if (it!=registry.end())
137      {
138        delete[] it->second.second ;
139        registry.erase(it) ;
140      }
141      registry.insert(pair<string, pair<size_t,char*> >(key, pair<size_t,char*>(size,value))) ;       
142    }
143    return true ;
144  } 
145
146  void CRegistry::toFile(const string& filename)
147  {
148    if (registry.size()==0) return ;
149   
150    CBufferOut buffer(this->size()) ;
151    this->toBuffer(buffer) ;
152    ofstream file(filename.c_str(), ofstream::out ) ;
153    size_t size=buffer.count() ;
154    file.write((const char*) &size,sizeof(size)) ;
155    file.write((const char*) buffer.start(),size) ;
156    file.close() ;
157  }
158
159  void CRegistry::fromFile(const string& filename)
160  {
161    ifstream file(filename.c_str(), ifstream::in | ifstream::binary) ;
162    if (!file) return ;
163    size_t size;
164    file.read((char*) &size,sizeof(size)) ;
165   
166    CBufferIn buffer(size) ;
167    file.read((char*) buffer.ptr(),size) ;
168    this->fromBuffer(buffer) ;
169
170    file.close() ;
171  }
172   
173  void CRegistry::mergeRegistry(const CRegistry& inRegistry)
174  {
175    size_t size ;
176    char* value;
177   
178    for(map<string,pair<size_t,char*> >::const_iterator it=inRegistry.registry.begin() ; it!=inRegistry.registry.end() ; ++it)
179    {
180      const string& key=it->first ;
181      map<string,pair<size_t,char*> >::iterator it2=registry.find(key) ;
182      if (it2==registry.end())
183      {
184        size=it->second.first ;
185        value=new char[size] ;
186        memcpy(value,it->second.second,size) ;
187        registry.insert(pair<string, pair<size_t,char*> >(key, pair<size_t,char*>(size,value))) ;     
188      }
189    }
190  }
191
192 
193  void CRegistry::bcastRegistry(void)
194  {
195    int rank ;
196    MPI_Comm_rank(communicator,&rank);
197    if (rank==0)
198    {
199      CBufferOut buffer(this->size()) ;
200      this->toBuffer(buffer) ;
201      int size=buffer.count() ;
202      MPI_Bcast(&size,1,MPI_INT,0,communicator) ;
203      MPI_Bcast(buffer.start(),size,MPI_CHAR,0,communicator) ;
204    }
205    else
206    {
207      int size ;
208      MPI_Bcast(&size,1,MPI_INT,0,communicator) ;
209      CBufferIn buffer(size) ;
210      MPI_Bcast(buffer.start(),size,MPI_CHAR,0,communicator) ;
211      this->fromBuffer(buffer) ;
212    }
213  }
214  void CRegistry::gatherRegistry(void)
215  {
216    gatherRegistry(communicator) ;
217  }
218
219  void CRegistry::gatherRegistry(const MPI_Comm& comm)
220  {
221    int rank,mpiSize ;
222    MPI_Comm_rank(comm,&rank);
223    MPI_Comm_size(comm,&mpiSize);
224
225    int* sizes=new int[mpiSize] ;
226    CBufferOut localBuffer(this->size()) ;
227    this->toBuffer(localBuffer) ;
228    int localSize=localBuffer.count() ;
229    MPI_Gather(&localSize,1,MPI_INT,sizes,1,MPI_INT,0,comm) ;
230
231    char* globalBuffer ;
232    int*   displs ;
233   
234    if (rank==0)
235    {
236      size_t globalBufferSize=0 ;
237      displs=new int[mpiSize] ;
238      for (int i=0;i<mpiSize;++i)
239      {
240        displs[i]=globalBufferSize ;
241        globalBufferSize+=sizes[i] ;
242      }
243
244      globalBuffer=new char[globalBufferSize] ;
245      MPI_Gatherv(localBuffer.start(),localSize,MPI_CHAR,globalBuffer,sizes,displs,MPI_CHAR,0,comm) ;
246      for(int i=1;i<mpiSize;++i)
247      {
248        CBufferIn buffer(globalBuffer+displs[i],sizes[i]) ;
249        CRegistry reg ;
250        reg.fromBuffer(buffer) ;
251        mergeRegistry(reg) ;
252      }
253      delete[] displs ;
254      delete[] globalBuffer ;
255    }
256    else  MPI_Gatherv(localBuffer.start(),localSize,MPI_CHAR,globalBuffer,sizes,displs,MPI_CHAR,0,comm) ;   
257    delete[] sizes ;
258   
259  }
260
261  void CRegistry::hierarchicalGatherRegistry(void)
262  {
263    //hierarchicalGatherRegistry(communicator) ;
264    gatherRegistry(communicator) ;
265  }
266
267  void CRegistry::hierarchicalGatherRegistry(const MPI_Comm& comm)
268  {
269    int mpiRank,mpiSize ;
270    MPI_Comm_rank(comm,&mpiRank);
271    MPI_Comm_size(comm,&mpiSize);   
272
273    if (mpiSize>2)
274    {
275      int color ;
276      if (mpiRank<mpiSize/2+mpiSize%2) color=0 ;
277      else color=1 ;
278      MPI_Comm commUp ;
279      MPI_Comm_split(comm,color,mpiRank,&commUp) ,
280      hierarchicalGatherRegistry(commUp) ;
281      MPI_Comm_free(&commUp) ;
282    }
283
284    if (mpiSize>1)
285    {
286      MPI_Comm commDown ;
287      int color ;
288     
289      if (mpiRank==0 || mpiRank==mpiSize/2+mpiSize%2) color=0 ;
290      else color=1 ;
291      MPI_Comm_split(comm,color,mpiRank,&commDown) ;
292      if (color==0) gatherRegistry(commDown) ;
293      MPI_Comm_free(&commDown) ;   
294    }
295  }
296
297}
Note: See TracBrowser for help on using the repository browser.