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, 14 months 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.