source: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp @ 1934

Last change on this file since 1934 was 1934, 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".

-> inputs work again

YM

File size: 9.7 KB
Line 
1#include "scalar.hpp"
2
3#include "attribute_template.hpp"
4#include "object_template.hpp"
5#include "group_template.hpp"
6#include "object_factory.hpp"
7#include "xios_spl.hpp"
8#include "type.hpp"
9#include "context.hpp"
10
11namespace xios {
12
13   /// ////////////////////// Définitions ////////////////////// ///
14
15   CScalar::CScalar(void)
16      : CObjectTemplate<CScalar>()
17      , CScalarAttributes()
18      , relFiles()
19   { /* Ne rien faire de plus */ }
20
21   CScalar::CScalar(const StdString & id)
22      : CObjectTemplate<CScalar>(id)
23      , CScalarAttributes()
24      , relFiles()
25   { /* Ne rien faire de plus */ }
26
27   CScalar::~CScalar(void)
28   { /* Ne rien faire de plus */ }
29
30   std::map<StdString, ETranformationType> CScalar::transformationMapList_ = std::map<StdString, ETranformationType>();
31   bool CScalar::dummyTransformationMapList_ = CScalar::initializeTransformationMap(CScalar::transformationMapList_);
32   bool CScalar::initializeTransformationMap(std::map<StdString, ETranformationType>& m)
33   {
34     m["reduce_axis"]   = TRANS_REDUCE_AXIS_TO_SCALAR;
35     m["extract_axis"]  = TRANS_EXTRACT_AXIS_TO_SCALAR;
36     m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_SCALAR;
37     m["reduce_scalar"] = TRANS_REDUCE_SCALAR_TO_SCALAR;
38   }
39
40   StdString CScalar::GetName(void)   { return (StdString("scalar")); }
41   StdString CScalar::GetDefName(void){ return (CScalar::GetName()); }
42   ENodeType CScalar::GetType(void)   { return (eScalar); }
43
44   CScalar* CScalar::createScalar()
45   {
46     CScalar* scalar = CScalarGroup::get("scalar_definition")->createChild();
47     return scalar;
48   }
49
50   bool CScalar::IsWritten(const StdString & filename) const
51   {
52      return (this->relFiles.find(filename) != this->relFiles.end());
53   }
54
55   void CScalar::addRelFile(const StdString& filename)
56   {
57      this->relFiles.insert(filename);
58   }
59
60   void CScalar::checkAttributes(void)
61   {
62      if (checkAttributes_done_) return ;
63
64      checkAttributes_done_ = true ; 
65   }
66
67  void CScalar::checkAttributesOnClient()
68  {
69
70  }
71
72  /*!
73    Compare two scalar objects.
74    They are equal if only if they have identical attributes as well as their values.
75    Moreover, they must have the same transformations.
76  \param [in] scalar Compared scalar
77  \return result of the comparison
78  */
79  bool CScalar::isEqual(CScalar* obj)
80  {
81    vector<StdString> excludedAttr;
82    excludedAttr.push_back("scalar_ref");
83    bool objEqual = SuperClass::isEqual(obj, excludedAttr);
84    if (!objEqual) return objEqual;
85
86    TransMapTypes thisTrans = this->getAllTransformations();
87    TransMapTypes objTrans  = obj->getAllTransformations();
88
89    TransMapTypes::const_iterator it, itb, ite;
90    std::vector<ETranformationType> thisTransType, objTransType;
91    for (it = thisTrans.begin(); it != thisTrans.end(); ++it)
92      thisTransType.push_back(it->first);
93    for (it = objTrans.begin(); it != objTrans.end(); ++it)
94      objTransType.push_back(it->first);
95
96    if (thisTransType.size() != objTransType.size()) return false;
97    for (int idx = 0; idx < thisTransType.size(); ++idx)
98      objEqual &= (thisTransType[idx] == objTransType[idx]);
99
100    return objEqual;
101  }
102
103  CTransformation<CScalar>* CScalar::addTransformation(ETranformationType transType, const StdString& id)
104  {
105    transformationMap_.push_back(std::make_pair(transType, CTransformation<CScalar>::createTransformation(transType,id)));
106    return transformationMap_.back().second;
107  }
108
109  bool CScalar::hasTransformation()
110  {
111    return (!transformationMap_.empty());
112  }
113
114  void CScalar::setTransformations(const TransMapTypes& scalarTrans)
115  {
116    transformationMap_ = scalarTrans;
117  }
118
119  CScalar::TransMapTypes CScalar::getAllTransformations(void)
120  {
121    return transformationMap_;
122  }
123
124  void CScalar::duplicateTransformation(CScalar* src)
125  {
126    if (src->hasTransformation())
127    {
128      this->setTransformations(src->getAllTransformations());
129    }
130  }
131
132  /*!
133   * Go through the hierarchy to find the scalar from which the transformations must be inherited
134   */
135  void CScalar::solveInheritanceTransformation()
136  {
137    if (hasTransformation() || !hasDirectScalarReference())
138      return;
139
140    CScalar* scalar = this;
141    std::vector<CScalar*> refScalar;
142    while (!scalar->hasTransformation() && scalar->hasDirectScalarReference())
143    {
144      refScalar.push_back(scalar);
145      scalar = scalar->getDirectScalarReference();
146    }
147
148    if (scalar->hasTransformation())
149      for (size_t i = 0; i < refScalar.size(); ++i)
150        refScalar[i]->setTransformations(scalar->getAllTransformations());
151  }
152 
153  void CScalar::sendScalarToFileServer(CContextClient* client)
154  {
155    if (sendScalarToFileServer_done_.count(client)!=0) return ;
156    else sendScalarToFileServer_done_.insert(client) ;
157    StdString scalarDefRoot("scalar_definition");
158    CScalarGroup* scalarPtr = CScalarGroup::get(scalarDefRoot);
159    this->sendAllAttributesToServer(client);
160  }
161
162  void CScalar::sendScalarToCouplerOut(CContextClient* client, const string& fieldId, int posInGrid)
163  {
164    if (sendScalarToCouplerOut_done_.count(client)!=0) return ;
165    else sendScalarToCouplerOut_done_.insert(client) ;
166
167    string scalarId="_scalar["+std::to_string(posInGrid)+"]_of_"+fieldId ;
168   
169    if (!scalar_ref.isEmpty())
170    {
171      auto scalar_ref_tmp=scalar_ref.getValue() ;
172      scalar_ref.reset() ; // remove the reference, find an other way to do that more cleanly
173      this->sendAllAttributesToServer(client, scalarId)  ;
174      scalar_ref = scalar_ref_tmp ;
175    }
176    else this->sendAllAttributesToServer(client, scalarId)  ;
177
178
179    this->sendAllAttributesToServer(client, scalarId);
180  } 
181
182  void CScalar::makeAliasForCoupling(const string& fieldId, int posInGrid)
183  {
184    const string scalarId = "_scalar["+std::to_string(posInGrid)+"]_of_"+fieldId ;
185    this->createAlias(scalarId) ;
186  }
187
188  void CScalar::setContextClient(CContextClient* contextClient)
189  TRY
190  {
191    if (clientsSet.find(contextClient)==clientsSet.end())
192    {
193      clients.push_back(contextClient) ;
194      clientsSet.insert(contextClient);
195    }
196  }
197  CATCH_DUMP_ATTR
198  /*!
199    Parse children nodes of a scalar in xml file.
200    \param node child node to process
201  */
202  void CScalar::parse(xml::CXMLNode & node)
203  {
204    SuperClass::parse(node);
205
206    if (node.goToChildElement())
207    {
208      StdString nodeElementName;
209      do
210      {
211        StdString nodeId("");
212        if (node.getAttributes().end() != node.getAttributes().find("id"))
213        { nodeId = node.getAttributes()["id"]; }
214
215        nodeElementName = node.getElementName();
216        std::map<StdString, ETranformationType>::const_iterator ite = transformationMapList_.end(), it;
217        it = transformationMapList_.find(nodeElementName);
218        if (ite != it)
219        {
220          transformationMap_.push_back(std::make_pair(it->second, CTransformation<CScalar>::createTransformation(it->second,
221                                                                                                                 nodeId,
222                                                                                                                 &node)));
223        }
224        else
225        {
226          ERROR("void CScalar::parse(xml::CXMLNode & node)",
227                << "The transformation " << nodeElementName << " has not been supported yet.");
228        }
229      } while (node.goToNextElement()) ;
230      node.goToParentElement();
231    }
232  }
233
234   //////////////////////////////////////////////////////////////////////////////////////
235   //  this part is related to distribution, element definition, views and connectors  //
236   //////////////////////////////////////////////////////////////////////////////////////
237
238   void CScalar::initializeLocalElement(void)
239   {
240      // after checkAttribute index of size n
241      int rank = CContext::getCurrent()->getIntraCommRank() ;
242     
243      CArray<size_t,1> ind(1) ;
244      ind(0)=0 ;
245
246      localElement_ = new CLocalElement(rank, 1, ind) ;
247   }
248
249   void CScalar::addFullView(void)
250   {
251      CArray<int,1> index(1) ;
252      for(int i=0; i<1 ; i++) index(0)=0 ;
253      localElement_ -> addView(CElementView::FULL, index) ;
254   }
255
256   void CScalar::addWorkflowView(void)
257   {
258     CArray<int,1> index(1) ;
259     for(int i=0; i<1 ; i++) index(0)=0 ;
260     localElement_ -> addView(CElementView::WORKFLOW, index) ;
261   }
262
263   void CScalar::addModelView(void)
264   {
265     CArray<int,1> index(1) ;
266     for(int i=0; i<1 ; i++) index(0)=0 ;
267     localElement_->addView(CElementView::MODEL, index) ;
268   }
269
270   void CScalar::computeModelToWorkflowConnector(void)
271   { 
272     CLocalView* srcView=getLocalView(CElementView::MODEL) ;
273     CLocalView* dstView=getLocalView(CElementView::WORKFLOW) ;
274     modelToWorkflowConnector_ = new CLocalConnector(srcView, dstView); 
275     modelToWorkflowConnector_->computeConnector() ;
276   }
277
278
279   void CScalar::computeRemoteElement(CContextClient* client, EDistributionType type)
280  {
281    CContext* context = CContext::getCurrent();
282    map<int, CArray<size_t,1>> globalIndex ;
283
284    int nbServer = client->serverSize;
285    size_t nglo=1 ;
286    CArray<size_t,1> indGlo ;
287    for(size_t i=0;i<nglo;i++) indGlo(i) = i ;
288    for (auto& rankServer : client->getRanksServerLeader()) globalIndex[rankServer] = indGlo ; 
289
290    remoteElement_[client] = new CDistributedElement(nglo, globalIndex) ;
291    remoteElement_[client]->addFullView() ;
292  }
293 
294  void CScalar::distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex)
295  {
296    CContext* context = CContext::getCurrent();
297    CDistributedElement scatteredElement(1,globalIndex) ;
298    clientToServerConnector_[client] = new CScattererConnector(localElement_->getView(CElementView::FULL), scatteredElement.getView(CElementView::FULL), 
299                                                               context->getIntraComm()) ;
300    clientToServerConnector_[client] ->computeConnector() ;
301
302// need to be completed   
303
304  }
305
306
307  // Definition of some macros
308  DEFINE_REF_FUNC(Scalar,scalar)
309
310} // namespace xios
Note: See TracBrowser for help on using the repository browser.