source: XIOS/dev/dev_ym/XIOS_COUPLING/src/object_template_impl.hpp @ 2241

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

Clean Context and it members before MPI_Finalize (to avoid some MPI call after MPI_Finalize, such as MPI_Free_mem in ServerBuffer? destructor)

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