source: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp @ 2265

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

tracking memory leak : remove context and all related object from object factory when context is finalized.
YM

  • 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: 15.6 KB
Line 
1#ifndef __XIOS_CContext__
2#define __XIOS_CContext__
3
4/// XIOS headers ///
5#include "xios_spl.hpp"
6//#include "node_type.hpp"
7#include "calendar_wrapper.hpp"
8
9#include "declare_group.hpp"
10#include "data_output.hpp"
11#include "garbage_collector.hpp"
12#include "registry.hpp"
13#include "mpi.hpp"
14#include "services_manager.hpp"
15#include "server_context.hpp"
16#include "event_scheduler.hpp"
17
18
19namespace xios
20{
21   class CContextClient;
22   class CContextServer;
23
24
25   /// ////////////////////// Déclarations ////////////////////// ///
26   class CContextGroup;
27   class CContextAttributes;
28   class CContext;
29   class CFile;
30   class CCouplerIn ;
31   class CCouplerOut ;
32   ///--------------------------------------------------------------
33
34   // Declare/Define CFileAttribute
35   BEGIN_DECLARE_ATTRIBUTE_MAP(CContext)
36#  include "context_attribute.conf"
37   END_DECLARE_ATTRIBUTE_MAP(CContext)
38
39   ///--------------------------------------------------------------
40  /*!
41  \class CContext
42   This class corresponds to the concrete presentation of context in xml file and in play an essential role in XIOS
43   Each object of this class contains all root definition of elements: files, fiels, domains, axis, etc, ... from which
44   we can have access to each element.
45   In fact, every thing must a be inside a particuliar context. After the xml file (iodef.xml) is parsed,
46   object of the class is created and its contains all information of other elements in the xml file.
47  */
48   class CContext
49      : public CObjectTemplate<CContext>
50      , public CContextAttributes
51   {
52         public :
53         enum EEventId
54         {
55           EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR,
56           EVENT_ID_CREATE_FILE_HEADER,EVENT_ID_CONTEXT_FINALIZE,
57           EVENT_ID_CONTEXT_FINALIZE_CLIENT,
58           EVENT_ID_COUPLER_IN_READY,
59           EVENT_ID_COUPLER_IN_CLOSE_DEFINITION,
60           EVENT_ID_COUPLER_IN_CONTEXT_FINALIZED,
61         };
62
63         /// typedef ///
64         typedef CObjectTemplate<CContext>   SuperClass;
65         typedef CContextAttributes SuperClassAttribute;
66
67      public :
68
69         typedef CContextAttributes RelAttributes;
70         typedef CContext           RelGroup;
71
72         //---------------------------------------------------------
73
74      public :
75
76         /// Constructeurs ///
77         CContext(void);
78         explicit CContext(const StdString & id);
79         CContext(const CContext & context);       // Not implemented yet.
80         CContext(const CContext * const context); // Not implemented yet.
81
82         /// Destructeur ///
83         virtual ~CContext(void);
84
85         //---------------------------------------------------------
86
87      public :
88
89         /// Mutateurs ///
90         void setCalendar(std::shared_ptr<CCalendar> newCalendar);
91
92         /// Accesseurs ///
93         std::shared_ptr<CCalendar>      getCalendar(void) const;
94
95      public :
96         // Initialize server or client
97         void init(CServerContext* parentServerContext, MPI_Comm intraComm, int serviceType);
98         void initClient(MPI_Comm intraComm, int serviceType);
99         
100         void initServer(MPI_Comm intraComm, int serviceType );
101         void createClientInterComm(MPI_Comm interCommClient, MPI_Comm interCommServer)  ;
102         void createServerInterComm(void)  ;
103
104         bool isInitialized(void);
105
106         StdString dumpClassAttributes(void);
107
108         // Put sever or client into loop state
109         bool eventLoop(bool enableEventsProcessing=true);
110         bool scheduledEventLoop(bool enableEventsProcessing=true) ; 
111         void globalEventLoop(void);
112
113         // Finalize a context
114         void finalize(void);
115
116         bool isFinalized(void);
117
118         void closeDefinition(void);
119
120         // to be removed     
121         std::vector<CField*> findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
122         // Some functions to process context
123         std::vector<CField*> findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles);
124         std::vector<CField*> findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles);
125         std::vector<CField*> findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut);
126         std::vector<CField*> findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn);
127         // void findAllEnabledFields(void);
128         // void findAllEnabledFieldsInReadModeFiles(void);
129         void readAttributesOfEnabledFieldsInReadModeFiles();
130         void solveAllInheritance(bool apply=true);
131         void findEnabledFiles(void);
132         void findEnabledCouplerIn(void);
133         void findEnabledCouplerOut(void);
134         void createCouplerInterCommunicator(void) ;
135         void findEnabledWriteModeFiles(void);
136         void findEnabledReadModeFiles(void);
137         void closeAllFile(void);
138         void updateCalendar(int step);
139         void createFileHeader(void);
140         void initReadFiles(void);
141         void prepareTimeseries(void);
142         void postProcessFilterGraph();
143         void startPrefetchingOfEnabledReadModeFiles();
144         void doPreTimestepOperationsForEnabledReadModeFiles();
145         void doPostTimestepOperationsForEnabledReadModeFiles();
146         void findFieldsWithReadAccess(void);
147         void triggerLateFields(void) ;
148         
149         std::map<int, StdSize> getAttributesBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
150         std::map<int, StdSize> getDataBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
151
152         // Distribute files (in write mode) among secondary-server pools according to the estimated data flux
153         void distributeFiles(const std::vector<CFile*>& files);
154         void distributeFileOverBandwith(const std::vector<CFile*>& files) ;
155         void distributeFileOverMemoryBandwith(const std::vector<CFile*>& files) ;
156         
157         // Send context close definition
158         void sendCloseDefinition(void);
159       public:
160         void sendCloseDefinition(CContextClient* client) ;
161       private:
162         set<CContextClient*> sendCloseDefinition_done_ ;
163       public:
164         // There are something to send on closing context defintion
165         void sendUpdateCalendar(int step);
166         void sendCreateFileHeader(void);
167         void sendEnabledFiles(const std::vector<CFile*>& activeFiles);
168         void sendEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
169         void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles);
170         //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers
171         void sendFinalizeClient(CContextClient* contextClient, const string& contextClientId);
172         
173         public:
174         void sendContextToFileServer(CContextClient* client) ;
175         private:
176         std::set<CContextClient*> sendToFileServer_done_ ;
177         
178         public: 
179         std::string getContextId() {return contextId_;}
180
181         // Client side: Receive and process messages
182         static void recvUpdateCalendar(CEventServer& event);
183         void recvUpdateCalendar(CBufferIn& buffer);
184         static void recvCloseDefinition(CEventServer& event);
185         static void recvCreateFileHeader(CEventServer& event);
186         void recvCreateFileHeader(CBufferIn& buffer);
187         static void recvSolveInheritanceContext(CEventServer& event);
188         void recvSolveInheritanceContext(CBufferIn& buffer);
189         static void recvFinalizeClient(CEventServer& event) ;
190         void recvFinalizeClient(CBufferIn& buffer);
191       
192       public:
193         void sendCouplerInReady(CContextClient* client);
194       private:
195         set<CContextClient*> sendCouplerInReady_done_;
196       public:
197         static void recvCouplerInReady(CEventServer& event) ;
198         void recvCouplerInReady(CBufferIn& buffer) ; //!< coupler is ready to receive grid definition.
199         set<CContextClient*> couplerInReady_;
200         bool isCouplerInReady(CContextClient* client) { return couplerInReady_.count(client)!=0 ;}
201
202       public:
203        void sendCouplerInCloseDefinition(CContextClient* client) ;
204        set<CContextClient*> sendCouplerInCloseDefinition_done_;
205        static void recvCouplerInCloseDefinition(CEventServer& event) ;
206        void recvCouplerInCloseDefinition(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent     
207        set<CContextClient*> couplerInCloseDefinition_ ;
208        bool isCouplerInCloseDefinition(CContextClient* client) { return couplerInCloseDefinition_.count(client)!=0 ;}
209
210       public:
211        void sendCouplerInContextFinalized(CContextClient* client) ;
212        set<CContextClient*> sendCouplerInContextFinalized_done_;
213        static void recvCouplerInContextFinalized(CEventServer& event) ;
214        void recvCouplerInContextFinalized(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent     
215        set<CContextClient*> couplerInContextFinalized_ ;
216        bool isCouplerInContextFinalized(CContextClient* client) { return couplerInContextFinalized_.count(client)!=0 ;}
217
218       public: 
219        void freeComms(void);                  //!< Free internally allcoated communicators
220        void releaseClientBuffers(void);       //! Deallocate buffers allocated by clientContexts
221
222         // dispatch event
223         static bool dispatchEvent(CEventServer& event);
224
225      public:
226        // Get current context
227        static CContext* getCurrent(void);
228
229        // Get context root
230        static CContextGroup* getRoot(void);
231
232        // Set current context
233        static void setCurrent(const string& id);
234
235        // Create new context
236        static CContext* create(const string& id = "");
237
238        /// Accesseurs statiques ///
239        static StdString GetName(void);
240        static StdString GetDefName(void);
241        static ENodeType GetType(void);
242
243        static CContextGroup* GetContextGroup(void);
244
245        // Some functions to visualize structure of current context
246        static void ShowTree(StdOStream & out = std::clog);
247        static void CleanTree(void);
248        static void removeContext(const std::string& contextId);
249        static void removeAllContexts(void) ;
250        int getServiceType(void) {return serviceType_;}
251
252      public :
253         // Parse xml node and write all info into context
254         virtual void parse(xml::CXMLNode & node);
255
256         // Visualize a context
257         virtual StdString toString(void) const;
258
259
260         // Solve all inheritance relation in current context
261         virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0);
262
263         // Verify if all root definition in a context have children
264         virtual bool hasChild(void) const;
265
266         bool isProcessingEvent(void) {return isProcessingEvent_;}
267         bool setProcessingEvent(void) {isProcessingEvent_=true ;}
268         bool unsetProcessingEvent(void) {isProcessingEvent_=false ;}
269         MPI_Comm getIntraComm(void) {return intraComm_ ;}
270         int getIntraCommRank(void) {return intraCommRank_;}
271         int getIntraCommSize(void) {return intraCommSize_;}
272
273         void addCouplingChanel(const std::string& contextId, bool out) ;
274
275      public :
276         // Calendar of context
277         std::shared_ptr<CCalendar>   calendar;
278
279         // List of all enabled files (files on which fields are written or read)
280         std::vector<CFile*> enabledFiles;
281         // List of all enabled files in read mode (files on which fields are read)
282         std::vector<CFile*> enabledReadModeFiles;
283         // List of all enabled files in write mode
284         std::vector<CFile*> enabledWriteModeFiles;
285
286         std::vector<CCouplerIn*> enabledCouplerIn;
287         std::vector<CCouplerOut*> enabledCouplerOut;
288
289
290         // List of all enabled fields whose instant data is accessible from the public API
291         // but which are not part of a file
292         std::vector<CField*> fieldsWithReadAccess_;
293         std::vector<CField*> couplerInFields_;
294         std::vector<CField*> fileInFields_;
295
296
297         // Context root
298         static std::shared_ptr<CContextGroup> root;
299
300         // Determine context on client or not
301         bool hasClient;
302
303         // Determine context on server or not
304         bool hasServer;
305
306         CContextServer* server;    //!< Concrete context server
307         CContextClient* client;    //!< Concrete contex client
308         std::vector<CContextServer*> serverPrimServer;
309         std::vector<CContextClient*> clientPrimServer;
310
311         // list of slave servers (IO server or others)
312         set<CContextClient*> slaveServers_ ;
313      private:
314         // the map containing context client associated to it string id for coupling out ;
315         std::map<std::string, CContextClient*> couplerOutClient_ ;
316         // the map containing context server associated to it string id for coupling out ;
317         std::map<std::string, CContextServer*> couplerOutServer_ ;
318         // the map containing context client associated to it string id for coupling in ;
319         std::map<std::string, CContextClient*> couplerInClient_ ;
320         // the map containing context server associated to it string id for coupling in ;
321         std::map<std::string, CContextServer*> couplerInServer_ ;
322      public:
323         CContextClient* getCouplerInClient(const string& contextId) { return couplerInClient_[contextId] ;}
324         CContextServer* getCouplerInServer(const string& contextId) { return couplerInServer_[contextId] ;}
325         CContextClient* getCouplerOutClient(const string& contextId) { return couplerOutClient_[contextId] ;}
326         CContextServer* getCouplerOutServer(const string& contextId) { return couplerOutServer_[contextId] ;}
327     
328 
329         std::vector<std::string> primServerId_;
330
331         CRegistry* registryIn ;    //!< input registry which is read from file
332         CRegistry* registryOut ;   //!< output registry which will be written into file at the finalize
333
334
335        MPI_Comm intraComm_ ; //! context intra communicator
336        int intraCommRank_ ; //! context intra communicator rank
337        int intraCommSize_ ; //! context intra communicator size
338       
339      private:
340         CEventScheduler* eventScheduler_ ; //! The local event scheduler for context
341         size_t hashId_ ; //! the local hashId for scheduler
342         size_t timeLine_=0 ;
343         void initEventScheduler(void) ;
344
345         bool isPostProcessed;
346         bool allProcessed;
347         bool finalized;
348         int countChildContextFinalized_;        //!< Counter of child contexts (for now it is the number of secondary server pools)
349         CGarbageCollector garbageCollector;
350         std::list<MPI_Comm> comms; //!< Communicators allocated internally
351
352         int serviceType_;  //!< service associated to the context
353         string contextId_ ; //!< context client id for the servers. For clients this is same as getId()
354         bool isProcessingEvent_ ;
355    private:     
356         CServerContext* parentServerContext_ ;
357    public:
358         CServerContext* getParentServerContext(void) { return parentServerContext_; }
359    private: 
360      bool lockedContext_=false;
361    public: 
362        void lockContext(void) {lockedContext_=true; }
363        void unlockContext(void) {lockedContext_=false; }
364        bool isLockedContext(void) { return lockedContext_;}
365      public: // Some function maybe removed in the near future
366        // virtual void toBinary  (StdOStream & os) const;
367        // virtual void fromBinary(StdIStream & is);
368   }; // class CContext
369
370   ///--------------------------------------------------------------
371
372   // Declare/Define CContextGroup and CContextDefinition
373   DECLARE_GROUP(CContext);
374
375   ///--------------------------------------------------------------
376
377} // namespace xios
378
379#endif // __XIOS_CContext__
Note: See TracBrowser for help on using the repository browser.