source: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp @ 1930

Last change on this file since 1930 was 1930, checked in by ymipsl, 4 years ago

Big update on on going work related to data distribution and transfer between clients and servers.
Revisite of the source and store filter using "connectors".

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
  • Property svn:executable set to *
File size: 35.6 KB
Line 
1#ifndef __XIOS_CGrid__
2#define __XIOS_CGrid__
3
4/// XIOS headers ///
5#include "xios_spl.hpp"
6#include "group_factory.hpp"
7
8#include "declare_group.hpp"
9#include "domain.hpp"
10#include "axis.hpp"
11#include "scalar.hpp"
12#include "array_new.hpp"
13#include "attribute_array.hpp"
14#include "distribution_server.hpp"
15#include "client_server_mapping.hpp"
16#include "utils.hpp"
17#include "transformation_enum.hpp"
18#include "grid_local_connector.hpp"
19#include "grid_elements.hpp"
20#include "grid_scatterer_connector.hpp"
21#include "grid_gatherer_connector.hpp"
22
23
24namespace xios {
25
26   /// ////////////////////// Declarations ////////////////////// ///
27
28   class CGridGroup;
29   class CGridAttributes;
30   class CDomainGroup;
31   class CAxisGroup;
32   class CScalarGroup;
33   class CGrid;
34   class CDistributionClient;
35   class CDistributionServer;
36   class CServerDistributionDescription;
37   class CClientServerMapping;
38   class CGridTransformation;
39
40   ///--------------------------------------------------------------
41
42   // Declare/Define CGridAttribute
43   BEGIN_DECLARE_ATTRIBUTE_MAP(CGrid)
44#  include "grid_attribute.conf"
45   END_DECLARE_ATTRIBUTE_MAP(CGrid)
46
47   ///--------------------------------------------------------------
48
49   class CGrid
50      : public CObjectTemplate<CGrid>
51      , public CGridAttributes
52   {
53         /// typedef ///
54         typedef CObjectTemplate<CGrid>   SuperClass;
55         typedef CGridAttributes SuperClassAttribute;
56
57      private:
58       
59        // define a structure to store elements (CDomain, CAxis, CScalar) using a void* and a type to cast the pointer
60         enum EElementType { TYPE_SCALAR, TYPE_AXIS, TYPE_DOMAIN } ;
61         struct SElement {void* ptr ; EElementType type ; CScalar* scalar ;  CAxis* axis ; CDomain* domain ; } ;
62         vector<SElement> elements_ ;
63         bool elementsComputed_ = false ; 
64         /** retrieve the vector of elements as a structure containing a void* and the type of pointer */
65         vector<SElement>& getElements(void) { if (!elementsComputed_) computeElements() ; return elements_ ; } 
66         void computeElements(void) ;
67         /** List order of axis and domain in a grid, if there is a domain, it will take value 2, axis 1, scalar 0 */
68         std::vector<int> order_;
69
70      public:
71
72         typedef CGridAttributes RelAttributes;
73         typedef CGridGroup      RelGroup;
74
75         enum EEventId
76         {
77           EVENT_ID_INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR
78         };
79
80         /// Constructeurs ///
81         CGrid(void);
82         explicit CGrid(const StdString& id);
83         CGrid(const CGrid& grid);       // Not implemented yet.
84         CGrid(const CGrid* const grid); // Not implemented yet.
85
86         /// Traitements ///
87//         void solveReference(void);
88
89         void checkEligibilityForCompressedOutput();
90         
91
92
93         void checkMaskIndex(bool doCalculateIndex);
94
95 //        virtual void toBinary  (StdOStream& os) const;
96//         virtual void fromBinary(StdIStream& is);
97
98         void addRelFileCompressed(const StdString& filename);
99
100         /// Tests ///
101         bool isCompressible(void) const;
102         bool isWrittenCompressed(const StdString& filename) const;
103
104      public:
105
106         /// Accesseurs ///
107         StdSize getDimension(void);
108
109         StdSize  getDataSize(void) ;
110
111         /**
112          * Get the local data grid size, ie the size of the compressed grid (inside the workflow)
113          * \return The size od the compressed grid
114          */
115         StdSize  getLocalDataSize(void) ;
116
117         /// Entrees-sorties de champs
118         template <int n>
119         void inputField(const CArray<double,n>& field, CArray<double,1>& stored) ;
120         template <int n>
121         void maskField(const CArray<double,n>& field, CArray<double,1>& stored) ;
122         template <int n>
123         void outputField(const CArray<double,1>& stored, CArray<double,n>& field) ; 
124         template <int n>
125         void uncompressField(const CArray<double,n>& data, CArray<double,1>& outData) ; 
126
127         virtual void parse(xml::CXMLNode& node);
128
129         /// Destructeur ///
130         virtual ~CGrid(void);
131
132      public:
133
134         /// Accesseurs statiques ///
135         static StdString GetName(void);
136         static StdString GetDefName(void);
137
138         static ENodeType GetType(void);
139
140         /// Instanciateurs Statiques ///
141         static CGrid* createGrid(CDomain* domain);
142         static CGrid* createGrid(CDomain* domain, CAxis* axis);
143         static CGrid* createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
144                                  const CArray<int,1>& axisDomainOrder = CArray<int,1>());
145         static CGrid* createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
146                                  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder = CArray<int,1>());
147         static CGrid* createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
148                                  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder);
149         static StdString generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
150                                     const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder = CArray<int,1>());
151         static StdString generateId(const CGrid* gridSrc, const CGrid* gridDest);
152         static CGrid* cloneGrid(const StdString& idNewGrid, CGrid* gridSrc);
153
154      public:           
155         void computeIndexServer(void);
156         void computeIndex(void);
157         void computeIndexScalarGrid();
158         void computeWrittenIndex();
159         void solveDomainAxisRef(bool areAttributesChecked);
160         void checkElementsAttributes(void) ;
161
162         void solveDomainRef(bool checkAtt);
163         void solveAxisRef(bool checkAtt);
164         void solveScalarRef(bool checkAtt);
165         void solveElementsRefInheritance(bool apply = true);
166        // void solveTransformations();
167         void solveDomainAxisBaseRef();
168
169         CDomain* addDomain(const std::string& id=StdString());
170         CAxis* addAxis(const std::string& id=StdString());
171         CScalar* addScalar(const std::string& id=StdString());
172
173      public:
174         void sendGridToFileServer(CContextClient* client) ;
175      private:
176         std::set<CContextClient*> sendGridToFileServer_done_ ;
177     
178      public:
179         void sendGridToCouplerOut(CContextClient* client, const string& fieldId) ;
180      private:
181         std::set<CContextClient*> sendGridToCouplerOut_done_ ;
182
183      public:
184         void makeAliasForCoupling(const string& fieldId) ;
185
186      public:
187         void sendAddDomain(const std::string& id,CContextClient* contextClient);
188         void sendAddAxis(const std::string& id,CContextClient* contextClient);
189         void sendAddScalar(const std::string& id,CContextClient* contextClient);
190         void sendAllDomains(CContextClient* contextClient);
191         void sendAllAxis(CContextClient* contextClient);
192         void sendAllScalars(CContextClient* contextClient);
193
194         static void recvAddDomain(CEventServer& event);
195         void recvAddDomain(CBufferIn& buffer);
196         static void recvAddAxis(CEventServer& event);
197         void recvAddAxis(CBufferIn& buffer);
198         static void recvAddScalar(CEventServer& event);
199         void recvAddScalar(CBufferIn& buffer);
200
201         static bool dispatchEvent(CEventServer& event);
202         static void recvIndex(CEventServer& event);
203         void recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server);
204       
205       public: 
206         void sendIndex(CContextClient* client, const string& gridId="");
207       private:
208          set<CContextClient*> sendIndex_done_ ;
209       
210       public:
211         void sendIndexScalarGrid(CContextClient* client, const string& gridId="");
212       private:
213          set<CContextClient*> sendIndexScalarGrid_done_ ;
214     
215       public:
216         void setContextClient(CContextClient* contextClient);
217
218         void computeDomConServer();
219         std::map<int, int> getDomConServerSide();
220         std::map<int, StdSize> getAttributesBufferSize(CContextClient* client, bool bufferForWriting = false);
221         std::map<int, StdSize> getDataBufferSize(CContextClient* client, const std::string& id = "", bool bufferForWriting = false);
222         std::vector<StdString> getDomainList();
223         std::vector<StdString> getAxisList();
224         std::vector<StdString> getScalarList();
225         std::vector<CDomain*> getDomains();
226         std::vector<CAxis*> getAxis();
227         std::vector<CScalar*> getScalars();
228         CDomain* getDomain(int domainIndex);
229         CAxis* getAxis(int axisIndex);
230         CScalar* getScalar(int scalarIndex);
231         std::vector<int> getAxisOrder();
232         std::vector<int> getGlobalDimension();
233         bool isScalarGrid() const;         
234
235         bool doGridHaveDataToWrite();
236         bool doGridHaveDataDistributed(CContextClient* client = 0);
237         size_t getWrittenDataSize() ;
238         int getNumberWrittenIndexes() const;
239         int getTotalNumberWrittenIndexes() const;
240         int getOffsetWrittenIndexes() const;
241
242         CGridTransformation* getTransformations();
243
244         void transformGrid(CGrid* transformGridSrc);
245         
246         void prepareTransformGrid(CGrid* transformGridSrc);
247         bool prepareTransformGrid_done_ = false ;
248
249         void makeTransformGrid(void); 
250         bool makeTransformGrid_done_ = false ;
251         
252         std::vector<std::string> getAuxInputTransformGrid(void) ; 
253
254         void completeGrid(CGrid* transformGridSrc = 0);
255         void doAutoDistribution(CGrid* transformGridSrc);
256         bool isTransformed();
257         void setTransformed();
258         bool isGenerated();
259         void setGenerated();
260         void addTransGridSource(CGrid* gridSrc);
261         std::map<CGrid*, std::pair<bool,StdString> >& getTransGridSource();
262         bool hasTransform();
263         size_t getGlobalWrittenSize(void) ;
264         
265         bool isCompleted(void) ;
266         void setCompleted(void) ;
267         void unsetCompleted(void) ;
268
269
270         bool hasMask(void) const;
271         void checkMask(void);
272         void createMask(void);
273         void modifyMask(const CArray<int,1>& indexToModify, bool valueToModify = false);
274         void modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue = false);
275       
276        /** get mask pointer stored in mask_1d, or mask_2d, or..., or mask_7d */
277         CArray<bool,1> mask_ ;
278         CArray<bool,1>& getMask(void) ;
279
280         void computeGridGlobalDimension(const std::vector<CDomain*>& domains,
281                                         const std::vector<CAxis*>& axis,
282                                         const std::vector<CScalar*>& scalars,
283                                         const CArray<int,1>& axisDomainOrder);
284
285         void computeGridIndexToFileServer(CContextClient* client) ;
286 
287     private:
288        /** Client-like distribution calculated based on the knowledge of the entire grid */
289       CDistributionClient* clientDistribution_;
290     public: 
291       void computeClientDistribution(void) ;
292     private:
293       bool computeClientDistribution_done_ = false ;
294     public:
295       CDistributionClient* getClientDistribution(void); 
296
297     private:   
298       /** Server-like distribution calculated upon receiving indexes */
299       CDistributionServer* serverDistribution_;
300       void computeServerDistribution(void) ;
301       bool computeServerDistribution_done_=false ;
302     public: 
303       CDistributionServer* getServerDistribution(void) { if (!computeServerDistribution_done_) computeServerDistribution() ; return serverDistribution_ ;}
304
305
306     private:
307       template<int N>
308       void checkGridMask(CArray<bool,N>& gridMask,
309                          const std::vector<CArray<bool,1>* >& domainMasks,
310                          const std::vector<CArray<bool,1>* >& axisMasks,
311                          const CArray<int,1>& axisDomainOrder,
312                          bool createMask = false);
313
314        template<int N>
315        void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify);
316
317        template<int N>
318        void modifyGridMaskSize(CArray<bool,N>& gridMask, const std::vector<int>& eachDimSize, bool newValue);
319
320        void storeField_arr(const double* const data, CArray<double, 1>& stored) ;
321        void restoreField_arr(const CArray<double, 1>& stored, double* const data) ;
322        void uncompressField_arr(const double* const data, CArray<double, 1>& outData) ;
323        void maskField_arr(const double* const data, CArray<double, 1>& stored) ;
324
325        void setVirtualDomainGroup(CDomainGroup* newVDomainGroup);
326        void setVirtualAxisGroup(CAxisGroup* newVAxisGroup);
327        void setVirtualScalarGroup(CScalarGroup* newVScalarGroup);
328
329        void setDomainList(const std::vector<CDomain*> domains = std::vector<CDomain*>());
330        void setAxisList(const std::vector<CAxis*> axis = std::vector<CAxis*>());
331        void setScalarList(const std::vector<CScalar*> scalars = std::vector<CScalar*>());
332
333        CDomainGroup* getVirtualDomainGroup() const;
334        CAxisGroup* getVirtualAxisGroup() const;
335        CScalarGroup* getVirtualScalarGroup() const;
336
337        void checkAttributesAfterTransformation();
338        void setTransformationAlgorithms();
339        void computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement,
340                                   const CContextClient* client,
341                                   CClientServerMapping::GlobalIndexMap& globalIndexOnServer);
342        int computeGridGlobalDimension(std::vector<int>& globalDim,
343                                       const std::vector<CDomain*> domains,
344                                       const std::vector<CAxis*> axis,
345                                       const std::vector<CScalar*> scalars,
346                                       const CArray<int,1>& axisDomainOrder);
347        int getDistributedDimension();
348
349        void computeConnectedClients(CContextClient* client);
350        set<CContextClient*> computeConnectedClients_done_ ;
351
352        void computeConnectedClientsScalarGrid(CContextClient* client); 
353        set<CContextClient*> computeConnectedClientsScalarGrid_done_ ;
354
355      public:
356/** Array containing the local index of the grid
357 *  storeIndex_client[local_workflow_grid_index] -> local_model_grid_index.
358 *  Used to store field from model into the worklow, or to return field into models. 
359 *  The size of the array is the number of local index of the workflow grid */       
360        CArray<int, 1> storeIndex_client_;
361        void computeStoreIndex_client(void) ;
362        bool computeStoreIndex_client_done_ = false ;
363        CArray<int, 1>& getStoreIndex_client(void) { if (!computeStoreIndex_client_done_) computeStoreIndex_client() ; return storeIndex_client_ ;}
364
365/** Array containing the grid mask masked defined by the mask_nd grid attribute.       
366  * The corresponding masked field value provided by the model will be replaced by a NaN value
367  * in the workflow.  */
368        CArray<bool, 1> storeMask_client_;
369        void computeStoreMask_client(void) ;
370        bool computeStoreMask_client_done_ = false ;
371        CArray<bool, 1>& getStoreMask_client(void) { if (!computeStoreMask_client_done_) computeStoreMask_client() ; return storeMask_client_ ;}
372
373/** Map containing the indexes on client side that will be sent to each connected server.
374  * storeIndex_toSrv[&contextClient] -> map concerning the contextClient for which the data will be sent (client side)
375  * storeIndex_toSrv[&contextClient][rank] -> array of indexes that will be sent to each "rank" of the connected servers
376  * storeIndex_toSrv[&contextClient][rank](index_of_buffer_sent_to_server) -> local index of the field of the workflow
377  * grid that will be sent to server */
378         std::map<CContextClient*, map<int, CArray<int, 1> > > storeIndex_toSrv_;
379
380
381/** Map containing the indexes on client side that will be received from each connected server.
382  * This map is used to agreggate field data received from server (for reading) into a single array, which will be an entry
383  * point of the worklow on client side.
384  * storeIndex_toSrv[rank] -> array of indexes that will be received from each "rank" of the connected servers
385  * storeIndex_toSrv[rank](index_of_buffer_received_from_server) -> local index of the field in the "workflow grid"
386  * that has been received from server */
387         std::map<int, CArray<int, 1> > storeIndex_fromSrv_; // Support, for now, reading with level-1 server
388
389
390/** Maps storing the number of participating clients for data sent a specific server for a given contextClient, identified
391  * by the servers communicator size. In future must be direcly identified by context.
392  * nbSender_[context_server_size] -> map the number of client sender by connected rank of servers
393  * nbSender_[context_server_size] [rank_server] -> the number of client participating to a send message for a server of rank "rank_server"
394  * Usefull to indicate in a message the number of participant needed by the transfer protocol */
395         std::map<int, std::map<int,int> > nbSenders_;
396
397      private:
398/** Maps storing the number of participating servers for data sent a specific client for a given contextClient.
399  * Symetric of nbSenders_, but for server side which want to send data to client.
400  * nbReadSender_[context_client_size] -> map the number of server sender by connected rank of clients
401  * nbReadSender_[context_client_size] [rank_client] -> the number of server participating to a send message for a client of rank "rank_client"
402  * Usefull to indicate in a message the number of participant needed by the transfer protocol */
403         std::map<CContextClient*, std::map<int,int> > nbReadSenders_;
404      public:
405         std::map<int,int>& getNbReadSenders(CContextClient* client) 
406         { if (nbReadSenders_.count(client)==0) computeNbReadSenders(client) ; return nbReadSenders_[client] ;}
407      private:
408         void computeNbReadSenders(CContextClient* client) ;
409     
410
411// Manh Ha's comment: " A client receives global index from other clients (via recvIndex)
412// then does mapping these index into local index of STORE_CLIENTINDEX
413// In this way, store_clientIndex can be used as an input of a source filter
414// Maybe we need a flag to determine whether a client wants to write. TODO "
415
416      private:
417       /** Map storing received data on server side. This map is the equivalent to the storeIndex_client, but for data received from client
418        * instead that from model. This map is used to concatenate data received from several clients into a single array on server side
419        * which match the local workflow grid.
420        * outLocalIndexStoreOnClient_[client_rank] -> Array of index from client of rank "client_rank"
421        * outLocalIndexStoreOnClient_[client_rank](index of buffer from client) -> local index of the workflow grid
422        * The map is created in CGrid::computeClientIndex and filled upon receiving data in CField::recvUpdateData().
423        * Symetrically it is also used to send data from a server to several client for reading case. */
424        map<int, CArray<size_t, 1>> outLocalIndexStoreOnClient_; 
425      public:
426         void computeOutLocalIndexStoreOnClient(void) ;
427      private:
428         bool computeOutLocalIndexStoreOnClient_done_ = false ; 
429      public:   
430         map<int, CArray<size_t, 1>>& getOutLocalIndexStoreOnClient(void) 
431         { if (!computeOutLocalIndexStoreOnClient_done_) computeOutLocalIndexStoreOnClient(); return outLocalIndexStoreOnClient_ ; }
432
433      public:
434/** Indexes calculated based on server-like distribution.
435 *  They are used for writing/reading data and only calculated for server level that does the writing/reading.
436 *  Along with localIndexToWriteOnClient, these indexes are used to correctly place incoming data.
437 *  size of the array : numberWrittenIndexes_ : number of index written in a compressed way
438 *  localIndexToWriteOnServer_(compressed_written_index) : -> local uncompressed index that will be written in the file */
439         CArray<size_t,1> localIndexToWriteOnServer_;
440
441/** Indexes calculated based on client-like distribution.
442  * They are used for writing/reading data and only calculated for server level that does the writing/reading.
443  * Along with localIndexToWriteOnServer, these indexes are used to correctly place incoming data.
444  * size of the array : numberWrittenIndexes_
445  * localIndexToWriteOnClient_(compressed_written_index) -> local index of the workflow grid*/
446         CArray<size_t,1> localIndexToWriteOnClient_;
447
448      public: 
449        bool isDataDistributed(void) ; 
450      private:
451
452/** Clients that have to send a grid. There can be multiple clients in case of secondary server, otherwise only one client. */
453        std::list<CContextClient*> clients;
454        std::set<CContextClient*> clientsSet;
455
456      private: 
457        /** Map storing received indexes on server side sent by clients. Key = sender rank, value = global index array.
458            Later, the global indexes received will be mapped onto local index computed with the local distribution.
459            outGlobalIndexFromClient_[rank] -> array of global index send by client of rank "rank"
460            outGlobalIndexFromClient_[rank](n) -> global index of datav n sent by client
461        */     
462        map<int, CArray<size_t, 1> > outGlobalIndexFromClient_;
463      public: 
464        map<int, CArray<size_t, 1> >& getOutGlobalIndexFromClient() { return outGlobalIndexFromClient_ ;}
465
466      private:
467        bool isChecked;
468        bool isDomainAxisChecked;
469        bool isIndexSent;
470
471        CDomainGroup* vDomainGroup_;
472        CAxisGroup* vAxisGroup_;
473        CScalarGroup* vScalarGroup_;
474        std::vector<std::string> axisList_, domList_, scalarList_;
475        bool isAxisListSet, isDomListSet, isScalarListSet;
476
477        CClientServerMapping* clientServerMap_;
478        int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_;
479
480/** Map storing local ranks of connected receivers. Key = size of receiver's intracomm.
481  * It is calculated in computeConnectedClients(). */
482        std::map<int, std::vector<int> > connectedServerRank_;
483
484/** Map storing the size of data to be send. Key = size of receiver's intracomm
485  * It is calculated in computeConnectedClients(). */
486        std::map<int, std::map<int,size_t> > connectedDataSize_;
487
488/** Ranks of connected receivers in case of reading. It is calculated in recvIndex(). */
489        std::vector<int> connectedServerRankRead_;
490
491/** Size of data to be send in case of reading. It is calculated in recvIndex(). */
492        std::map<int,size_t> connectedDataSizeRead_;
493     
494         //! True if and only if the data defined on the grid can be outputted in a compressed way
495        bool isCompressible_;
496        std::set<std::string> relFilesCompressed;
497
498        bool isTransformed_, isGenerated_;
499        bool computedWrittenIndex_;
500       
501        std::vector<int> axisPositionInGrid_;
502        void computeAxisPositionInGrid(void) ;
503        bool computeAxisPositionInGrid_done_ = false ;
504        std::vector<int>& getAxisPositionInGrid(void) { if (!computeAxisPositionInGrid_done_) computeAxisPositionInGrid() ; return axisPositionInGrid_ ;}
505
506        CGridTransformation* transformations_;
507        bool hasDomainAxisBaseRef_;       
508        std::map<CGrid*, std::pair<bool,StdString> > gridSrc_;
509        bool hasTransform_;
510
511/** Map storing global indexes of server-like (band-wise) distribution for sending to receivers (client side).
512  * Key = size of receiver's intracomm (i.e. number of servers)
513  * ~ map<int, umap<int, std::vector<size_t> >> globalIndexOnServer_
514  * globalIndexOnServer_[servers_size] -> map for a distribution of size "servers_size" (number of servers)
515  * globalIndexOnServer_[servers_size][server_rank] -> array of global index managed by server of rank "server_rank"
516  * globalIndexOnServer_[servers_size][server_rank][n] -> global index of data to be send to the server by client based on sub element of the grid.
517  * -> grid masking is not included.
518  */
519//        std::map<CContextClient*, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;
520        std::map<int, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;
521
522     
523
524     //////////////////////////////////////////////////////////////////////////////////////
525     //  this part is related to distribution, element definition, views and connectors  //
526     //////////////////////////////////////////////////////////////////////////////////////
527
528
529      private: 
530        CGridLocalElements* gridLocalElements_= nullptr ;
531        void computeGridLocalElements(void) ;
532      public:
533        CGridLocalElements* getGridLocalElements(void) { if (gridLocalElements_==nullptr) computeGridLocalElements() ; return gridLocalElements_ ;}
534
535      private:
536        CGridLocalConnector* modelToWorkflowConnector_ ;
537      public:
538        void computeModelToWorkflowConnector(void) ;
539        CGridLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_;}
540
541      private:
542        CGridLocalConnector* workflowToModelConnector_ ;
543      public:
544        void computeWorkflowToModelConnector(void) ;
545        CGridLocalConnector* getWorkflowToModelConnector(void) { if (workflowToModelConnector_==nullptr) computeWorkflowToModelConnector() ; return workflowToModelConnector_;}
546
547      public: //?
548        void distributeGridToFileServer(CContextClient* client);
549     
550      private:
551         map<CContextClient*, CGridScattererConnector*> clientToServerConnector_ ;
552      public:
553         CGridScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;} // make some test to see if connector exits for the given client
554         
555      private:
556         CGridGathererConnector* serverFromClientConnector_ = nullptr ;
557      public:
558         CGridGathererConnector* getServerFromClientConnector(void) { if (serverFromClientConnector_==nullptr) computeServerFromClientConnector() ; return serverFromClientConnector_;}
559         void computeServerFromClientConnector(void) ;
560         
561      private:
562        CGridLocalConnector* workflowToFullConnector_ = nullptr;
563      public:
564        void computeWorkflowToFullConnector(void) ;
565        CGridLocalConnector* getWorkflowToFullConnector(void) { if (workflowToFullConnector_==nullptr) computeWorkflowToFullConnector() ; return workflowToFullConnector_;}
566
567      private:
568        CGridLocalConnector* fullToWorkflowConnector_ = nullptr;
569      public:
570        void computeFullToWorkflowConnector(void) ;
571        CGridLocalConnector* getFullToWorkflowConnector(void) { if (fullToWorkflowConnector_==nullptr) computeFullToWorkflowConnector() ; return fullToWorkflowConnector_;}
572
573      private:
574         CGridGathererConnector* clientFromClientConnector_ = nullptr ;
575      public:
576         CGridGathererConnector* getClientFromClientConnector(void) { if (clientFromClientConnector_==nullptr) computeClientFromClientConnector() ; return clientFromClientConnector_;}
577         void computeClientFromClientConnector(void) ;
578
579      private:
580         map<CContextClient*, CGridScattererConnector*> clientToClientConnector_ ;
581      public:
582         CGridScattererConnector* getClientToClientConnector(CContextClient* client) { return clientToClientConnector_[client] ;} // make some test to see if connector exits for the given client
583 
584
585      private:
586         CGridGathererConnector* clientFromServerConnector_ = nullptr ;
587      public:
588         CGridGathererConnector* getClientFromServerConnector(void) { if (clientFromServerConnector_==nullptr) computeClientFromServerConnector() ; return clientFromServerConnector_;}
589         void computeClientFromServerConnector(void) ;
590
591   }; // class CGrid
592
593   ///--------------------------------------------------------------
594
595   template <int n>
596   void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored)
597   TRY
598   {
599//#ifdef __XIOS_DEBUG
600      if (this->getDataSize() != field.numElements())
601         ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const",
602                << "[ Awaiting data of size = " << this->getDataSize() << ", "
603                << "Received data size = "      << field.numElements() << " ] "
604                << "The data array does not have the right size! "
605                << "Grid = " << this->getId())
606//#endif
607      this->storeField_arr(field.dataFirst(), stored);
608   }
609   CATCH
610
611/* obsolete
612   template <int n>
613   void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)
614   {
615//#ifdef __XIOS_DEBUG
616      if (this->getDataSize() != field.numElements())
617         ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const",
618                << "[ Awaiting data of size = " << this->getDataSize() << ", "
619                << "Received data size = "      << field.numElements() << " ] "
620                << "The data array does not have the right size! "
621                << "Grid = " << this->getId())
622//#endif
623      this->maskField_arr(field.dataFirst(), stored);
624   }
625*/
626   template <int n>
627   void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)
628   {
629      auto connector = getModelToWorkflowConnector() ;
630
631      if (connector->getSrcSize() != field.numElements())
632         ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const",
633                << "[ Awaiting data of size = " << this->getDataSize() << ", "
634                << "Received data size = "      << field.numElements() << " ] "
635                << "The data array does not have the right size! "
636                << "Grid = " << this->getId())
637      const double nanValue = std::numeric_limits<double>::quiet_NaN();
638      connector->transfer(field, stored, nanValue) ;
639   }
640
641
642
643   template <int n>
644   void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field)
645   TRY
646   {
647//#ifdef __XIOS_DEBUG
648      if (this->getDataSize() != field.numElements())
649         ERROR("void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const",
650                << "[ Size of the data = " << this->getDataSize() << ", "
651                << "Output data size = "   << field.numElements() << " ] "
652                << "The ouput array does not have the right size! "
653                << "Grid = " << this->getId())
654//#endif
655      this->restoreField_arr(stored, field.dataFirst());
656   }
657   CATCH
658
659   /*!
660     This function removes the effect of mask on received data on the server.
661     This function only serve for the checking purpose. TODO: Something must be done to seperate mask and data_index from each other in received data
662     \data data received data with masking effect on the server
663     \outData data without masking effect
664   */
665   template <int N>
666   void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData)
667   TRY
668   {     
669     uncompressField_arr(data.dataFirst(), outData);
670   }
671   CATCH
672
673   template<int N>
674   void CGrid::checkGridMask(CArray<bool,N>& gridMask,
675                             const std::vector<CArray<bool,1>* >& domainMasks,
676                             const std::vector<CArray<bool,1>* >& axisMasks,
677                             const CArray<int,1>& axisDomainOrder,
678                             bool createMask)
679   TRY
680   {
681     int idx = 0;
682     int numElement = axisDomainOrder.numElements();
683     int dim = domainMasks.size() * 2 + axisMasks.size();
684     std::vector<CDomain*> domainP = this->getDomains();
685     std::vector<CAxis*> axisP = this->getAxis();
686
687     std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim);
688     std::vector<int> currentIndex(dim);
689     int idxDomain = 0, idxAxis = 0;
690    for (int i = 0; i < numElement; ++i)
691    {
692      indexMap[i] = idx;
693      if (2 == axisDomainOrder(i)) {
694          eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni;
695          eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj;
696          idx += 2; ++idxDomain;
697      }
698      else if (1 == axisDomainOrder(i)) {
699//        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements();
700        eachDimSize[indexMap[i]] = axisP[idxAxis]->n;
701        ++idx; ++idxAxis;
702      }
703      else {};
704    }
705
706    if (!gridMask.isEmpty() && !createMask)
707    {
708      for (int i = 0; i < dim; ++i)
709      {
710        if (gridMask.extent(i) != eachDimSize[i])
711          ERROR("CGrid::checkMask(void)",
712                << "The mask has one dimension whose size is different from the one of the local grid." << std::endl
713                << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl
714                << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl
715                << "Grid = " << this->getId())
716      }
717    }
718    else {
719        CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);
720        gridMask = true;
721    }
722
723    int ssize = gridMask.numElements();
724    idx = 0;
725    while (idx < ssize)
726    {
727      for (int i = 0; i < dim-1; ++i)
728      {
729        if (idxLoop[i] == eachDimSize[i])
730        {
731          idxLoop[i] = 0;
732          ++idxLoop[i+1];
733        }
734      }
735
736      // Find out outer index
737      idxDomain = idxAxis = 0;
738      bool maskValue = true;
739      for (int i = 0; i < numElement; ++i)
740      {
741        if (2 == axisDomainOrder(i))
742        {
743          int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]];
744          if (idxTmp < (*domainMasks[idxDomain]).numElements())
745            maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp);
746          else
747            maskValue = false;
748          ++idxDomain;
749        }
750        else if (1 == axisDomainOrder(i))
751        {
752          int idxTmp = idxLoop[indexMap[i]];
753          if (idxTmp < (*axisMasks[idxAxis]).numElements())
754            maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp);
755          else
756            maskValue = false;
757
758          ++idxAxis;
759        }
760      }
761
762      int maskIndex = idxLoop[0];
763      int mulDim = 1;
764      for (int k = 1; k < dim; ++k)
765      {
766        mulDim *= eachDimSize[k-1];
767        maskIndex += idxLoop[k]*mulDim;
768      }
769      *(gridMask.dataFirst()+maskIndex) &= maskValue;
770
771      ++idxLoop[0];
772      ++idx;
773    }
774   }
775   CATCH_DUMP_ATTR
776
777   template<int N>
778   void CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,
779                                  const std::vector<int>& eachDimSize,
780                                  bool newValue)
781   TRY
782   {
783      if (N != eachDimSize.size())
784      {
785        // ERROR("CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,
786        //                                  const std::vector<int>& eachDimSize,
787        //                                  bool newValue)",
788        //       << "Dimension size of the mask is different from input dimension size." << std::endl
789        //       << "Mask dimension is " << N << "." << std::endl
790        //       << "Input dimension is " << eachDimSize.size() << "." << std::endl
791        //       << "Grid = " << this->getId())
792      }
793      CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);
794      gridMask = newValue;
795   }
796   CATCH_DUMP_ATTR
797                                 
798
799   /*!
800     Modify the current mask of grid, the local index to be modified will take value false
801     \param [in/out] gridMask current mask of grid
802     \param [in] indexToModify local index to modify
803   */
804   template<int N>
805   void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify)
806   TRY
807   {     
808     int num = indexToModify.numElements();
809     for (int idx = 0; idx < num; ++idx)
810     {
811       *(gridMask.dataFirst()+indexToModify(idx)) = valueToModify;
812     }
813   }
814   CATCH_DUMP_ATTR
815
816   ///--------------------------------------------------------------
817
818
819
820   // Declare/Define CGridGroup and CGridDefinition
821   DECLARE_GROUP(CGrid);
822
823   ///--------------------------------------------------------------
824
825} // namespace xios
826
827#endif // __XIOS_CGrid__
Note: See TracBrowser for help on using the repository browser.