source: XIOS/dev/branch_openmp/src/object_template_impl.hpp @ 1501

Last change on this file since 1501 was 1460, checked in by yushan, 6 years ago

branch_openmp merged with XIOS_DEV_CMIP6@1459

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 18.8 KB
Line 
1#ifndef __XIOS_CObjectTemplate_impl__
2#define __XIOS_CObjectTemplate_impl__
3
4#include "xios_spl.hpp"
5#include "context_client.hpp"
6#include "object_factory.hpp"
7#include "context.hpp"
8#include "buffer_in.hpp"
9#include "attribute.hpp"
10#include "event_client.hpp"
11#include "object_template.hpp"
12#include "context_client.hpp"
13#include "indent.hpp"
14#include "type_util.hpp"
15#include "message.hpp"
16#include "type.hpp"
17#include "type_util.hpp"
18#include "group_template.hpp"
19
20namespace xios
21{
22   /// ////////////////////// Définitions ////////////////////// ///
23   template <class T>
24      xios_map<StdString,
25      xios_map<StdString,
26      //boost::shared_ptr<T> > > CObjectTemplate<T>::AllMapObj;
27      boost::shared_ptr<T> > > *CObjectTemplate<T>::AllMapObj_ptr = 0;
28
29   template <class T>
30      xios_map<StdString,
31      //std::vector<boost::shared_ptr<T> > > CObjectTemplate<T>::AllVectObj;
32      std::vector<boost::shared_ptr<T> > > *CObjectTemplate<T>::AllVectObj_ptr = 0;
33
34   template <class T>
35      //xios_map<StdString,long int> CObjectTemplate<T>::GenId;
36      xios_map<StdString,long int> *CObjectTemplate<T>::GenId_ptr = 0;
37
38   template <class T>
39      CObjectTemplate<T>::CObjectTemplate(void)
40         : CAttributeMap()
41         , CObject()
42   { /* Ne rien faire de plus */ }
43
44   template <class T>
45      CObjectTemplate<T>::CObjectTemplate(const StdString & id)
46         : CAttributeMap()
47         , CObject(id, CObjectFactory::IsGenUId<T>(id))
48   { /* Ne rien faire de plus */ }
49
50   template <class T>
51      CObjectTemplate<T>::CObjectTemplate
52         (const CObjectTemplate<T> & object, bool withAttrList, bool withId)
53         : CAttributeMap()
54         , CObject()
55   {
56      if (object.hasId() && withId)
57         this->setId(object.getId(), object.hasAutoGeneratedId());
58      ERROR("CObjectTemplate<T> construtor 3", << "Not completly implemented yet !");
59   }
60
61   template <class T>
62      CObjectTemplate<T>::~CObjectTemplate(void)
63   { /* Ne rien faire de plus */ }
64
65   ///--------------------------------------------------------------
66
67   template <class T>
68      std::vector<boost::shared_ptr<T> > &
69         CObjectTemplate<T>::GetAllVectobject(const StdString & contextId)
70   {
71      //return (CObjectTemplate<T>::AllVectObj[contextId]);
72    return (CObjectTemplate<T>::AllVectObj_ptr->at(contextId));
73   }
74
75   //---------------------------------------------------------------
76
77   template <class T>
78      StdString CObjectTemplate<T>::toString(void) const
79   {
80      StdOStringStream oss;
81      oss << "<" << T::GetName();
82      if (this->hasId())
83         oss << " id=\"" << this->getId() << "\"";
84      oss << " " << SuperClassMap::toString() << "/>";
85      return (oss.str());
86   }
87
88   template <class T>
89      void CObjectTemplate<T>::fromString(const StdString & str)
90   {
91      ERROR("CObjectTemplate<T>::fromString(str)",
92            << "[ str = " << str << "] Not implemented yet !");
93   }
94
95   //---------------------------------------------------------------
96
97/*
98   template <class T>
99      void CObjectTemplate<T>::toBinary(StdOStream & os) const
100   {
101      SuperClassMap::toBinary(os);
102   }
103
104   template <class T>
105      void CObjectTemplate<T>::fromBinary(StdIStream & is)
106   {
107      SuperClassMap::fromBinary(is);
108   }
109*/
110
111   //---------------------------------------------------------------
112
113   template <class T>
114      void CObjectTemplate<T>::parse(xml::CXMLNode & node)
115   {
116      xml::THashAttributes attributes = node.getAttributes();
117      CAttributeMap::setAttributes(attributes);
118   }
119
120   //---------------------------------------------------------------
121
122   template <class T>
123      ENodeType CObjectTemplate<T>::getType(void) const
124   {
125      return (T::GetType());
126   }
127
128   template <class T>
129   string CObjectTemplate<T>::getName(void) const
130   {
131      return (T::GetName());
132   }
133
134   //---------------------------------------------------------------
135
136   template <class T>
137      bool CObjectTemplate<T>::hasChild(void) const
138   {
139      return (false);
140   }
141
142   /*!
143     Compare two object of same type
144   */
145   template <class T>
146   bool CObjectTemplate<T>::isEqual(const string& id, const vector<StdString>& excludedAttrs)
147   {
148      T* obj = CObjectTemplate<T>::get(id);
149      return this->isEqual(obj, excludedAttrs);
150   }
151
152   template <class T>
153   bool CObjectTemplate<T>::isEqual(T* obj, const vector<StdString>& excludedAttrs)
154   {
155
156      CAttributeMap& attrMapThis = *this;
157      CAttributeMap& attrMapObj  = *obj;
158      return (attrMapThis.isEqual(attrMapObj, excludedAttrs));
159   }
160
161   //---------------------------------------------------------------
162
163   template <class T>
164      void CObjectTemplate<T>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
165   {
166      if (parent != NULL)
167         SuperClassMap::setAttributes(parent, apply);
168   }
169
170   //---------------------------------------------------------------
171
172   template <class T>
173      void CObjectTemplate<T>::ClearAllAttributes(void)
174   {
175      vector<T*> avect = CObjectTemplate<T>::getAll();
176      typename vector<T*>::iterator
177            it = avect.begin(), end = avect.end();
178
179      for (;it != end; it++)
180      {
181         CAttributeMap & amap = **it;
182         amap.clearAllAttributes();
183      }
184   }
185
186   template<typename T>
187   std::map<int, size_t> CObjectTemplate<T>::getMinimumBufferSizeForAttributes(CContextClient* client)
188   {
189     std::map<int, size_t> minimumSizes;
190
191     if (client->isServerLeader())
192     {
193       size_t minimumSize = 0;
194       CAttributeMap& attrMap = *this;
195       CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
196       for (; it != itE; ++it)
197       {
198         if (!it->second->isEmpty())
199         {
200           size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
201           if (size > minimumSize)
202             minimumSize = size;
203         }
204       }
205
206       if (minimumSize)
207       {
208         // Account for extra header info
209         minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
210
211         const std::list<int>& ranks = client->getRanksServerLeader();
212         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
213           minimumSizes.insert(std::make_pair(*itRank, minimumSize));
214       }
215     }
216     return minimumSizes;
217   }
218
219
220   template<typename T>
221   void CObjectTemplate<T>::sendAllAttributesToServer()
222   {
223     CAttributeMap& attrMap = *this;
224     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
225     for (; it != itE; ++it)
226     {
227       if (it->second->doSend() && !(it->second)->isEmpty()) sendAttributToServer(*(it->second));
228     }
229   }
230
231   template<typename T>
232   void CObjectTemplate<T>::sendAllAttributesToServer(CContextClient* client)
233   {
234     CAttributeMap& attrMap = *this;
235     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
236     for (; it != itE; ++it)
237     {
238       if (it->second->doSend() && !(it->second)->isEmpty()) sendAttributToServer(*(it->second), client);
239     }
240   }
241
242   template <class T>
243   void CObjectTemplate<T>::sendAttributToServer(const string& id)
244   {
245      CAttributeMap & attrMap = *this;
246      CAttribute* attr=attrMap[id];
247      sendAttributToServer(*attr);
248   }
249
250   template <class T>
251   void CObjectTemplate<T>::sendAttributToServer(const string& id, CContextClient* client)
252   {
253      CAttributeMap & attrMap = *this;
254      CAttribute* attr=attrMap[id];
255      sendAttributToServer(*attr, client);
256   }
257
258  template <class T>
259  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr)
260  {
261     // Use correct context client to send message
262    CContext* context=CContext::getCurrent();
263    if (context->hasClient)
264    {
265      // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
266      int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;
267      for (int i = 0; i < nbSrvPools; ++i)
268      {
269        CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
270        CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
271        if (contextClientTmp->isServerLeader())
272        {
273          CMessage msg;
274          msg<<this->getIdServer();
275          msg << attr.getName();
276          msg << attr;
277          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
278          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
279            event.push(*itRank,1,msg);
280          contextClientTmp->sendEvent(event);
281        }
282        else contextClientTmp->sendEvent(event);
283      }
284    }
285  }
286
287  template <class T>
288  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr, CContextClient* client)
289  {
290    CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
291    if (client->isServerLeader())
292    {
293      CMessage msg;
294      msg<<this->getIdServer();
295      msg << attr.getName();
296      msg << attr;
297      const std::list<int>& ranks = client->getRanksServerLeader();
298      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
299        event.push(*itRank,1,msg);
300      client->sendEvent(event);
301    }
302    else client->sendEvent(event);
303  }
304
305  /*!
306    This generic funtion only provides instance for sending, for receving, each
307    child class must define itself.
308    \param [in] id Id of added item
309    \param [in] itemType type of added item
310  */
311  template<class T>
312  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType)
313  {
314    CContext* context = CContext::getCurrent();
315    typedef typename T::EEventId ItemType;
316    if (context->hasClient)
317    {
318      // Use correct context client to send message
319      // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
320      int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;
321      for (int i = 0; i < nbSrvPools; ++i)
322      {
323         CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
324         CEventClient event(this->getType(),ItemType(itemType));
325         if (contextClientTmp->isServerLeader())
326         {
327           CMessage msg;
328           msg << this->getId();
329           msg << id;
330           const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
331           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
332             event.push(*itRank,1,msg);
333           contextClientTmp->sendEvent(event);
334         }
335         else contextClientTmp->sendEvent(event);
336      }
337    }
338  }
339
340  template<class T>
341  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType, CContextClient* client)
342  {
343    typedef typename T::EEventId ItemType;
344     CEventClient event(this->getType(),ItemType(itemType));
345     if (client->isServerLeader())
346     {
347       CMessage msg;
348       msg << this->getId();
349       msg << id;
350       const std::list<int>& ranks = client->getRanksServerLeader();
351       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
352         event.push(*itRank,1,msg);
353       client->sendEvent(event);
354     }
355     else client->sendEvent(event);
356  }
357
358  template <class T>
359  void CObjectTemplate<T>::recvAttributFromClient(CEventServer& event)
360  {
361
362    CBufferIn* buffer=event.subEvents.begin()->buffer;
363    string id,attrId;
364    *buffer>>id;
365    CAttributeMap & attrMap = *get(id);
366    *buffer>>attrId;
367    CAttribute* attr=attrMap[attrId];
368    info(50) << "attribut recu " << attrId << "  ";
369    if (attr->isEmpty()) info(50) << "--> empty" << endl;
370    else info(50) /*<attr->getValue()*/ << endl;
371    *buffer>>*attr;
372     info(50) << "attribut recu " << attrId << "  ";
373    if (attr->isEmpty()) info(50) << "--> empty" << endl;
374    else info(50) /*attr->getValue()*/ << endl;
375  }
376
377   template <class T>
378   bool CObjectTemplate<T>::dispatchEvent(CEventServer& event)
379   {
380      switch(event.type)
381      {
382         case EVENT_ID_SEND_ATTRIBUTE :
383           recvAttributFromClient(event);
384           return true;
385           break;
386
387         default :
388         return false;
389//           ERROR("void CObjectTemplate<T>::recvEvent(CEventServer& event)", << "Unknown Event");
390      }
391   }
392
393   template <typename T>
394   bool CObjectTemplate<T>::has(const string & id)
395   {
396     return CObjectFactory::HasObject<T>(id);
397   }
398
399   template <typename T>
400   bool CObjectTemplate<T>::has(const string& contextId, const string & id)
401   {
402     return CObjectFactory::HasObject<T>(contextId,id);
403   }
404
405   template <typename T>
406   T* CObjectTemplate<T>::get(const string & id)
407   {
408     return CObjectFactory::GetObject<T>(id).get();
409   }
410
411   template <typename T>
412   T* CObjectTemplate<T>::get(const T* ptr)
413   {
414     return CObjectFactory::GetObject<T>(ptr).get();
415   }
416
417   template <typename T>
418   boost::shared_ptr<T> CObjectTemplate<T>::getShared(const T* ptr)
419   {
420     return CObjectFactory::GetObject<T>(ptr);
421   }
422
423   template <typename T>
424   boost::shared_ptr<T> CObjectTemplate<T>::getShared(void)
425   {
426     return CObjectFactory::GetObject<T>((T*)this);
427   }
428
429   template <typename T>
430   const vector<T*> CObjectTemplate<T>::getAll()
431   {
432     const vector< boost::shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>();
433     vector<T*> vect;
434
435     typename vector<boost::shared_ptr<T> >::const_iterator it;
436     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
437     return vect;
438   }
439
440   template <typename T>
441   const vector<T*> CObjectTemplate<T>::getAll(const string & id)
442   {
443     const vector< boost::shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>(id);
444     vector<T*> vect;
445
446     typename vector<boost::shared_ptr<T> >::const_iterator it;
447     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
448     return vect;
449   }
450
451   template <typename T>
452   T* CObjectTemplate<T>::get(const string& contextId, const string & id)
453   {
454     return CObjectFactory::GetObject<T>(contextId,id).get();
455   }
456
457   template <typename T>
458   T* CObjectTemplate<T>::create(const string & id)
459   {
460     return CObjectFactory::CreateObject<T>(id).get();
461   }   ///--------------------------------------------------------------
462
463  template <typename T>
464  T* CObjectTemplate<T>::get(void)
465  {
466    return CObjectFactory::GetObject<T>((T*)this).get();
467  }
468
469   template <typename T>
470   void CObjectTemplate<T>::generateCInterface(ostream& oss)
471   {
472     string className=getName();
473     int found=className.rfind("_group");
474     if (found!=string::npos) className.replace(found,1,0,'x');
475
476     oss << "/* ************************************************************************** *" << iendl;
477     oss << " *               Interface auto generated - do not modify                     *" << iendl;
478     oss << " * ************************************************************************** */" << iendl;
479     oss << iendl;
480     oss << "#include <boost/multi_array.hpp>" << iendl;
481     oss << "#include <boost/shared_ptr.hpp>" << iendl;
482     oss << "#include \"xios.hpp\"" << iendl;
483     oss << "#include \"attribute_template.hpp\"" << iendl;
484     oss << "#include \"object_template.hpp\"" << iendl;
485     oss << "#include \"group_template.hpp\"" << iendl;
486     oss << "#include \"icutil.hpp\"" << iendl;
487     oss << "#include \"icdate.hpp\"" << iendl;
488     oss << "#include \"timer.hpp\"" << iendl;
489     oss << "#include \"node_type.hpp\"" << iendl;
490     oss << iendl;
491     oss << "extern \"C\"" << iendl;
492     oss << "{" << iendl++;
493     oss << "typedef xios::" << getStrType<T>() << "* " << className << "_Ptr;";
494     SuperClassMap::generateCInterface(oss,className);
495     oss << "}" << iendl--;
496   }
497
498   template <typename T>
499   void CObjectTemplate<T>::generateFortran2003Interface(ostream& oss)
500   {
501     string className=getName();
502     int found=className.rfind("_group");
503     if (found!=string::npos) className.replace(found,1,0,'x');
504
505     oss << "! * ************************************************************************** *" << iendl;
506     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
507     oss << "! * ************************************************************************** *" << iendl;
508     oss << "#include \"../fortran/xios_fortran_prefix.hpp\"" << iendl;
509     oss << iendl;
510     oss << "MODULE " << className << "_interface_attr" << iendl++;
511     oss << "USE, INTRINSIC :: ISO_C_BINDING" << std::endl;
512     oss << iendl;
513     oss << "INTERFACE" << iendl++;
514     oss << "! Do not call directly / interface FORTRAN 2003 <-> C99";
515     SuperClassMap::generateFortran2003Interface(oss,className);
516     oss << iendl--;
517     oss << "END INTERFACE" << iendl--;
518     oss << iendl;
519     oss << "END MODULE " << className << "_interface_attr" << iendl;
520   }
521
522   template <typename T>
523   void CObjectTemplate<T>::generateFortranInterface(ostream& oss)
524   {
525     string className=getName();
526     int found=className.rfind("_group");
527     if (found!=string::npos) className.erase(found,1);
528     string superClassName=getName();
529     found=superClassName.find("_group");
530     if (found!=string::npos) superClassName.erase(found,6);
531
532     oss << "! * ************************************************************************** *" << iendl;
533     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
534     oss << "! * ************************************************************************** *" << iendl;
535     oss << "#include \"xios_fortran_prefix.hpp\"" << iendl;
536     oss << iendl;
537     oss << "MODULE i" << className << "_attr" << iendl++;
538     oss << "USE, INTRINSIC :: ISO_C_BINDING" << iendl;
539     oss << "USE i" << superClassName << iendl;
540     oss << "USE " << className << "_interface_attr" << iendl--;
541//   oss << "TYPE txios(" << className << ")" << iendl;
542//   oss << "  INTEGER(kind = C_INTPTR_T) :: daddr" << iendl;
543//   oss << "END TYPE txios(" << className << ")" << iendl;
544     oss << iendl;
545     oss << "CONTAINS" << iendl;
546     oss << iendl++;
547     SuperClassMap::generateFortranInterface_id(oss,className);
548     oss << iendl;
549     SuperClassMap::generateFortranInterface_hdl(oss,className);
550     oss << iendl;
551     SuperClassMap::generateFortranInterface_hdl_(oss,className);
552     oss << iendl;
553     SuperClassMap::generateFortranInterfaceGet_id(oss,className);
554     oss << iendl;
555     SuperClassMap::generateFortranInterfaceGet_hdl(oss,className);
556     oss << iendl;
557     SuperClassMap::generateFortranInterfaceGet_hdl_(oss,className);
558     oss << iendl;
559     SuperClassMap::generateFortranInterfaceIsDefined_id(oss,className);
560     oss << iendl;
561     SuperClassMap::generateFortranInterfaceIsDefined_hdl(oss,className);
562     oss << iendl;
563     SuperClassMap::generateFortranInterfaceIsDefined_hdl_(oss,className);
564     oss << iendl--;
565     oss << "END MODULE i" << className << "_attr" << iendl;
566   }
567} // namespace xios
568
569#endif // __XIOS_CObjectTemplate_impl__
Note: See TracBrowser for help on using the repository browser.