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

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

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