Changeset 2019 for XIOS/dev/dev_trunk_graph/src/node/grid.cpp
- Timestamp:
- 01/22/21 12:00:29 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/dev_trunk_graph/src/node/grid.cpp
r1612 r2019 16 16 #include "client_server_mapping_distributed.hpp" 17 17 #include "distribution_client.hpp" 18 #include "grid_transformation.hpp"19 #include "grid_generate.hpp"20 18 #include "server.hpp" 21 22 namespace xios { 19 #include "distribution_type.hpp" 20 #include "grid_remote_connector.hpp" 21 #include "grid_elements.hpp" 22 #include "grid_local_view.hpp" 23 #include "grid_mask_connector.hpp" 24 #include "transformation_path.hpp" 25 #include "grid_transformation_factory_impl.hpp" 26 #include "transform_filter.hpp" 27 #include "grid_algorithm.hpp" 28 #include "grid_algorithm_generic.hpp" 29 #include "generic_algorithm_transformation.hpp" 30 #include "algo_types.hpp" 31 32 33 namespace xios 34 { 23 35 24 36 /// ////////////////////// Dfinitions ////////////////////// /// … … 30 42 , vAxisGroup_(), axisList_(), isAxisListSet(false) 31 43 , vScalarGroup_(), scalarList_(), isScalarListSet(false) 32 , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 33 , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 44 , clientDistribution_(0), isIndexSent(false) 34 45 , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 35 , isDataDistributed_(true), isCompressible_(false) 36 , transformations_(0), isTransformed_(false) 46 , isCompressible_(false) 37 47 , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 38 , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 39 , computedWrittenIndex_(false) 48 , gridSrc_(), order_() 40 49 , clients() 41 50 { … … 51 60 , vAxisGroup_(), axisList_(), isAxisListSet(false) 52 61 , vScalarGroup_(), scalarList_(), isScalarListSet(false) 53 , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 54 , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 62 , clientDistribution_(0), isIndexSent(false) 55 63 , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 56 , isDataDistributed_(true), isCompressible_(false) 57 , transformations_(0), isTransformed_(false) 64 , isCompressible_(false) 58 65 , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 59 , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 60 , computedWrittenIndex_(false) 66 , gridSrc_(), order_() 61 67 , clients() 62 68 { … … 69 75 { 70 76 if (0 != clientDistribution_) delete clientDistribution_; 71 if (0 != serverDistribution_) delete serverDistribution_;72 if (0 != clientServerMap_) delete clientServerMap_;73 if (0 != transformations_) delete transformations_;74 77 } 75 78 … … 81 84 82 85 86 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 87 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 88 ///////// MEMBER FUNCTION RELATED TO GRID CONSTRUCTION by ELEMNTS AND MANAGEMENT ///// 89 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 90 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 91 92 93 CGrid* CGrid::createGrid(CDomain* domain) 94 TRY 95 { 96 std::vector<CDomain*> vecDom(1, domain); 97 std::vector<CAxis*> vecAxis; 98 return createGrid(vecDom, vecAxis); 99 } 100 CATCH 101 102 CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis) 103 TRY 104 { 105 std::vector<CDomain*> vecDom(1, domain); 106 std::vector<CAxis*> vecAxis(1, axis); 107 108 return createGrid(vecDom, vecAxis); 109 } 110 CATCH 111 112 CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 113 const CArray<int,1>& axisDomainOrder) 114 TRY 115 { 116 std::vector<CScalar*> vecScalar; 117 return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder); 118 } 119 CATCH 120 121 CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 122 const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 123 TRY 124 { 125 return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder); 126 } 127 CATCH 128 129 CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 130 const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 131 TRY 132 { 133 if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size())) 134 ERROR("CGrid* CGrid::createGrid(...)", 135 << "The size of axisDomainOrder (" << axisDomainOrder.numElements() 136 << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<")."); 137 138 CGrid* grid = CGridGroup::get("grid_definition")->createChild(id); 139 grid->setDomainList(domains); 140 grid->setAxisList(axis); 141 grid->setScalarList(scalars); 142 143 // By default, domains are always the first elements of a grid 144 if (0 == axisDomainOrder.numElements()) 145 { 146 int size = domains.size() + axis.size() + scalars.size(); 147 int nb = 0; 148 grid->axis_domain_order.resize(size); 149 for (int i = 0; i < size; ++i) 150 { 151 if (i < domains.size()) 152 { 153 grid->axis_domain_order(i) = 2; 154 grid->order_.push_back(2) ; 155 } 156 else if ((scalars.size() < (size-nb)) < size) 157 { 158 grid->axis_domain_order(i) = 1; 159 grid->order_.push_back(1) ; 160 } 161 else 162 { 163 grid->axis_domain_order(i) = 0; 164 grid->order_.push_back(0) ; 165 } 166 ++nb; 167 } 168 } 169 else 170 { 171 grid->axis_domain_order.resize(axisDomainOrder.numElements()); 172 grid->axis_domain_order = axisDomainOrder; 173 grid->order_.clear() ; 174 for(int i=0; i<axisDomainOrder.numElements();i++) grid->order_.push_back(axisDomainOrder(i)) ; 175 176 } 177 178 // grid->solveElementsRefInheritance(true); 179 grid->computeElements() ; 180 return grid; 181 } 182 CATCH 183 184 //---------------------------------------------------------------- 185 186 //! Change virtual field group to a new one 187 void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup) 188 TRY 189 { 190 this->vDomainGroup_ = newVDomainGroup; 191 } 192 CATCH_DUMP_ATTR 193 194 //! Change virtual variable group to new one 195 void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup) 196 TRY 197 { 198 this->vAxisGroup_ = newVAxisGroup; 199 } 200 CATCH_DUMP_ATTR 201 202 //! Change virtual variable group to new one 203 void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup) 204 TRY 205 { 206 this->vScalarGroup_ = newVScalarGroup; 207 } 208 CATCH_DUMP_ATTR 209 210 //---------------------------------------------------------------- 211 212 CDomainGroup* CGrid::getVirtualDomainGroup() const 213 TRY 214 { 215 return this->vDomainGroup_; 216 } 217 CATCH 218 219 CAxisGroup* CGrid::getVirtualAxisGroup() const 220 TRY 221 { 222 return this->vAxisGroup_; 223 } 224 CATCH 225 226 CScalarGroup* CGrid::getVirtualScalarGroup() const 227 TRY 228 { 229 return this->vScalarGroup_; 230 } 231 CATCH 232 233 ///--------------------------------------------------------------- 234 235 CDomain* CGrid::addDomain(const std::string& id) 236 TRY 237 { 238 order_.push_back(2); 239 axis_domain_order.resize(order_.size()); 240 for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 241 CDomain* domain = vDomainGroup_->createChild(id); 242 isDomListSet=false ; 243 computeElements(); 244 return domain ; 245 } 246 CATCH_DUMP_ATTR 247 248 CAxis* CGrid::addAxis(const std::string& id) 249 TRY 250 { 251 order_.push_back(1); 252 axis_domain_order.resize(order_.size()); 253 for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 254 CAxis* axis=vAxisGroup_->createChild(id); 255 isAxisListSet=false ; 256 computeElements(); 257 return axis ; 258 } 259 CATCH_DUMP_ATTR 260 261 CScalar* CGrid::addScalar(const std::string& id) 262 TRY 263 { 264 order_.push_back(0); 265 axis_domain_order.resize(order_.size()); 266 for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 267 CScalar* scalar = vScalarGroup_->createChild(id); 268 isScalarListSet=false ; 269 computeElements(); 270 return scalar; 271 } 272 CATCH_DUMP_ATTR 273 274 275 276 277 /*! 278 \brief Get the list of domain pointers 279 \return list of domain pointers 280 */ 281 std::vector<CDomain*> CGrid::getDomains() 282 TRY 283 { 284 setDomainList(); 285 std::vector<CDomain*> domList; 286 if (!domList_.empty()) 287 { 288 for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i])); 289 } 290 return domList; 291 } 292 CATCH_DUMP_ATTR 293 294 /*! 295 \brief Get the list of axis pointers 296 \return list of axis pointers 297 */ 298 std::vector<CAxis*> CGrid::getAxis() 299 TRY 300 { 301 setAxisList(); 302 std::vector<CAxis*> aList; 303 if (!axisList_.empty()) 304 for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i])); 305 306 return aList; 307 } 308 CATCH_DUMP_ATTR 309 310 /*! 311 \brief Get the list of axis pointers 312 \return list of axis pointers 313 */ 314 std::vector<CScalar*> CGrid::getScalars() 315 TRY 316 { 317 setScalarList() ; 318 std::vector<CScalar*> sList; 319 if (!scalarList_.empty()) 320 for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i])); 321 322 return sList; 323 } 324 CATCH_DUMP_ATTR 325 326 /*! 327 \brief Get domain pointer with index 328 \return domain pointer 329 */ 330 CDomain* CGrid::getDomain(int domainIndex) 331 TRY 332 { 333 std::vector<CDomain*> domainListP = this->getDomains(); 334 if (domainListP.empty()) 335 { 336 ERROR("CGrid::getDomain(int domainIndex)", 337 << "No domain associated to this grid. " << std::endl 338 << "Grid id = " << this->getId()); 339 } 340 341 if (domainIndex >= domainListP.size() || (domainIndex < 0)) 342 ERROR("CGrid::getDomain(int domainIndex)", 343 << "Domain with the index doesn't exist " << std::endl 344 << "Grid id = " << this->getId() << std::endl 345 << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl); 346 347 return domainListP[domainIndex]; 348 } 349 CATCH_DUMP_ATTR 350 351 /*! 352 \brief Get the axis pointer with index 353 \return axis pointer 354 */ 355 CAxis* CGrid::getAxis(int axisIndex) 356 TRY 357 { 358 std::vector<CAxis*> axisListP = this->getAxis(); 359 if (axisListP.empty()) 360 { 361 ERROR("CGrid::getDomain(int axisIndex)", 362 << "No axis associated to this grid. " << std::endl 363 << "Grid id = " << this->getId()); 364 } 365 366 if (axisIndex >= axisListP.size() || (axisIndex < 0)) 367 ERROR("CGrid::getDomain(int axisIndex)", 368 << "Domain with the index doesn't exist " << std::endl 369 << "Grid id = " << this->getId() << std::endl 370 << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl); 371 372 return axisListP[axisIndex]; 373 } 374 CATCH_DUMP_ATTR 375 376 /*! 377 \brief Get the a scalar pointer 378 \return scalar pointer 379 */ 380 CScalar* CGrid::getScalar(int scalarIndex) 381 TRY 382 { 383 std::vector<CScalar*> scalarListP = this->getScalars(); 384 if (scalarListP.empty()) 385 { 386 ERROR("CGrid::getScalar(int scalarIndex)", 387 << "No scalar associated to this grid. " << std::endl 388 << "Grid id = " << this->getId()); 389 } 390 391 if (scalarIndex >= scalarListP.size() || (scalarIndex < 0)) 392 ERROR("CGrid::getScalar(int scalarIndex)", 393 << "Scalar with the index doesn't exist " << std::endl 394 << "Grid id = " << this->getId() << std::endl 395 << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl); 396 397 return scalarListP[scalarIndex]; 398 } 399 CATCH_DUMP_ATTR 400 401 /*! 402 \brief Set domain(s) of a grid from a list 403 \param[in] domains list of domains 404 */ 405 void CGrid::setDomainList(const std::vector<CDomain*> domains) 406 TRY 407 { 408 if (isDomListSet) return; 409 std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 410 if (!domains.empty() && domList.empty()) 411 { 412 for (int i = 0; i < domains.size(); ++i) 413 this->getVirtualDomainGroup()->addChild(domains[i]); 414 domList = this->getVirtualDomainGroup()->getAllChildren(); 415 } 416 417 if (!domList.empty()) 418 { 419 int sizeDom = domList.size(); 420 domList_.resize(sizeDom); 421 for (int i = 0; i < sizeDom; ++i) 422 { 423 domList_[i] = domList[i]->getId(); 424 } 425 isDomListSet = true; 426 } 427 } 428 CATCH_DUMP_ATTR 429 430 /*! 431 \brief Set axis(s) of a grid from a list 432 \param[in] axis list of axis 433 */ 434 void CGrid::setAxisList(const std::vector<CAxis*> axis) 435 TRY 436 { 437 if (isAxisListSet) return; 438 std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 439 if (!axis.empty() && aList.empty()) 440 { 441 for (int i = 0; i < axis.size(); ++i) 442 this->getVirtualAxisGroup()->addChild(axis[i]); 443 aList = this->getVirtualAxisGroup()->getAllChildren(); 444 } 445 446 if (!aList.empty()) 447 { 448 int sizeAxis = aList.size(); 449 axisList_.resize(sizeAxis); 450 for (int i = 0; i < sizeAxis; ++i) 451 { 452 axisList_[i] = aList[i]->getId(); 453 } 454 isAxisListSet = true; 455 } 456 } 457 CATCH_DUMP_ATTR 458 459 /*! 460 \brief Set scalar(s) of a grid from a list 461 \param[in] scalars list of scalars 462 */ 463 void CGrid::setScalarList(const std::vector<CScalar*> scalars) 464 TRY 465 { 466 if (isScalarListSet) return; 467 std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 468 if (!scalars.empty() && sList.empty()) 469 { 470 for (int i = 0; i < scalars.size(); ++i) 471 this->getVirtualScalarGroup()->addChild(scalars[i]); 472 sList = this->getVirtualScalarGroup()->getAllChildren(); 473 } 474 475 if (!sList.empty()) 476 { 477 int sizeScalar = sList.size(); 478 scalarList_.resize(sizeScalar); 479 for (int i = 0; i < sizeScalar; ++i) 480 { 481 scalarList_[i] = sList[i]->getId(); 482 } 483 isScalarListSet = true; 484 } 485 } 486 CATCH_DUMP_ATTR 487 488 /*! 489 \brief Get list of id of domains 490 \return id list of domains 491 */ 492 std::vector<StdString> CGrid::getDomainList() 493 TRY 494 { 495 setDomainList(); 496 return domList_; 497 } 498 CATCH 499 500 /*! 501 \brief Get list of id of axis 502 \return id list of axis 503 */ 504 std::vector<StdString> CGrid::getAxisList() 505 TRY 506 { 507 setAxisList(); 508 return axisList_; 509 } 510 CATCH 511 512 /*! 513 \brief Get list of id of scalar 514 \return id list of scalar 515 */ 516 std::vector<StdString> CGrid::getScalarList() 517 TRY 518 { 519 setScalarList(); 520 return scalarList_; 521 } 522 CATCH 523 524 525 void CGrid::computeElements(void) 526 { 527 const auto& domains = getDomains() ; 528 const auto& axis = getAxis() ; 529 const auto& scalars = getScalars() ; 530 int idxDomain = 0, idxAxis=0 , idxScalar=0 ; 531 532 elements_.clear() ; 533 for(auto type : order_) 534 { 535 if (type == 0) { elements_.push_back({scalars[idxScalar], TYPE_SCALAR, scalars[idxScalar], nullptr, nullptr } ) ; idxScalar++;} 536 else if (type == 1) { elements_.push_back({axis[idxAxis], TYPE_AXIS, nullptr, axis[idxAxis], nullptr}) ; idxAxis++;} 537 else if (type == 2) { elements_.push_back({domains[idxDomain], TYPE_DOMAIN, nullptr, nullptr, domains[idxDomain] }) ; idxDomain++;} 538 } 539 elementsComputed_ = true ; 540 } 541 542 543 /*! 544 Parse a grid, for now, it contains only domain, axis and scalar 545 */ 546 void CGrid::parse(xml::CXMLNode& node) 547 TRY 548 { 549 SuperClass::parse(node); 550 551 if (node.goToChildElement()) 552 { 553 StdString domainName("domain"); 554 StdString axisName("axis"); 555 StdString scalarName("scalar"); 556 do 557 { 558 if (node.getElementName() == domainName) { 559 order_.push_back(2); 560 this->getVirtualDomainGroup()->parseChild(node); 561 } 562 if (node.getElementName() == axisName) { 563 order_.push_back(1); 564 this->getVirtualAxisGroup()->parseChild(node); 565 } 566 if (node.getElementName() == scalarName) { 567 order_.push_back(0); 568 this->getVirtualScalarGroup()->parseChild(node); 569 } 570 } while (node.goToNextElement()); 571 node.goToParentElement(); 572 } 573 574 if (!order_.empty()) 575 { 576 int sizeOrd = order_.size(); 577 axis_domain_order.resize(sizeOrd); 578 for (int i = 0; i < sizeOrd; ++i) 579 { 580 axis_domain_order(i) = order_[i]; 581 } 582 } 583 584 setDomainList(); 585 setAxisList(); 586 setScalarList(); 587 computeElements() ; 588 } 589 CATCH_DUMP_ATTR 590 591 592 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 593 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 594 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 595 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 596 597 598 83 599 StdSize CGrid::getDimension(void) 84 600 TRY … … 90 606 //--------------------------------------------------------------- 91 607 92 StdSize CGrid::getDataSize(void) const608 StdSize CGrid::getDataSize(void) 93 609 TRY 94 610 { … … 96 612 if (!isScalarGrid()) 97 613 { 98 std::vector<int> dataNindex = clientDistribution_->getDataNIndex();614 std::vector<int> dataNindex = getClientDistribution()->getDataNIndex(); 99 615 for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i]; 100 616 } … … 102 618 } 103 619 CATCH 620 621 /*! 622 * Get the local data grid size, ie the size of the compressed grid (inside the workflow) 623 * \return The size od the compressed grid 624 */ 625 StdSize CGrid::getLocalDataSize(void) { return getClientDistribution()->getLocalDataSize();} 626 104 627 105 628 /*! … … 128 651 for (size_t i = 0; i < axisList.size(); ++i) 129 652 { 130 std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(), axisPositionInGrid_[i]);653 std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),getAxisPositionInGrid()[i]); 131 654 for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it) 132 655 { … … 202 725 CATCH_DUMP_ATTR 203 726 204 void CGrid::checkAttributesAfterTransformation() 205 TRY 206 { 207 setAxisList(); 208 std::vector<CAxis*> axisListP = this->getAxis(); 209 if (!axisListP.empty()) 210 { 211 int idx = 0; 212 axisPositionInGrid_.resize(0); 213 for (int i = 0; i < axis_domain_order.numElements(); ++i) 214 { 215 int elementDimension = axis_domain_order(i); 216 if (1 == elementDimension) 217 { 218 axisPositionInGrid_.push_back(idx); 219 ++idx; 220 } 221 else if (2 == elementDimension) idx += 2; 222 } 223 224 for (int i = 0; i < axisListP.size(); ++i) 225 { 226 axisListP[i]->checkAttributesOnClientAfterTransformation(getGlobalDimension(),axisPositionInGrid_[i]); 227 } 228 } 229 230 setDomainList(); 231 std::vector<CDomain*> domListP = this->getDomains(); 232 if (!domListP.empty()) 233 { 234 for (int i = 0; i < domListP.size(); ++i) 235 { 236 domListP[i]->checkAttributesOnClientAfterTransformation(); 237 } 238 } 239 } 240 CATCH_DUMP_ATTR 241 242 //--------------------------------------------------------------- 243 727 728 void CGrid::computeAxisPositionInGrid(void) 729 { 730 axisPositionInGrid_.resize(0); 731 int idx = 0; 732 for (int i = 0; i < axis_domain_order.numElements(); ++i) 733 { 734 int elementDimension = axis_domain_order(i); 735 if (1 == elementDimension) 736 { 737 axisPositionInGrid_.push_back(idx); 738 ++idx; 739 } 740 else if (2 == elementDimension) idx += 2; 741 } 742 } 743 744 244 745 /*! 245 746 * Test whether the data defined on the grid can be outputted in a compressed way. … … 327 828 CATCH_DUMP_ATTR 328 829 830 //ym obsolete -> to be removed later 329 831 void CGrid::checkMaskIndex(bool doSendingIndex) 330 832 TRY 331 833 { 332 834 CContext* context = CContext::getCurrent(); 333 int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; 334 nbSrvPools = 1; 335 for (int p = 0; p < nbSrvPools; ++p) 336 { 337 if (context->hasClient && this->isChecked && doSendingIndex && !isIndexSent) 338 { 339 if (isScalarGrid()) 340 sendIndexScalarGrid(); 341 else 342 sendIndex(); 343 this->isIndexSent = true; 344 } 345 346 // Not sure about this 347 //if (!(this->hasTransform() && !this->isTransformed())) 348 // this->isChecked = true; 349 //return; 350 } 351 835 352 836 if (this->isChecked) return; 353 this->checkAttributesAfterTransformation(); 354 355 // TODO: Transfer grid attributes 356 //if (!context->hasClient && context->hasServer) this->createMask(); 357 this->computeIndex(); 358 359 if (!(this->hasTransform() && !this->isTransformed())) 360 this->isChecked = true; 361 362 if (!(this->hasTransform() && (!this->isGenerated()))) 363 this->isChecked = true; 364 } 365 CATCH_DUMP_ATTR 837 this->checkElementsAttributes(); 838 this->isChecked = true; 839 } 840 CATCH_DUMP_ATTR 841 842 366 843 bool CGrid::hasMask() const 367 844 TRY … … 372 849 CATCH 373 850 374 /* 375 Create mask of grid from mask of its components 376 */ 377 void CGrid::createMask(void) 378 TRY 379 { 380 using namespace std; 381 std::vector<CDomain*> domainP = this->getDomains(); 382 std::vector<CAxis*> axisP = this->getAxis(); 383 int dim = domainP.size() * 2 + axisP.size(); 384 385 std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 386 for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 387 std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 388 for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 389 390 switch (dim) { 391 case 1: 392 checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order, true); 393 break; 394 case 2: 395 checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order, true); 396 break; 397 case 3: 398 checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order, true); 399 break; 400 case 4: 401 checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order, true); 402 break; 403 case 5: 404 checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order, true); 405 break; 406 case 6: 407 checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order, true); 408 break; 409 case 7: 410 checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order, true); 411 break; 412 default: 413 break; 414 } 415 } 416 CATCH_DUMP_ATTR 417 418 /* 419 Check validity of grid's mask by using the masks of its components 420 */ 421 void CGrid::checkMask(void) 422 TRY 423 { 424 using namespace std; 425 std::vector<CDomain*> domainP = this->getDomains(); 426 std::vector<CAxis*> axisP = this->getAxis(); 427 int dim = domainP.size() * 2 + axisP.size(); 428 429 std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 430 for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 431 std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 432 for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 433 434 switch (dim) { 435 case 1: 436 checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order); 437 break; 438 case 2: 439 checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order); 440 break; 441 case 3: 442 checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order); 443 break; 444 case 4: 445 checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order); 446 break; 447 case 5: 448 checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order); 449 break; 450 case 6: 451 checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order); 452 break; 453 case 7: 454 checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order); 455 break; 456 default: 457 break; 458 } 459 } 460 CATCH_DUMP_ATTR 461 462 /* 463 Modify value of mask in a certain index 464 This function can be used to correct the mask of grid after being constructed with createMask 465 \param [in] indexToModify 466 \param [in] modifyValue 467 */ 468 void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue) 469 TRY 470 { 471 using namespace std; 472 std::vector<CDomain*> domainP = this->getDomains(); 473 std::vector<CAxis*> axisP = this->getAxis(); 474 int dim = domainP.size() * 2 + axisP.size(); 475 476 switch (dim) { 477 case 0: 478 modifyGridMask(mask_0d, indexToModify, modifyValue); 479 break; 480 case 1: 481 modifyGridMask(mask_1d, indexToModify, modifyValue); 482 break; 483 case 2: 484 modifyGridMask(mask_2d, indexToModify, modifyValue); 485 break; 486 case 3: 487 modifyGridMask(mask_3d, indexToModify, modifyValue); 488 break; 489 case 4: 490 modifyGridMask(mask_4d, indexToModify, modifyValue); 491 break; 492 case 5: 493 modifyGridMask(mask_5d, indexToModify, modifyValue); 494 break; 495 case 6: 496 modifyGridMask(mask_6d, indexToModify, modifyValue); 497 break; 498 case 7: 499 modifyGridMask(mask_7d, indexToModify, modifyValue); 500 break; 501 default: 502 break; 503 } 504 } 505 CATCH_DUMP_ATTR 506 507 /* 508 Change the mask size. This function is used on reconstructing mask in server side 509 \param [in] newDimensionSize 510 \param [in] newValue 511 */ 512 void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue) 513 TRY 514 { 515 std::vector<CDomain*> domainP = this->getDomains(); 516 std::vector<CAxis*> axisP = this->getAxis(); 517 int dim = domainP.size() * 2 + axisP.size(); 518 519 switch (dim) { 520 case 0: 521 modifyGridMaskSize(mask_0d, newDimensionSize, newValue); 522 break; 523 case 1: 524 modifyGridMaskSize(mask_1d, newDimensionSize, newValue); 525 break; 526 case 2: 527 modifyGridMaskSize(mask_2d, newDimensionSize, newValue); 528 break; 529 case 3: 530 modifyGridMaskSize(mask_3d, newDimensionSize, newValue); 531 break; 532 case 4: 533 modifyGridMaskSize(mask_4d, newDimensionSize, newValue); 534 break; 535 case 5: 536 modifyGridMaskSize(mask_5d, newDimensionSize, newValue); 537 break; 538 case 6: 539 modifyGridMaskSize(mask_6d, newDimensionSize, newValue); 540 break; 541 case 7: 542 modifyGridMaskSize(mask_7d, newDimensionSize, newValue); 543 break; 544 default: 545 break; 546 } 547 } 548 CATCH_DUMP_ATTR 549 851 852 CArray<bool,1>& CGrid::getMask(void) 853 { 854 855 if (mask_.isEmpty()) 856 { 857 if (!mask_0d.isEmpty()) mask_.reference(CArray<bool,1>(mask_0d.dataFirst(),shape(mask_0d.numElements()), neverDeleteData)) ; 858 if (!mask_1d.isEmpty()) mask_.reference(CArray<bool,1>(mask_1d.dataFirst(),shape(mask_1d.numElements()), neverDeleteData)) ; 859 if (!mask_2d.isEmpty()) mask_.reference(CArray<bool,1>(mask_2d.dataFirst(),shape(mask_2d.numElements()), neverDeleteData)) ; 860 if (!mask_3d.isEmpty()) mask_.reference(CArray<bool,1>(mask_3d.dataFirst(),shape(mask_3d.numElements()), neverDeleteData)) ; 861 if (!mask_4d.isEmpty()) mask_.reference(CArray<bool,1>(mask_4d.dataFirst(),shape(mask_4d.numElements()), neverDeleteData)) ; 862 if (!mask_5d.isEmpty()) mask_.reference(CArray<bool,1>(mask_5d.dataFirst(),shape(mask_5d.numElements()), neverDeleteData)) ; 863 if (!mask_6d.isEmpty()) mask_.reference(CArray<bool,1>(mask_6d.dataFirst(),shape(mask_6d.numElements()), neverDeleteData)) ; 864 if (!mask_7d.isEmpty()) mask_.reference(CArray<bool,1>(mask_7d.dataFirst(),shape(mask_7d.numElements()), neverDeleteData)) ; 865 } 866 return mask_ ; 867 } 868 869 550 870 //--------------------------------------------------------------- 551 871 … … 556 876 std::vector<CDomain*> domListP = this->getDomains(); 557 877 if (!domListP.empty()) 558 { 559 for (int i = 0; i < domListP.size(); ++i) 560 { 561 if (sendAtt) domListP[i]->sendCheckedAttributes(); 562 else domListP[i]->checkAttributesOnClient(); 563 } 564 } 878 for (int i = 0; i < domListP.size(); ++i) domListP[i]->checkAttributes(); 565 879 } 566 880 CATCH_DUMP_ATTR … … 574 888 std::vector<CAxis*> axisListP = this->getAxis(); 575 889 if (!axisListP.empty()) 576 { 577 int idx = 0; 578 axisPositionInGrid_.resize(0); 579 for (int i = 0; i < axis_domain_order.numElements(); ++i) 580 { 581 int elementDimension = axis_domain_order(i); 582 if (1 == elementDimension) 583 { 584 axisPositionInGrid_.push_back(idx); 585 ++idx; 586 } 587 else if (2 == elementDimension) idx += 2; 588 } 589 590 for (int i = 0; i < axisListP.size(); ++i) 591 { 592 if (sendAtt) 593 axisListP[i]->sendCheckedAttributes(getGlobalDimension(),axisPositionInGrid_[i]); 594 else 595 axisListP[i]->checkAttributesOnClient(); 596 } 597 } 890 for (int i = 0; i < axisListP.size(); ++i) axisListP[i]->checkAttributes(); 598 891 } 599 892 CATCH_DUMP_ATTR … … 607 900 std::vector<CScalar*> scalarListP = this->getScalars(); 608 901 if (!scalarListP.empty()) 609 { 610 for (int i = 0; i < scalarListP.size(); ++i) 611 { 612 /*Nothing to do for now */ 613 // if (sendAtt) scalarListP[i]->sendCheckedAttributes(); 614 // else scalarListP[i]->checkAttributesOnClient(); 615 } 616 } 617 } 618 CATCH_DUMP_ATTR 619 620 /*! 621 Compute the index to for write data into a file 622 */ 623 void CGrid::computeWrittenIndex() 624 TRY 625 { 626 if (computedWrittenIndex_) return; 627 computedWrittenIndex_ = true; 628 629 if (isScalarGrid()) 630 { 631 size_t nbWritten = 1; 632 int writtenIndex = 0; 633 634 localIndexToWriteOnClient.resize(nbWritten); 635 localIndexToWriteOnServer.resize(nbWritten); 636 localIndexToWriteOnServer(0) = writtenIndex; 637 localIndexToWriteOnClient(0) = writtenIndex; 638 639 return; 640 } 641 642 size_t nbWritten = 0, indGlo; 643 CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 644 CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(), 645 ite = globalDataIndex.end(), it; 646 const CDistributionServer::GlobalLocalMap& globalLocalIndex = serverDistribution_->getGlobalLocalIndex(); 647 CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(), 648 itSrve = globalLocalIndex.end(), itSrv; 649 for (it = itb; it != ite; ++it) 650 { 651 indGlo = it->first; 652 if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten; 653 } 654 655 localIndexToWriteOnClient.resize(nbWritten); 656 localIndexToWriteOnServer.resize(nbWritten); 657 658 { 659 numberWrittenIndexes_ = nbWritten; 660 if (isDataDistributed_) 661 { 662 CContextServer* server = CContext::getCurrent()->server; 663 MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 664 MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 665 offsetWrittenIndexes_ -= numberWrittenIndexes_; 666 } 667 else 668 totalNumberWrittenIndexes_ = numberWrittenIndexes_; 669 } 670 671 nbWritten = 0; 672 for (it = itb; it != ite; ++it) 673 { 674 indGlo = it->first; 675 itSrv = globalLocalIndex.find(indGlo); 676 if (itSrve != itSrv) 677 { 678 localIndexToWriteOnServer(nbWritten) = itSrv->second; 679 localIndexToWriteOnClient(nbWritten) = it->second; 680 ++nbWritten; 681 } 682 } 683 } 684 CATCH_DUMP_ATTR 685 686 //--------------------------------------------------------------- 687 688 /* 689 Compute the global index and its local index taking account mask and data index. 690 These global indexes will be used to compute the connection of this client (sender) to its servers (receivers) 691 (via function computeConnectedClient) 692 These global indexes also correspond to data sent to servers (if any) 693 */ 694 void CGrid::computeClientIndex() 695 TRY 696 { 902 for (int i = 0; i < scalarListP.size(); ++i) scalarListP[i]->checkAttributes() ; 903 } 904 CATCH_DUMP_ATTR 905 906 907 //--------------------------------------------------------------- 908 CDistributionClient* CGrid::getClientDistribution() 909 TRY 910 { 911 if (!computeClientDistribution_done_) computeClientDistribution() ; 912 return clientDistribution_; 913 } 914 CATCH_DUMP_ATTR 915 916 void CGrid::computeClientDistribution(void) 917 { 918 if (computeClientDistribution_done_) return ; 919 else computeClientDistribution_done_ = true ; 920 697 921 CContext* context = CContext::getCurrent(); 698 699 CContextClient* client = context->client; 700 int rank = client->clientRank; 701 922 int rank = context-> getIntraCommRank(); 702 923 clientDistribution_ = new CDistributionClient(rank, this); 703 // Get local data index on client 704 int nbStoreIndex = clientDistribution_->getLocalDataIndexOnClient().size(); 705 int nbStoreGridMask = clientDistribution_->getLocalMaskIndexOnClient().size(); 706 // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise 707 storeIndex_client.resize(nbStoreIndex); 708 storeMask_client.resize(nbStoreGridMask); 709 for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 710 for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMask_client(idx) = (clientDistribution_->getLocalMaskIndexOnClient())[idx]; 711 712 if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); 713 else 714 { 715 // Mapping global index received from clients to the storeIndex_client 716 CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 717 CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 718 map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 719 ite = outGlobalIndexFromClient.end(), it; 720 721 for (it = itb; it != ite; ++it) 722 { 723 int rank = it->first; 724 CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 725 outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 726 CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 727 size_t nbIndex = 0; 728 729 // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 730 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 731 { 732 if (itGloe != globalDataIndex.find(globalIndex(idx))) 733 { 734 ++nbIndex; 735 } 736 } 737 738 if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 739 ERROR("void CGrid::computeClientIndex()", 740 << "Number of local index on client is different from number of received global index" 741 << "Rank of sent client " << rank <<"." 742 << "Number of local index " << nbIndex << ". " 743 << "Number of received global index " << localIndex.numElements() << "."); 744 745 nbIndex = 0; 746 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 747 { 748 if (itGloe != globalDataIndex.find(globalIndex(idx))) 749 { 750 localIndex(idx) = globalDataIndex[globalIndex(idx)]; 751 } 752 } 753 } 754 } 755 } 756 CATCH_DUMP_ATTR 757 758 /*! 759 Compute connected receivers and indexes to be sent to these receivers. 760 */ 761 void CGrid::computeConnectedClients() 762 TRY 763 { 764 CContext* context = CContext::getCurrent(); 765 int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size(); 766 connectedServerRank_.clear(); 767 connectedDataSize_.clear(); 768 globalIndexOnServer_.clear(); 769 nbSenders.clear(); 770 771 for (int p = 0; p < nbSrvPools; ++p) 772 { 773 CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p]; 774 int receiverSize = client->serverSize; 775 // connectedServerRank_[client].clear(); 776 777 if (connectedServerRank_.find(receiverSize) == connectedServerRank_.end()) 778 { 779 if (!doGridHaveDataDistributed(client)) 780 { 781 if (client->isServerLeader()) 782 { 783 size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 784 const std::list<int>& ranks = client->getRanksServerLeader(); 785 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 786 { 787 connectedServerRank_[receiverSize].push_back(*itRank); 788 connectedDataSize_[receiverSize][*itRank] = ssize; 789 } 790 } 791 return; 792 } 793 794 // Compute mapping between client and server 795 std::vector<std::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 796 CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 797 std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 798 client->clientRank, 799 client->clientSize, 800 axis_domain_order, 801 getDistributedDimension()); 802 803 // Even if servers have no index, they must received something from client 804 // We only use several client to send "empty" message to these servers 805 std::list<int> serverZeroIndexLeader; 806 std::list<int> serverZeroIndexNotLeader; 807 CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 808 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 809 *it = serverZeroIndex[*it]; 810 811 if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end()) 812 computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]); 813 814 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 815 CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 816 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 817 itbGlobalMap = globalIndexOnServer_[receiverSize].begin(); 818 iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 819 820 for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 821 { 822 int serverRank = itGlobalMap->first; 823 int indexSize = itGlobalMap->second.size(); 824 const std::vector<size_t>& indexVec = itGlobalMap->second; 825 for (int idx = 0; idx < indexSize; ++idx) 826 { 827 itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 828 if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 829 { 830 if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank)) 831 connectedDataSize_[receiverSize][serverRank] = 1; 832 else 833 ++connectedDataSize_[receiverSize][serverRank]; 834 } 835 } 836 } 837 838 // Connected servers which really have index 839 for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 840 connectedServerRank_[receiverSize].push_back(itGlobalMap->first); 841 } 842 843 // Connected servers which have no index at all 844 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 845 connectedServerRank_[receiverSize].push_back(*it); 846 847 // Even if a client has no index, it must connect to at least one server and 848 // send an "empty" data to this server 849 if (connectedServerRank_[receiverSize].empty()) 850 connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 851 852 // Now check if all servers have data to receive. If not, master client will send empty data. 853 // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 854 std::vector<int> counts (client->clientSize); 855 std::vector<int> displs (client->clientSize); 856 displs[0] = 0; 857 int localCount = connectedServerRank_[receiverSize].size() ; 858 MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 859 for (int i = 0; i < client->clientSize-1; ++i) 860 { 861 displs[i+1] = displs[i] + counts[i]; 862 } 863 std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]); 864 MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 865 866 if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0)) 867 { 868 std::vector<bool> isSrvConnected (receiverSize, false); 869 for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 870 for (int i = 0; i < receiverSize; ++i) 871 { 872 if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i); 873 } 874 } 875 876 nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 877 } 878 } 879 } 880 CATCH_DUMP_ATTR 881 882 /*! 883 Compute the global index of grid to send to server as well as the connected server of the current client. 884 First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know 885 their global index. We can have a map of global index of grid and local index that each client holds 886 Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s) 887 of the current client. 888 */ 889 void CGrid::computeIndex(void) 890 TRY 891 { 892 CContext* context = CContext::getCurrent(); 893 if (isScalarGrid()) 894 { 895 computeClientIndexScalarGrid(); 896 if (context->hasClient) 897 { 898 computeConnectedClientsScalarGrid(); 899 } 900 } 901 else 902 { 903 computeClientIndex(); 904 if (context->hasClient) 905 { 906 computeConnectedClients(); 907 } 908 } 909 if (CServer::serverLevel==2) 910 { 911 computeWrittenIndex() ; 912 if (serverDistribution_!=0) serverDistribution_->partialClear() ; 913 if (clientDistribution_!=0) clientDistribution_->partialClear() ; 914 outGlobalIndexFromClient.clear() ; 915 } 916 } 917 CATCH_DUMP_ATTR 918 919 /*! 920 Compute the global of (client) grid to send to server with the global index of each element of grid 921 Each element of grid has its own global index associated to a groups of server. We only search for the global index of each element whose 922 server is the same, then calculate the global index of grid. This way can reduce so much the time for executing DHT, which only needs to run 923 on each element whose size is much smaller than one of whole grid. 924 \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 925 \param [in] client contextClient 926 \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 927 */ 928 void CGrid::computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 929 const CContextClient* client, 930 CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 931 TRY 932 { 933 int serverSize = client->serverSize; 934 935 std::vector<CDomain*> domList = getDomains(); 936 std::vector<CAxis*> axisList = getAxis(); 937 938 // Some pre-calculations of global index on each element of current grid. 939 int nbElement = axis_domain_order.numElements(); 940 std::vector<CArray<size_t,1> > globalIndexElement(nbElement); 941 int domainIdx = 0, axisIdx = 0, scalarIdx = 0; 942 std::vector<size_t> elementNGlobal(nbElement); 943 elementNGlobal[0] = 1; 944 size_t globalSize = 1; 945 for (int idx = 0; idx < nbElement; ++idx) 946 { 947 elementNGlobal[idx] = globalSize; 948 size_t elementSize; 949 size_t elementGlobalSize = 1; 950 if (2 == axis_domain_order(idx)) // This is domain 951 { 952 elementSize = domList[domainIdx]->i_index.numElements(); 953 globalIndexElement[idx].resize(elementSize); 954 for (int jdx = 0; jdx < elementSize; ++jdx) 955 { 956 globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx); 957 } 958 elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue(); 959 ++domainIdx; 960 } 961 else if (1 == axis_domain_order(idx)) // This is axis 962 { 963 elementSize = axisList[axisIdx]->index.numElements(); 964 globalIndexElement[idx].resize(elementSize); 965 for (int jdx = 0; jdx < elementSize; ++jdx) 966 { 967 globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx); 968 } 969 elementGlobalSize = axisList[axisIdx]->n_glo.getValue(); 970 ++axisIdx; 971 } 972 else // Of course, this is scalar 973 { 974 globalIndexElement[idx].resize(1); 975 globalIndexElement[idx](0) = 0; 976 elementGlobalSize = 1; 977 } 978 globalSize *= elementGlobalSize; 979 } 980 981 std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false)); 982 std::vector<std::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement); 983 CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server 984 // Number of temporary distributed global index held by each client for each server 985 // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank 986 CArray<int,1> nbIndexOnServerTmp(serverSize); 987 for (int idx = 0; idx < nbElement; ++idx) 988 { 989 nbIndexOnServer = 0; 990 const std::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx]; 991 const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx]; 992 CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm); 993 clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient); 994 const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap(); 995 CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(), 996 ite = globalIndexElementOnServerMap.end(), it; 997 for (it = itb; it != ite; ++it) 998 { 999 const std::vector<int>& tmp = it->second; 1000 nbIndexOnServerTmp = 0; 1001 for (int i = 0; i < tmp.size(); ++i) 1002 { 1003 if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]); 1004 } 1005 nbIndexOnServer += nbIndexOnServerTmp; 1006 } 1007 1008 for (int i = 0; i < serverSize; ++i) 1009 { 1010 if (0 != nbIndexOnServer(i)) 1011 { 1012 globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i)); 1013 elementOnServer[idx][i] = true; 1014 } 1015 } 1016 1017 nbIndexOnServer = 0; 1018 for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 1019 { 1020 it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 1021 if (it != ite) 1022 { 1023 const std::vector<int>& tmp = it->second; 1024 nbIndexOnServerTmp = 0; 1025 for (int i = 0; i < tmp.size(); ++i) 1026 { 1027 if (0 == nbIndexOnServerTmp(tmp[i])) 1028 { 1029 globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first; 1030 ++nbIndexOnServerTmp(tmp[i]); 1031 } 1032 } 1033 nbIndexOnServer += nbIndexOnServerTmp; 1034 } 1035 } 1036 } 1037 1038 // Determine server which contain global source index 1039 std::vector<bool> intersectedProc(serverSize, true); 1040 for (int idx = 0; idx < nbElement; ++idx) 1041 { 1042 std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(), 1043 intersectedProc.begin(), intersectedProc.begin(), 1044 std::logical_and<bool>()); 1045 } 1046 1047 std::vector<int> srcRank; 1048 for (int idx = 0; idx < serverSize; ++idx) 1049 { 1050 if (intersectedProc[idx]) srcRank.push_back(idx); 1051 } 1052 1053 // Compute the global index of grid from global index of each element. 1054 for (int i = 0; i < srcRank.size(); ++i) 1055 { 1056 size_t ssize = 1; 1057 int rankSrc = srcRank[i]; 1058 std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement); 1059 std::vector<size_t> currentIndex(nbElement,0); 1060 for (int idx = 0; idx < nbElement; ++idx) 1061 { 1062 ssize *= (globalElementIndexOnServer[idx][rankSrc]).size(); 1063 globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]); 1064 } 1065 globalIndexOnServer[rankSrc].resize(ssize); 1066 1067 std::vector<int> idxLoop(nbElement,0); 1068 int innnerLoopSize = (globalIndexOfElementTmp[0])->size(); 1069 size_t idx = 0; 1070 while (idx < ssize) 1071 { 1072 for (int ind = 0; ind < nbElement; ++ind) 1073 { 1074 if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size()) 1075 { 1076 idxLoop[ind] = 0; 1077 ++idxLoop[ind+1]; 1078 } 1079 1080 currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]]; 1081 } 1082 1083 for (int ind = 0; ind < innnerLoopSize; ++ind) 1084 { 1085 currentIndex[0] = (*globalIndexOfElementTmp[0])[ind]; 1086 size_t globalSrcIndex = 0; 1087 for (int idxElement = 0; idxElement < nbElement; ++idxElement) 1088 { 1089 globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement]; 1090 } 1091 globalIndexOnServer[rankSrc][idx] = globalSrcIndex; 1092 ++idx; 1093 ++idxLoop[0]; 1094 } 1095 } 1096 } 1097 } 1098 CATCH_DUMP_ATTR 1099 //---------------------------------------------------------------- 1100 1101 CGrid* CGrid::createGrid(CDomain* domain) 1102 TRY 1103 { 1104 std::vector<CDomain*> vecDom(1, domain); 1105 std::vector<CAxis*> vecAxis; 1106 1107 return createGrid(vecDom, vecAxis); 1108 } 1109 CATCH 1110 1111 CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis) 1112 TRY 1113 { 1114 std::vector<CDomain*> vecDom(1, domain); 1115 std::vector<CAxis*> vecAxis(1, axis); 1116 1117 return createGrid(vecDom, vecAxis); 1118 } 1119 CATCH 1120 1121 CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 1122 const CArray<int,1>& axisDomainOrder) 1123 TRY 1124 { 1125 std::vector<CScalar*> vecScalar; 1126 return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder); 1127 } 1128 CATCH 1129 1130 CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 1131 const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 1132 TRY 1133 { 1134 return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder); 1135 } 1136 CATCH 1137 1138 CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 1139 const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 1140 TRY 1141 { 1142 if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size())) 1143 ERROR("CGrid* CGrid::createGrid(...)", 1144 << "The size of axisDomainOrder (" << axisDomainOrder.numElements() 1145 << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<")."); 1146 1147 CGrid* grid = CGridGroup::get("grid_definition")->createChild(id); 1148 grid->setDomainList(domains); 1149 grid->setAxisList(axis); 1150 grid->setScalarList(scalars); 1151 1152 // By default, domains are always the first elements of a grid 1153 if (0 == axisDomainOrder.numElements()) 1154 { 1155 int size = domains.size() + axis.size() + scalars.size(); 1156 int nb = 0; 1157 grid->axis_domain_order.resize(size); 1158 for (int i = 0; i < size; ++i) 1159 { 1160 if (i < domains.size()) { 1161 grid->axis_domain_order(i) = 2; 1162 1163 } 1164 else if ((scalars.size() < (size-nb)) < size) { 1165 grid->axis_domain_order(i) = 1; 1166 } 1167 else 1168 grid->axis_domain_order(i) = 0; 1169 ++nb; 1170 } 1171 } 1172 else 1173 { 1174 grid->axis_domain_order.resize(axisDomainOrder.numElements()); 1175 grid->axis_domain_order = axisDomainOrder; 1176 } 1177 1178 grid->solveDomainAxisRefInheritance(true); 1179 1180 return grid; 1181 } 1182 CATCH 924 } 925 926 927 bool CGrid::isDataDistributed(void) 928 { 929 return getClientDistribution()->isDataDistributed() ; 930 } 931 932 1183 933 1184 934 CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc) … … 1283 1033 CATCH 1284 1034 1035 1285 1036 //---------------------------------------------------------------- 1286 1037 1287 CDomainGroup* CGrid::getVirtualDomainGroup() const 1288 TRY 1289 { 1290 return this->vDomainGroup_; 1291 } 1292 CATCH 1293 1294 CAxisGroup* CGrid::getVirtualAxisGroup() const 1295 TRY 1296 { 1297 return this->vAxisGroup_; 1298 } 1299 CATCH 1300 1301 CScalarGroup* CGrid::getVirtualScalarGroup() const 1302 TRY 1303 { 1304 return this->vScalarGroup_; 1305 } 1306 CATCH 1307 1308 /* 1309 void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field) 1310 { 1311 const CArray<size_t,1>& out_i = outIndexFromClient[rank]; 1312 StdSize numElements = stored.numElements(); 1313 for (StdSize n = 0; n < numElements; ++n) 1314 { 1315 field[out_i(n)] = stored(n); 1316 } 1317 } 1318 1319 void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored) 1320 { 1321 const CArray<size_t,1>& out_i = outIndexFromClient[rank]; 1322 StdSize numElements = stored.numElements(); 1323 for (StdSize n = 0; n < numElements; ++n) 1324 { 1325 stored(n) = field[out_i(n)]; 1326 } 1327 } 1328 1329 void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field) 1330 { 1331 const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank]; 1332 StdSize numElements = stored.numElements(); 1333 for (StdSize n = 0; n < numElements; ++n) 1334 { 1335 field[out_i(n)] = stored(n); 1336 } 1337 } 1338 */ 1339 //---------------------------------------------------------------- 1340 1341 void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const 1342 TRY 1343 { 1344 const StdSize size = storeIndex_client.numElements(); 1345 1346 stored.resize(size); 1347 for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 1348 } 1349 CATCH 1350 1351 void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const 1352 TRY 1353 { 1354 const StdSize size = storeIndex_client.numElements(); 1355 1356 for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i); 1357 } 1358 CATCH 1359 1360 void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const 1361 { 1362 const StdSize size = storeIndex_client.numElements(); 1363 stored.resize(size); 1364 const double nanValue = std::numeric_limits<double>::quiet_NaN(); 1365 1366 if (storeMask_client.numElements() != 0) 1367 for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue; 1368 else 1369 for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 1370 } 1371 1372 void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 1373 TRY 1374 { 1375 const std::vector<int>& localMaskedDataIndex = clientDistribution_->getLocalMaskedDataIndexOnClient(); 1376 const int size = localMaskedDataIndex.size(); 1377 for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i]; 1378 } 1379 CATCH 1380 1381 void CGrid::computeClientIndexScalarGrid() 1382 TRY 1383 { 1384 CContext* context = CContext::getCurrent(); 1385 { 1386 CContextClient* client = context->client; 1387 1388 int rank = client->clientRank; 1389 1390 clientDistribution_ = new CDistributionClient(rank, this); 1391 1392 storeIndex_client.resize(1); 1393 storeIndex_client(0) = 0; 1394 1395 if (0 != serverDistribution_) 1396 { 1397 map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 1398 ite = outGlobalIndexFromClient.end(), it; 1399 for (it = itb; it != ite; ++it) 1400 { 1401 int rank = it->first; 1402 CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 1403 outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 1404 CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 1405 if (1 != globalIndex.numElements()) 1406 ERROR("void CGrid::computeClientIndexScalarGrid()", 1407 << "Something wrong happened. " 1408 << "Number of received global index on scalar grid should equal to 1" 1409 << "Number of received global index " << globalIndex.numElements() << "."); 1410 1411 localIndex(0) = globalIndex(0); 1412 } 1413 } 1414 } 1415 } 1416 CATCH_DUMP_ATTR 1417 1418 void CGrid::computeConnectedClientsScalarGrid() 1419 TRY 1420 { 1421 CContext* context = CContext::getCurrent(); 1422 int nbSrvPools = (context->clientPrimServer.size()==0) ? 1 : context->clientPrimServer.size(); 1423 connectedServerRank_.clear(); 1424 connectedDataSize_.clear(); 1425 nbSenders.clear(); 1426 1427 for (int p = 0; p < nbSrvPools; ++p) 1428 { 1429 CContextClient* client = (context->clientPrimServer.size()==0) ? context->client : context->clientPrimServer[p]; 1430 int receiverSize = client->serverSize; 1431 1432 // connectedServerRank_[client].clear(); 1433 1434 if (connectedServerRank_.find(receiverSize)==connectedServerRank_.end()) 1435 { 1436 if (client->isServerLeader()) 1437 { 1438 const std::list<int>& ranks = client->getRanksServerLeader(); 1439 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1440 { 1441 int rank = *itRank; 1442 int nb = 1; 1443 connectedServerRank_[receiverSize].push_back(rank); 1444 connectedDataSize_[receiverSize][rank] = nb; 1445 nbSenders[receiverSize][rank] = nb; 1446 } 1447 } 1448 else 1449 { 1450 const std::list<int>& ranks = client->getRanksServerNotLeader(); 1451 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1452 { 1453 int rank = *itRank; 1454 int nb = 1; 1455 connectedServerRank_[receiverSize].push_back(rank); 1456 connectedDataSize_[receiverSize][rank] = nb; 1457 nbSenders[receiverSize][rank] = nb; 1458 } 1459 } 1460 } 1461 isDataDistributed_ = false; 1462 } 1463 } 1464 CATCH_DUMP_ATTR 1465 1466 void CGrid::sendIndexScalarGrid() 1467 TRY 1468 { 1469 CContext* context = CContext::getCurrent(); 1470 storeIndex_toSrv.clear(); 1471 std::list<CContextClient*>::iterator it; 1472 1473 for (it=clients.begin(); it!=clients.end(); ++it) 1474 { 1475 CContextClient* client = *it; 1476 int receiverSize = client->serverSize; 1477 1478 CEventClient event(getType(), EVENT_ID_INDEX); 1479 list<CMessage> listMsg; 1480 list<CArray<size_t,1> > listOutIndex; 1481 1482 if (client->isServerLeader()) 1483 { 1484 const std::list<int>& ranks = client->getRanksServerLeader(); 1485 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1486 { 1487 int rank = *itRank; 1488 int nb = 1; 1489 storeIndex_toSrv[client].insert(std::make_pair(rank, CArray<int,1>(nb))); 1490 listOutIndex.push_back(CArray<size_t,1>(nb)); 1491 1492 CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 1493 CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 1494 1495 for (int k = 0; k < nb; ++k) 1496 { 1497 outGlobalIndexOnServer(k) = 0; 1498 outLocalIndexToServer(k) = 0; 1499 } 1500 1501 if (context->hasClient && !context->hasServer) 1502 storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 1503 1504 listMsg.push_back(CMessage()); 1505 listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); 1506 1507 event.push(rank, 1, listMsg.back()); 1508 } 1509 client->sendEvent(event); 1510 } 1511 else 1512 { 1513 const std::list<int>& ranks = client->getRanksServerNotLeader(); 1514 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1515 { 1516 int rank = *itRank; 1517 int nb = 1; 1518 CArray<int, 1> outLocalIndexToServer(nb); 1519 for (int k = 0; k < nb; ++k) 1520 { 1521 outLocalIndexToServer(k) = 0; 1522 } 1523 1524 if (context->hasClient && !context->hasServer) 1525 storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 1526 } 1527 client->sendEvent(event); 1528 } 1529 } 1530 } 1531 CATCH_DUMP_ATTR 1532 1533 void CGrid::sendIndex(void) 1534 TRY 1535 { 1536 CContext* context = CContext::getCurrent(); 1537 storeIndex_toSrv.clear(); 1538 std::list<CContextClient*>::iterator it; 1539 1540 for (it=clients.begin(); it!=clients.end(); ++it) 1541 { 1542 CContextClient* client = *it; 1543 int receiverSize = client->serverSize; 1544 1545 CEventClient event(getType(), EVENT_ID_INDEX); 1546 int rank; 1547 list<CMessage> listMsg; 1548 list<CArray<size_t,1> > listOutIndex; 1549 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 1550 CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex, 1551 iteIndex = globalLocalIndexSendToServer.end(); 1552 itIndex = itbIndex; 1553 1554 if (!doGridHaveDataDistributed(client)) 1555 { 1556 if (client->isServerLeader()) 1557 { 1558 int indexSize = globalLocalIndexSendToServer.size(); 1559 CArray<size_t,1> outGlobalIndexOnServer(indexSize); 1560 CArray<int,1> outLocalIndexToServer(indexSize); 1561 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 1562 { 1563 outGlobalIndexOnServer(idx) = itIndex->first; 1564 outLocalIndexToServer(idx) = itIndex->second; 1565 } 1566 1567 const std::list<int>& ranks = client->getRanksServerLeader(); 1568 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1569 { 1570 storeIndex_toSrv[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1571 if (context->hasClient && !context->hasServer) 1572 storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1573 1574 listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 1575 1576 listMsg.push_back(CMessage()); 1577 listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 1578 1579 event.push(*itRank, 1, listMsg.back()); 1580 } 1581 client->sendEvent(event); 1582 } 1583 else 1584 { 1585 int indexSize = globalLocalIndexSendToServer.size(); 1586 CArray<int,1> outLocalIndexToServer(indexSize); 1587 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 1588 { 1589 outLocalIndexToServer(idx) = itIndex->second; 1590 } 1591 1592 const std::list<int>& ranks = client->getRanksServerNotLeader(); 1593 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1594 { 1595 storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1596 } 1597 client->sendEvent(event); 1598 } 1599 } 1600 else 1601 { 1602 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 1603 itGlobalMap = globalIndexOnServer_[receiverSize].begin(); 1604 iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 1605 1606 std::map<int,std::vector<int> >localIndexTmp; 1607 std::map<int,std::vector<size_t> > globalIndexTmp; 1608 for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 1609 { 1610 int serverRank = itGlobalMap->first; 1611 int indexSize = itGlobalMap->second.size(); 1612 const std::vector<size_t>& indexVec = itGlobalMap->second; 1613 for (int idx = 0; idx < indexSize; ++idx) 1614 { 1615 itIndex = globalLocalIndexSendToServer.find(indexVec[idx]); 1616 if (iteIndex != itIndex) 1617 { 1618 globalIndexTmp[serverRank].push_back(itIndex->first); 1619 localIndexTmp[serverRank].push_back(itIndex->second); 1620 } 1621 } 1622 } 1623 1624 for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns) 1625 { 1626 rank = connectedServerRank_[receiverSize][ns]; 1627 int nb = 0; 1628 if (globalIndexTmp.end() != globalIndexTmp.find(rank)) 1629 nb = globalIndexTmp[rank].size(); 1630 1631 storeIndex_toSrv[client].insert(make_pair(rank, CArray<int,1>(nb))); 1632 listOutIndex.push_back(CArray<size_t,1>(nb)); 1633 1634 CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 1635 CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 1636 1637 for (int k = 0; k < nb; ++k) 1638 { 1639 outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k); 1640 outLocalIndexToServer(k) = localIndexTmp[rank].at(k); 1641 } 1642 1643 storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 1644 listMsg.push_back(CMessage()); 1645 listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 1646 1647 event.push(rank, nbSenders[receiverSize][rank], listMsg.back()); 1648 } 1649 1650 client->sendEvent(event); 1651 } 1652 } 1653 } 1654 CATCH_DUMP_ATTR 1655 1656 void CGrid::recvIndex(CEventServer& event) 1657 TRY 1658 { 1659 string gridId; 1660 vector<int> ranks; 1661 vector<CBufferIn*> buffers; 1662 1663 list<CEventServer::SSubEvent>::iterator it; 1664 for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 1665 { 1666 ranks.push_back(it->rank); 1667 CBufferIn* buffer = it->buffer; 1668 *buffer >> gridId; 1669 buffers.push_back(buffer); 1670 } 1671 get(gridId)->recvIndex(ranks, buffers); 1672 } 1673 CATCH 1674 1675 void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers) 1676 TRY 1677 { 1678 CContext* context = CContext::getCurrent(); 1679 connectedServerRankRead_ = ranks; 1680 1681 int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 1682 nbSrvPools = 1; 1683 nbReadSenders.clear(); 1684 for (int p = 0; p < nbSrvPools; ++p) 1685 { 1686 CContextServer* server = (!context->hasClient) ? context->server : context->serverPrimServer[p]; 1687 CContextClient* client = context->client; //(!context->hasClient) ? context->client : context->clientPrimServer[p]; 1688 1689 int idx = 0, numElement = axis_domain_order.numElements(); 1690 int ssize = numElement; 1691 std::vector<int> indexMap(numElement); 1692 for (int i = 0; i < numElement; ++i) 1693 { 1694 indexMap[i] = idx; 1695 if (2 == axis_domain_order(i)) 1696 { 1697 ++ssize; 1698 idx += 2; 1699 } 1700 else 1701 ++idx; 1702 } 1703 1704 for (int n = 0; n < ranks.size(); n++) 1705 { 1706 int rank = ranks[n]; 1707 CBufferIn& buffer = *buffers[n]; 1708 1709 buffer >> isDataDistributed_ >> isCompressible_; 1710 size_t dataSize = 0; 1711 1712 if (0 == serverDistribution_) 1713 { 1714 int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 1715 std::vector<CDomain*> domainList = getDomains(); 1716 std::vector<CAxis*> axisList = getAxis(); 1717 std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize), nGlobElement(numElement); 1718 std::vector<CArray<int,1> > globalIndex(numElement); 1719 for (int i = 0; i < numElement; ++i) 1720 { 1721 nGlobElement[i] = globalSize; 1722 if (2 == axis_domain_order(i)) //domain 1723 { 1724 nBegin[indexMap[i]] = domainList[domainId]->ibegin; 1725 nSize[indexMap[i]] = domainList[domainId]->ni; 1726 nBeginGlobal[indexMap[i]] = 0; 1727 nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 1728 1729 nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 1730 nSize[indexMap[i] + 1] = domainList[domainId]->nj; 1731 nBeginGlobal[indexMap[i] + 1] = 0; 1732 nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 1733 1734 { 1735 int count = 0; 1736 globalIndex[i].resize(nSize[indexMap[i]]*nSize[indexMap[i]+1]); 1737 for (int jdx = 0; jdx < nSize[indexMap[i]+1]; ++jdx) 1738 for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 1739 { 1740 globalIndex[i](count) = (nBegin[indexMap[i]] + idx) + (nBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]]; 1741 ++count; 1742 } 1743 } 1744 1745 ++domainId; 1746 } 1747 else if (1 == axis_domain_order(i)) // axis 1748 { 1749 nBegin[indexMap[i]] = axisList[axisId]->begin; 1750 nSize[indexMap[i]] = axisList[axisId]->n; 1751 nBeginGlobal[indexMap[i]] = 0; 1752 nGlob[indexMap[i]] = axisList[axisId]->n_glo; 1753 globalIndex[i].resize(nSize[indexMap[i]]); 1754 for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 1755 globalIndex[i](idx) = nBegin[indexMap[i]] + idx; 1756 1757 ++axisId; 1758 } 1759 else // scalar 1760 { 1761 nBegin[indexMap[i]] = 0; 1762 nSize[indexMap[i]] = 1; 1763 nBeginGlobal[indexMap[i]] = 0; 1764 nGlob[indexMap[i]] = 1; 1765 globalIndex[i].resize(1); 1766 globalIndex[i](0) = 0; 1767 ++scalarId; 1768 } 1769 } 1770 dataSize = 1; 1771 1772 for (int i = 0; i < nSize.size(); ++i) 1773 dataSize *= nSize[i]; 1774 serverDistribution_ = new CDistributionServer(server->intraCommRank, 1775 globalIndex, axis_domain_order, 1776 nBegin, nSize, nBeginGlobal, nGlob); 1777 } 1778 1779 CArray<size_t,1> outIndex; 1780 buffer >> outIndex; 1781 outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex)); 1782 connectedDataSizeRead_[rank] = outIndex.numElements(); 1783 1784 if (doGridHaveDataDistributed(client)) 1785 {} 1786 else 1787 { 1788 // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER 1789 // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar) 1790 dataSize = serverDistribution_->getGridSize(); 1791 } 1792 writtenDataSize_ += dataSize; 1793 } 1794 1795 1796 // Compute mask of the current grid 1797 { 1798 int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 1799 std::vector<CDomain*> domainList = getDomains(); 1800 std::vector<CAxis*> axisList = getAxis(); 1801 int dimSize = 2 * domainList.size() + axisList.size(); 1802 std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize); 1803 for (int i = 0; i < numElement; ++i) 1804 { 1805 if (2 == axis_domain_order(i)) //domain 1806 { 1807 nBegin[indexMap[i]] = domainList[domainId]->ibegin; 1808 nSize[indexMap[i]] = domainList[domainId]->ni; 1809 nBeginGlobal[indexMap[i]] = 0; 1810 nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 1811 1812 nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 1813 nSize[indexMap[i] + 1] = domainList[domainId]->nj; 1814 nBeginGlobal[indexMap[i] + 1] = 0; 1815 nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 1816 1817 ++domainId; 1818 } 1819 else if (1 == axis_domain_order(i)) // axis 1820 { 1821 nBegin[indexMap[i]] = axisList[axisId]->begin; 1822 nSize[indexMap[i]] = axisList[axisId]->n; 1823 nBeginGlobal[indexMap[i]] = 0; 1824 nGlob[indexMap[i]] = axisList[axisId]->n_glo; 1825 ++axisId; 1826 } 1827 else // scalar 1828 { 1829 } 1830 } 1831 1832 if (nSize.empty()) // Scalar grid 1833 { 1834 nBegin.push_back(0); 1835 nSize.push_back(1); 1836 nBeginGlobal.push_back(0); 1837 nGlob.push_back(1); 1838 } 1839 } 1840 1841 if (isScalarGrid()) return; 1842 1843 nbReadSenders[client] = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks); 1844 } 1845 } 1846 CATCH_DUMP_ATTR 1847 1038 1039 1040 1848 1041 /* 1849 1042 Compute on the fly the global dimension of a grid with its elements … … 1938 1131 TRY 1939 1132 { 1940 return (0 != writtenDataSize_);1133 return (0 != getGridLocalElements()->getView(CElementView::FULL)->getSize()); 1941 1134 } 1942 1135 CATCH_DUMP_ATTR 1943 1136 1944 /*! 1945 Return size of data which is written on each server 1946 Whatever dimension of a grid, data which are written on server must be presented as 1947 an one dimension array. 1948 \return size of data written on server 1949 */ 1950 size_t CGrid::getWrittenDataSize() const 1951 TRY 1952 { 1953 return writtenDataSize_; 1954 } 1955 CATCH 1956 1957 /*! 1958 Returns the number of indexes written by each server. 1959 \return the number of indexes written by each server 1960 */ 1961 int CGrid::getNumberWrittenIndexes() const 1962 TRY 1963 { 1964 return numberWrittenIndexes_; 1965 } 1966 CATCH 1967 1968 /*! 1969 Returns the total number of indexes written by the servers. 1970 \return the total number of indexes written by the servers 1971 */ 1972 int CGrid::getTotalNumberWrittenIndexes() const 1973 TRY 1974 { 1975 return totalNumberWrittenIndexes_; 1976 } 1977 CATCH 1978 1979 /*! 1980 Returns the offset of indexes written by each server. 1981 \return the offset of indexes written by each server 1982 */ 1983 int CGrid::getOffsetWrittenIndexes() const 1984 TRY 1985 { 1986 return offsetWrittenIndexes_; 1987 } 1988 CATCH 1989 1990 CDistributionServer* CGrid::getDistributionServer() 1991 TRY 1992 { 1993 return serverDistribution_; 1994 } 1995 CATCH_DUMP_ATTR 1996 1997 CDistributionClient* CGrid::getDistributionClient() 1998 TRY 1999 { 2000 return clientDistribution_; 2001 } 2002 CATCH_DUMP_ATTR 2003 1137 2004 1138 bool CGrid::doGridHaveDataDistributed(CContextClient* client) 2005 1139 TRY 2006 1140 { 1141 // This function is now useless because it will return false only if server and client size are equal to 1 1142 // to be seriously check in future 1143 2007 1144 if (isScalarGrid()) return false; 2008 1145 else if (0 != client) 2009 1146 { 2010 return (isDataDistributed _|| (1 != client->clientSize) || (1 != client->serverSize));1147 return (isDataDistributed() || (1 != client->clientSize) || (1 != client->serverSize)); 2011 1148 } 2012 1149 else 2013 return isDataDistributed _;1150 return isDataDistributed(); 2014 1151 } 2015 1152 CATCH_DUMP_ATTR … … 2031 1168 switch(event.type) 2032 1169 { 2033 case EVENT_ID_INDEX :2034 recvIndex(event);2035 return true;2036 break;2037 2038 1170 case EVENT_ID_ADD_DOMAIN : 2039 1171 recvAddDomain(event); … … 2050 1182 return true; 2051 1183 break; 1184 1185 case EVENT_ID_SEND_MASK : 1186 recvMask(event); 1187 return true; 1188 break; 2052 1189 default : 2053 ERROR("bool C Domain::dispatchEvent(CEventServer& event)",1190 ERROR("bool CGrid::dispatchEvent(CEventServer& event)", 2054 1191 << "Unknown Event"); 2055 1192 return false; … … 2059 1196 CATCH 2060 1197 2061 ///--------------------------------------------------------------- 2062 2063 CDomain* CGrid::addDomain(const std::string& id) 2064 TRY 2065 { 2066 order_.push_back(2); 2067 axis_domain_order.resize(order_.size()); 2068 for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 2069 return vDomainGroup_->createChild(id); 2070 } 2071 CATCH_DUMP_ATTR 2072 2073 CAxis* CGrid::addAxis(const std::string& id) 2074 TRY 2075 { 2076 order_.push_back(1); 2077 axis_domain_order.resize(order_.size()); 2078 for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 2079 return vAxisGroup_->createChild(id); 2080 } 2081 CATCH_DUMP_ATTR 2082 2083 CScalar* CGrid::addScalar(const std::string& id) 2084 TRY 2085 { 2086 order_.push_back(0); 2087 axis_domain_order.resize(order_.size()); 2088 for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 2089 return vScalarGroup_->createChild(id); 2090 } 2091 CATCH_DUMP_ATTR 2092 2093 //! Change virtual field group to a new one 2094 void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup) 2095 TRY 2096 { 2097 this->vDomainGroup_ = newVDomainGroup; 2098 } 2099 CATCH_DUMP_ATTR 2100 2101 //! Change virtual variable group to new one 2102 void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup) 2103 TRY 2104 { 2105 this->vAxisGroup_ = newVAxisGroup; 2106 } 2107 CATCH_DUMP_ATTR 2108 2109 //! Change virtual variable group to new one 2110 void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup) 2111 TRY 2112 { 2113 this->vScalarGroup_ = newVScalarGroup; 2114 } 2115 CATCH_DUMP_ATTR 1198 1199 1200 void CGrid::sendGridToFileServer(CContextClient* client) 1201 { 1202 if (sendGridToFileServer_done_.count(client)!=0) return ; 1203 else sendGridToFileServer_done_.insert(client) ; 1204 1205 StdString gridDefRoot("grid_definition"); 1206 CGridGroup* gridPtr = CGridGroup::get(gridDefRoot); 1207 gridPtr->sendCreateChild(this->getId(),client); 1208 this->sendAllAttributesToServer(client); 1209 distributeGridToFileServer(client) ; 1210 } 1211 1212 1213 void CGrid::distributeGridToFileServer(CContextClient* client) 1214 { 1215 CContext* context = CContext::getCurrent(); 1216 // simple Distribution for now 1217 // distribute over the fisrt element except if it is a scalar 1218 auto& elements = getElements() ; 1219 int posDistributed = 0 ; 1220 for(auto& element : elements) 1221 { 1222 if (element.type==TYPE_DOMAIN) break ; 1223 else if (element.type==TYPE_AXIS) break ; 1224 else if (element.type==TYPE_SCALAR) posDistributed++ ; 1225 } 1226 1227 vector<CLocalView*> localViews ; 1228 vector<CDistributedView*> remoteViews ; 1229 1230 for(int i=0 ; i<elements.size() ; i++) 1231 { 1232 if (elements[i].type==TYPE_DOMAIN) 1233 { 1234 CDomain* domain = (CDomain*) elements[i].ptr ; 1235 domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 1236 remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ; 1237 localViews.push_back(domain->getLocalView(CElementView::FULL)) ; 1238 } 1239 else if (elements[i].type==TYPE_AXIS) 1240 { 1241 CAxis* axis = (CAxis*) elements[i].ptr ; 1242 axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 1243 remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ; 1244 localViews.push_back(axis->getLocalView(CElementView::FULL)) ; 1245 } 1246 else if (elements[i].type==TYPE_SCALAR) 1247 { 1248 CScalar* scalar = (CScalar*) elements[i].ptr ; 1249 scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 1250 remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ; 1251 localViews.push_back(scalar->getLocalView(CElementView::FULL)) ; 1252 } 1253 } 1254 CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm(), client->getRemoteSize()) ; 1255 gridRemoteConnector.computeConnector() ; 1256 1257 vector<CScattererConnector*> scattererConnectors ; 1258 CScattererConnector* scattererConnector; 1259 for(int i=0 ; i<elements.size() ; i++) 1260 { 1261 if (elements[i].type==TYPE_DOMAIN) 1262 { 1263 CDomain* domain = (CDomain*) elements[i].ptr ; 1264 sendAddDomain(domain->getId(),client) ; 1265 domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 1266 scattererConnectors.push_back(scattererConnector) ; 1267 } 1268 else if (elements[i].type==TYPE_AXIS) 1269 { 1270 CAxis* axis = (CAxis*) elements[i].ptr ; 1271 sendAddAxis(axis->getId(),client) ; 1272 axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 1273 scattererConnectors.push_back(scattererConnector) ; 1274 } 1275 else if (elements[i].type==TYPE_SCALAR) 1276 { 1277 CScalar* scalar = (CScalar*) elements[i].ptr ; 1278 sendAddScalar(scalar->getId(),client) ; 1279 scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 1280 scattererConnectors.push_back(scattererConnector) ; 1281 } 1282 } 1283 1284 CGridScattererConnector gridScattererConnector(scattererConnectors) ; 1285 CGridLocalConnector* workflowToFull = getGridLocalElements()->getConnector(CElementView::WORKFLOW, CElementView::FULL) ; 1286 CArray<bool,1> maskIn(workflowToFull->getSrcSize()) ; 1287 CArray<bool,1> maskOut(workflowToFull->getDstSize()) ; 1288 maskIn = true ; 1289 workflowToFull->transfer(maskIn,maskOut,false) ; 1290 1291 CEventClient event(getType(), EVENT_ID_SEND_MASK); 1292 CMessage message ; 1293 message<<getId() ; 1294 gridScattererConnector.transfer(maskOut, client, event, message) ; 1295 for(auto& it : scattererConnectors) delete it ; 1296 1297 vector<CScattererConnector*> clientToServerConnectors ; 1298 vector<CGathererConnector*> clientFromServerConnectors ; 1299 for(auto& element : elements) 1300 { 1301 if (element.type==TYPE_DOMAIN) 1302 { 1303 clientToServerConnectors.push_back(element.domain->getClientToServerConnector(client)) ; 1304 clientFromServerConnectors.push_back(element.domain->getClientFromServerConnector(client)) ; 1305 } 1306 else if (element.type==TYPE_AXIS) 1307 { 1308 clientToServerConnectors.push_back(element.axis->getClientToServerConnector(client)) ; 1309 clientFromServerConnectors.push_back(element.axis->getClientFromServerConnector(client)) ; 1310 1311 } 1312 else if (element.type==TYPE_SCALAR) 1313 { 1314 clientToServerConnectors.push_back(element.scalar->getClientToServerConnector(client)) ; 1315 clientFromServerConnectors.push_back(element.scalar->getClientFromServerConnector(client)) ; 1316 } 1317 } 1318 1319 // compute the grid clientToServerConnector to send flux from client to servers 1320 clientToServerConnector_[client] = new CGridScattererConnector(clientToServerConnectors) ; 1321 clientFromServerConnector_[client] = new CGridGathererConnector(clientFromServerConnectors) ; 1322 1323 1324 } 1325 1326 void CGrid::recvMask(CEventServer& event) 1327 { 1328 string gridId; 1329 for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> gridId ; 1330 get(gridId)->receiveMask(event); 1331 } 1332 1333 void CGrid::receiveMask(CEventServer& event) 1334 { 1335 vector<CGathererConnector*> gathererConnectors ; 1336 vector<CLocalView*> fullViews ; 1337 1338 for(auto& element : getElements()) 1339 { 1340 if (element.type==TYPE_DOMAIN) 1341 { 1342 gathererConnectors.push_back(element.domain->getGathererConnector()); 1343 fullViews.push_back(element.domain->getLocalElement()->getView(CElementView::FULL)); 1344 1345 } 1346 else if (element.type==TYPE_AXIS) 1347 { 1348 gathererConnectors.push_back(element.axis->getGathererConnector()); 1349 fullViews.push_back(element.axis->getLocalElement()->getView(CElementView::FULL)); 1350 } 1351 else if (element.type==TYPE_SCALAR) 1352 { 1353 gathererConnectors.push_back(element.scalar->getGathererConnector()); 1354 fullViews.push_back(element.scalar->getLocalElement()->getView(CElementView::FULL)); 1355 } 1356 } 1357 CGridGathererConnector gridGathererConnector(gathererConnectors) ; 1358 CGridMaskConnector gridMaskConnector(fullViews) ; 1359 1360 CArray<bool,1> maskOut ; 1361 gridGathererConnector.transfer_or(event,maskOut) ; 1362 gridMaskConnector.computeConnector(maskOut) ; 1363 1364 CContextClient* client = event.getContextServer()->getAssociatedClient() ; 1365 int i=0 ; 1366 for(auto& element : getElements()) 1367 { 1368 if (element.type==TYPE_DOMAIN) element.domain->setServerMask(gridMaskConnector.getElementMask(i),client); 1369 else if (element.type==TYPE_AXIS) element.axis->setServerMask(gridMaskConnector.getElementMask(i),client); 1370 else if (element.type==TYPE_SCALAR) element.scalar->setServerMask(gridMaskConnector.getElementMask(i),client); 1371 i++ ; 1372 } 1373 } 1374 1375 1376 void CGrid::sendGridToCouplerOut(CContextClient* client, const string& fieldId) 1377 { 1378 /* if (sendGridToCouplerOut_done_.count(client)!=0) return ; 1379 else sendGridToCouplerOut_done_.insert(client) ; 1380 1381 CContext* context = CContext::getCurrent(); 1382 // simple Distribution for now 1383 // distribute over the fisrt element except if it is a scalar 1384 auto& elements = getElements() ; 1385 int posDistributed = 0 ; 1386 for(auto& element : elements) 1387 { 1388 if (element.type==TYPE_DOMAIN) break ; 1389 else if (element.type==TYPE_AXIS) break ; 1390 else if (element.type==TYPE_SCALAR) posDistributed++ ; 1391 } 1392 1393 vector<CLocalView*> localViews ; 1394 vector<CDistributedView*> remoteViews ; 1395 1396 for(int i=0 ; i<elements.size() ; i++) 1397 { 1398 if (elements[i].type==TYPE_DOMAIN) 1399 { 1400 CDomain* domain = (CDomain*) elements[i].ptr ; 1401 domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 1402 remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ; 1403 localViews.push_back(domain->getLocalView(CElementView::FULL)) ; 1404 } 1405 else if (elements[i].type==TYPE_AXIS) 1406 { 1407 CAxis* axis = (CAxis*) elements[i].ptr ; 1408 axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 1409 remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ; 1410 localViews.push_back(axis->getLocalView(CElementView::FULL)) ; 1411 } 1412 else if (elements[i].type==TYPE_SCALAR) 1413 { 1414 CScalar* scalar = (CScalar*) elements[i].ptr ; 1415 scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 1416 remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ; 1417 localViews.push_back(scalar->getLocalView(CElementView::FULL)) ; 1418 } 1419 } 1420 CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm(), client->getRemoteSize()) ; 1421 gridRemoteConnector.computeConnector() ; 1422 1423 vector<CScattererConnector*> clientToClientConnectors ; 1424 for(int i=0 ; i<elements.size() ; i++) 1425 { 1426 if (elements[i].type==TYPE_DOMAIN) 1427 { 1428 CDomain* domain = (CDomain*) elements[i].ptr ; 1429 sendAddDomain(domain->getId(),client) ; 1430 domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 1431 clientToClientConnectors.push_back(domain->getClientToServerConnector(client)) ; 1432 } 1433 else if (elements[i].type==TYPE_AXIS) 1434 { 1435 CAxis* axis = (CAxis*) elements[i].ptr ; 1436 sendAddAxis(axis->getId(),client) ; 1437 axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 1438 clientToClientConnectors.push_back(axis->getClientToServerConnector(client)) ; 1439 } 1440 else if (elements[i].type==TYPE_SCALAR) 1441 { 1442 CScalar* scalar = (CScalar*) elements[i].ptr ; 1443 sendAddScalar(scalar->getId(),client) ; 1444 scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 1445 clientToClientConnectors.push_back(scalar->getClientToServerConnector(client)) ; 1446 } 1447 } 1448 1449 // compute the grid clientToServerConnector to send flux from client to servers 1450 clientToClientConnector_[client] = new CGridScattererConnector(clientToClientConnectors) ;*/ 1451 } 1452 1453 void CGrid::makeAliasForCoupling(const string& fieldId) 1454 { 1455 string gridId="_grid_of_"+fieldId ; 1456 createAlias(gridId) ; 1457 1458 const auto& domVect = getDomains() ; 1459 for (int pos=0; pos<domVect.size();pos++) domVect[pos]->makeAliasForCoupling(fieldId, pos); 1460 1461 const auto& axisVect=getAxis() ; 1462 for (int pos=0; pos<axisVect.size();pos++) axisVect[pos]->makeAliasForCoupling(fieldId, pos); 1463 1464 const auto& scalVect=getScalars() ; 1465 for (int pos=0; pos<scalVect.size();pos++) scalVect[pos]->makeAliasForCoupling(fieldId, pos); 1466 } 2116 1467 2117 1468 /*! … … 2119 1470 \param[in] id String identity of domain that will be created on server 2120 1471 */ 2121 void CGrid::sendAddDomain(const string& id )2122 TRY 2123 { 2124 sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN );1472 void CGrid::sendAddDomain(const string& id, CContextClient* contextClient) 1473 TRY 1474 { 1475 sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN, contextClient); 2125 1476 } 2126 1477 CATCH_DUMP_ATTR … … 2130 1481 \param[in] id String identity of axis that will be created on server 2131 1482 */ 2132 void CGrid::sendAddAxis(const string& id )2133 TRY 2134 { 2135 sendAddItem(id, (int)EVENT_ID_ADD_AXIS );1483 void CGrid::sendAddAxis(const string& id, CContextClient* contextClient) 1484 TRY 1485 { 1486 sendAddItem(id, (int)EVENT_ID_ADD_AXIS, contextClient); 2136 1487 } 2137 1488 CATCH_DUMP_ATTR … … 2141 1492 \param[in] id String identity of scalar that will be created on server 2142 1493 */ 2143 void CGrid::sendAddScalar(const string& id )2144 TRY 2145 { 2146 sendAddItem(id, (int)EVENT_ID_ADD_SCALAR );1494 void CGrid::sendAddScalar(const string& id, CContextClient* contextClient) 1495 TRY 1496 { 1497 sendAddItem(id, (int)EVENT_ID_ADD_SCALAR, contextClient); 2147 1498 } 2148 1499 CATCH_DUMP_ATTR … … 2231 1582 } 2232 1583 CATCH_DUMP_ATTR 1584 1585 /*! 1586 \brief Check if all elements of the grid are complete 1587 Before make any grid processing, we must be sure that all grid information elements have 1588 been sent, for exemple when reading a grid in a file or when grid elements are sent by an 1589 other context (coupling) 1590 */ 1591 bool CGrid::isCompleted(void) 1592 { 1593 setDomainList(); 1594 for (auto domainId : domList_) if (!CDomain::get(domainId)->isCompleted()) return false ; 1595 setAxisList() ; 1596 for (auto axisId : axisList_) if (!CAxis::get(axisId)->isCompleted()) return false ; 1597 setScalarList() ; 1598 for (auto scalarId : scalarList_) if (!CScalar::get(scalarId)->isCompleted()) return false ; 1599 return true ; 1600 } 1601 1602 /*! 1603 \brief impose that all elements of the grid are complete 1604 Before make any grid processing, we must be sure that all grid information elements have 1605 been sent, for exemple when reading a grid in a file or when grid elements are sent by an 1606 other context (coupling) 1607 */ 1608 void CGrid::setCompleted(void) 1609 { 1610 setDomainList(); 1611 for (auto domainId : domList_) CDomain::get(domainId)->setCompleted() ; 1612 setAxisList() ; 1613 for (auto axisId : axisList_) CAxis::get(axisId)->setCompleted() ; 1614 setScalarList() ; 1615 for (auto scalarId : scalarList_) CScalar::get(scalarId)->setCompleted() ; 1616 } 1617 1618 /*! 1619 \brief impose that all elements of the grid are incomplete 1620 Before make any grid processing, we must be sure that all grid information elements have 1621 been sent, for exemple when reading a grid in a file or when grid elements are sent by an 1622 other context (coupling) 1623 */ 1624 void CGrid::unsetCompleted(void) 1625 { 1626 setDomainList(); 1627 for (auto domainId : domList_) CDomain::get(domainId)->unsetCompleted() ; 1628 setAxisList() ; 1629 for (auto axisId : axisList_) CAxis::get(axisId)->unsetCompleted() ; 1630 setScalarList() ; 1631 for (auto scalarId : scalarList_) CScalar::get(scalarId)->unsetCompleted() ; 1632 } 2233 1633 2234 1634 /*! … … 2238 1638 \param[in] apply inherit all attributes of parents (true) 2239 1639 */ 2240 void CGrid::solveDomainAxisRefInheritance(bool apply) 2241 TRY 2242 { 2243 CContext* context = CContext::getCurrent(); 2244 unsigned int vecSize, i; 2245 std::vector<StdString>::iterator it, itE; 1640 void CGrid::solveElementsRefInheritance(bool apply) 1641 TRY 1642 { 2246 1643 setDomainList(); 2247 it = domList_.begin(); itE = domList_.end(); 2248 for (; it != itE; ++it) 2249 { 2250 CDomain* pDom = CDomain::get(*it); 2251 if (context->hasClient && !context->hasServer) 2252 { 2253 pDom->solveRefInheritance(apply); 2254 pDom->solveInheritanceTransformation(); 2255 } 1644 for (auto domainId : domList_) 1645 { 1646 CDomain* pDom = CDomain::get(domainId); 1647 pDom->solveRefInheritance(apply); 1648 pDom->solveInheritanceTransformation(); 2256 1649 } 2257 1650 2258 1651 setAxisList(); 2259 it = axisList_.begin(); itE = axisList_.end(); 2260 for (; it != itE; ++it) 2261 { 2262 CAxis* pAxis = CAxis::get(*it); 2263 if (context->hasClient && !context->hasServer) 2264 { 2265 pAxis->solveRefInheritance(apply); 2266 pAxis->solveInheritanceTransformation(); 2267 } 1652 for (auto axisId : axisList_) 1653 { 1654 CAxis* pAxis = CAxis::get(axisId); 1655 pAxis->solveRefInheritance(apply); 1656 pAxis->solveInheritanceTransformation(); 2268 1657 } 2269 1658 2270 1659 setScalarList(); 2271 it = scalarList_.begin(); itE = scalarList_.end(); 2272 for (; it != itE; ++it) 2273 { 2274 CScalar* pScalar = CScalar::get(*it); 2275 if (context->hasClient && !context->hasServer) 2276 { 2277 pScalar->solveRefInheritance(apply); 2278 pScalar->solveInheritanceTransformation(); 2279 } 1660 for (auto scalarId : scalarList_) 1661 { 1662 CScalar* pScalar = CScalar::get(scalarId); 1663 pScalar->solveRefInheritance(apply); 1664 pScalar->solveInheritanceTransformation(); 2280 1665 } 2281 1666 } 2282 1667 CATCH_DUMP_ATTR 2283 1668 2284 bool CGrid::isTransformed() 2285 TRY 2286 { 2287 return isTransformed_; 1669 /*! 1670 \brief check attributes of all elements of the grid 1671 */ 1672 void CGrid::checkElementsAttributes(void) 1673 TRY 1674 { 1675 setDomainList(); 1676 for (auto domainId : domList_) CDomain::get(domainId)->checkAttributes(); 1677 1678 setAxisList(); 1679 for (auto axisId : axisList_) CAxis::get(axisId)->checkAttributes(); 1680 1681 setScalarList(); 1682 for (auto scalarId : scalarList_) CScalar::get(scalarId)->checkAttributes(); 2288 1683 } 2289 1684 CATCH_DUMP_ATTR 2290 1685 2291 void CGrid::setTransformed() 2292 TRY 2293 { 2294 isTransformed_ = true; 1686 1687 1688 //********************************************************** 1689 //************** New transformation method ************** 1690 //********************************************************** 1691 1692 std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > 1693 CGrid::buildTransformationGraph(CGarbageCollector& gc, bool isSource, CGrid* gridSrc, double detectMissingValues, double defaultValue, CGrid*& newGrid, bool graphEnabled) 1694 TRY 1695 { 1696 registerAlgorithmTransformation() ; // needed to enable self-registration of the transformations 1697 // big mystery why it doesn't work witout that... 1698 // problem with the linker ?? 1699 1700 std::shared_ptr<CFilter> inputFilter = std::shared_ptr<CPassThroughFilter>(new CPassThroughFilter(gc)); 1701 std::shared_ptr<CFilter> outputFilter = inputFilter ; 1702 1703 1704 string newId ; 1705 if (gridSrc!=nullptr) newId = gridSrc->getId() + " --> " + this->getId() ; 1706 else newId = " --> " + this->getId() ; 1707 bool isNewGrid ; 1708 if (CGrid::has(newId)) 1709 { 1710 cout<<"Retrive existing grid : "<<newId<<endl ; 1711 newGrid = CGrid::get(newId); 1712 isNewGrid = false ; 1713 } 1714 else 1715 { 1716 cout<<"Create new grid : "<<newId<<endl ; 1717 newGrid = CGrid::create(newId) ; 1718 isNewGrid = true ; 1719 } 1720 1721 bool hadTransform=false ; 1722 bool hasTransform=false ; 1723 bool hasRemainTransform=false ; 1724 CGenericAlgorithmTransformation* algo ; 1725 int pos ; 1726 1727 for(int i=0 ; i<elements_.size(); i++) 1728 { 1729 CTransformationPaths transformationPath ; 1730 auto dstElement = elements_[i] ; 1731 1732 if (dstElement.type==TYPE_DOMAIN) transformationPath = dstElement.domain->getTransformationPaths() ; 1733 else if (dstElement.type==TYPE_AXIS) transformationPath = dstElement.axis->getTransformationPaths() ; 1734 else if (dstElement.type==TYPE_SCALAR) transformationPath = dstElement.scalar->getTransformationPaths() ; 1735 1736 SElement srcElement ; 1737 if (gridSrc==nullptr) srcElement = this->elements_[i] ; 1738 else srcElement = gridSrc->elements_[i] ; 1739 1740 if (gridSrc==nullptr) transformationPath.mergePaths() ; 1741 else 1742 { 1743 if (srcElement.type==TYPE_DOMAIN) transformationPath.mergePaths(srcElement.domain->getTransformationPaths()) ; 1744 else if (srcElement.type==TYPE_AXIS) transformationPath.mergePaths(srcElement.axis->getTransformationPaths()) ; 1745 else if (srcElement.type==TYPE_SCALAR) transformationPath.mergePaths(srcElement.scalar->getTransformationPaths()) ; 1746 } 1747 1748 hasTransform=transformationPath.hasTransform() ; 1749 1750 if (hasTransform && !hadTransform) 1751 { 1752 pos=i ; 1753 EElement dstElementType=transformationPath.getNextElementType() ; 1754 string dstElementId=transformationPath.getNextElementId() ; 1755 string srcElementId=transformationPath.getNextElementSrcId() ; 1756 auto transType = transformationPath.getNextTransformationType() ; 1757 auto transId = transformationPath.getNextTransformationId() ; 1758 1759 CGrid* tmpGridSrc=CGrid::create(); // source grid 1760 if (srcElement.type==TYPE_DOMAIN) tmpGridSrc->addDomain(srcElement.domain->getId()) ; 1761 else if (srcElement.type==TYPE_AXIS) tmpGridSrc->addAxis(srcElement.axis->getId()) ; 1762 else if (srcElement.type==TYPE_SCALAR) tmpGridSrc->addScalar(srcElement.scalar->getId()) ; 1763 tmpGridSrc->checkElementsAttributes() ; 1764 CGrid* tmpGridDst=CGrid::create(); // destination Grid 1765 map<int,int> posInGrid={{0,0}} ; 1766 1767 cout<<"--> New transform from "<<srcElementId<<" to "<<dstElementId<<endl ; 1768 if (dstElementType==EElement::DOMAIN) 1769 { 1770 CDomain* dstDomain ; 1771 CDomain* lastDstDomain ; 1772 bool isGenerate=false ; 1773 1774 do 1775 { 1776 1777 if (CDomain::has(dstElementId)) 1778 { 1779 dstDomain = CDomain::get(dstElementId) ; 1780 cout<<"Retrive existing domain : "<<dstElementId<<endl ; 1781 } 1782 else 1783 { 1784 dstDomain = CDomain::create() ; 1785 dstDomain->createAlias(dstElementId) ; 1786 cout<<"Create new domain : "<<dstDomain->getId()<<" with alias : "<<dstElementId<<endl ; 1787 1788 if (isGenerate) dstDomain->duplicateAttributes(lastDstDomain) ; 1789 else if (srcElementId=="" && srcElement.type==TYPE_DOMAIN) dstDomain->duplicateAttributes(srcElement.domain) ; // make a copy 1790 else dstDomain->duplicateAttributes(dstElement.domain) ; // make a copy 1791 CTransformation<CDomain>* transformation = CTransformation<CDomain>::createTransformation(transType,"") ; 1792 auto srcTransform = CTransformation<CDomain>::getTransformation(transType, transId) ; 1793 transformation->inheritFrom(srcTransform) ; 1794 CGrid* tmpGridDst=CGrid::create(); // destination Grid 1795 tmpGridDst->addDomain(dstDomain->getId()) ; 1796 1797 algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 1798 posInGrid,posInGrid,posInGrid, 1799 posInGrid,posInGrid,posInGrid ); 1800 1801 1802 dstDomain->setTransformationAlgorithm(algo) ; 1803 dstDomain->setTransformationPaths(transformationPath) ; 1804 } 1805 algo=dstDomain->getTransformationAlgorithm() ; 1806 isGenerate = algo->isGenerateTransformation() ; 1807 transformationPath.removeNextTransform() ; 1808 dstElementId=transformationPath.getNextElementId() ; 1809 srcElementId=transformationPath.getNextElementSrcId() ; 1810 transType = transformationPath.getNextTransformationType() ; 1811 transId = transformationPath.getNextTransformationId() ; 1812 lastDstDomain=dstDomain ; 1813 dstDomain->setTransformationPaths(transformationPath) ; 1814 } while(transformationPath.hasTransform() && isGenerate) ; 1815 1816 if (isNewGrid) newGrid->addDomain(dstDomain->getId()) ; 1817 algo = dstDomain->getTransformationAlgorithm() ; 1818 } 1819 else if (dstElementType==EElement::AXIS) 1820 { 1821 CAxis* dstAxis ; 1822 CAxis* lastDstAxis ; 1823 bool isGenerate=false ; 1824 1825 do 1826 { 1827 if (CAxis::has(dstElementId)) 1828 { 1829 dstAxis = CAxis::get(dstElementId) ; 1830 cout<<"Retrive existing axis : "<<dstElementId<<endl ; 1831 } 1832 else 1833 { 1834 dstAxis = CAxis::create() ; 1835 dstAxis->createAlias(dstElementId) ; 1836 cout<<"Create new axis : "<<dstAxis->getId()<<" with alias : "<<dstElementId<<endl ; 1837 1838 if (isGenerate) dstAxis->duplicateAttributes(lastDstAxis) ; 1839 else if (srcElementId=="" && srcElement.type==TYPE_AXIS) dstAxis->duplicateAttributes(srcElement.axis) ; // make a copy 1840 else dstAxis->duplicateAttributes(dstElement.axis) ; // make a copy 1841 CTransformation<CAxis>* transformation = CTransformation<CAxis>::createTransformation(transType,"") ; 1842 auto srcTransform = CTransformation<CAxis>::getTransformation(transType, transId) ; 1843 transformation->inheritFrom(srcTransform) ; 1844 tmpGridDst->addAxis(dstAxis->getId()) ; 1845 1846 algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 1847 posInGrid,posInGrid,posInGrid, 1848 posInGrid,posInGrid,posInGrid ); 1849 1850 dstAxis->setTransformationAlgorithm(algo) ; 1851 dstAxis->setTransformationPaths(transformationPath) ; 1852 } 1853 1854 algo=dstAxis->getTransformationAlgorithm() ; 1855 isGenerate = algo->isGenerateTransformation() ; 1856 transformationPath.removeNextTransform() ; 1857 dstElementId=transformationPath.getNextElementId() ; 1858 srcElementId=transformationPath.getNextElementSrcId() ; 1859 transType = transformationPath.getNextTransformationType() ; 1860 transId = transformationPath.getNextTransformationId() ; 1861 lastDstAxis=dstAxis ; 1862 dstAxis->setTransformationPaths(transformationPath) ; 1863 } while(transformationPath.hasTransform() && isGenerate) ; 1864 1865 if (isNewGrid) newGrid->addAxis(dstAxis->getId()) ; 1866 algo = dstAxis->getTransformationAlgorithm() ; 1867 } 1868 else if (dstElementType==EElement::SCALAR) 1869 { 1870 CScalar* dstScalar ; 1871 CScalar* lastDstScalar ; 1872 bool isGenerate=false ; 1873 1874 do 1875 { 1876 if (CScalar::has(dstElementId)) 1877 { 1878 dstScalar = CScalar::get(dstElementId) ; 1879 cout<<"Retrive existing scalar : "<<dstElementId<<endl ; 1880 } 1881 else 1882 { 1883 dstScalar = CScalar::create() ; 1884 dstScalar->createAlias(dstElementId) ; 1885 cout<<"Create new scalar : "<<dstScalar->getId()<<" with alias : "<<dstElementId<<endl ; 1886 1887 if (isGenerate) dstScalar->duplicateAttributes(lastDstScalar) ; 1888 else if (srcElementId=="" && srcElement.type==TYPE_SCALAR) dstScalar->duplicateAttributes(srcElement.scalar) ; // make a copy 1889 else dstScalar->duplicateAttributes(dstElement.scalar) ; // make a copy 1890 CTransformation<CScalar>* transformation = CTransformation<CScalar>::createTransformation(transType,"") ; 1891 auto srcTransform = CTransformation<CScalar>::getTransformation(transType, transId) ; 1892 transformation->inheritFrom(srcTransform) ; 1893 tmpGridDst->addScalar(dstScalar->getId()) ; 1894 1895 algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 1896 posInGrid,posInGrid,posInGrid, 1897 posInGrid,posInGrid,posInGrid ); 1898 1899 dstScalar->setTransformationAlgorithm(algo) ; 1900 dstScalar->setTransformationPaths(transformationPath) ; 1901 } 1902 algo=dstScalar->getTransformationAlgorithm() ; 1903 isGenerate = algo->isGenerateTransformation() ; 1904 transformationPath.removeNextTransform() ; 1905 dstElementId=transformationPath.getNextElementId() ; 1906 srcElementId=transformationPath.getNextElementSrcId() ; 1907 transType = transformationPath.getNextTransformationType() ; 1908 transId = transformationPath.getNextTransformationId() ; 1909 lastDstScalar=dstScalar ; 1910 dstScalar->setTransformationPaths(transformationPath) ; 1911 } while(transformationPath.hasTransform() && isGenerate) ; 1912 1913 if (isNewGrid) newGrid->addScalar(dstScalar->getId()) ; 1914 algo = dstScalar->getTransformationAlgorithm() ; 1915 } 1916 // here create a new spatial filter with algo 1917 1918 hadTransform=true ; 1919 hasTransform=false ; 1920 } 1921 else 1922 { 1923 string srcElementId=transformationPath.getNextElementSrcId() ; 1924 1925 if (srcElement.type==TYPE_DOMAIN) 1926 { 1927 CDomain* domain ; 1928 if (srcElementId=="") srcElementId=srcElement.domain->getId() ; 1929 if (!CDomain::has(srcElementId)) 1930 { 1931 domain=srcElement.domain ; 1932 domain->createAlias(srcElementId) ; 1933 } 1934 else domain = CDomain::get(srcElementId) ; 1935 domain->checkAttributes() ; 1936 1937 if (isNewGrid) newGrid->addDomain(srcElementId) ; 1938 } 1939 else if (srcElement.type==TYPE_AXIS) 1940 { 1941 CAxis* axis ; 1942 if (srcElementId=="") srcElementId=srcElement.axis->getId() ; 1943 if (!CAxis::has(srcElementId)) 1944 { 1945 axis=srcElement.axis ; 1946 axis->createAlias(srcElementId) ; 1947 } 1948 else axis = CAxis::get(srcElementId) ; 1949 axis->checkAttributes() ; 1950 1951 if (isNewGrid) newGrid->addAxis(srcElementId) ; 1952 } 1953 else if (srcElement.type==TYPE_SCALAR) 1954 { 1955 CScalar* scalar ; 1956 if (srcElementId=="") srcElementId=srcElement.scalar->getId() ; 1957 if (!CScalar::has(srcElementId)) 1958 { 1959 scalar=srcElement.scalar ; 1960 scalar->createAlias(srcElementId) ; 1961 } 1962 else scalar = CScalar::get(srcElementId) ; 1963 scalar->checkAttributes() ; 1964 1965 if (isNewGrid) newGrid->addScalar(srcElementId) ; 1966 } 1967 } 1968 1969 if (transformationPath.hasTransform() && hadTransform) hasRemainTransform=true ; 1970 } 1971 1972 1973 if (hadTransform) 1974 { 1975 1976 if (!isSource) 1977 { 1978 CGridAlgorithm* gridAlgorithm ; 1979 if (isNewGrid) 1980 { 1981 gridAlgorithm = algo->createGridAlgorithm(gridSrc, newGrid, pos) ; 1982 newGrid->setGridAlgorithm(gridAlgorithm); 1983 } 1984 else gridAlgorithm = newGrid->getGridAlgorithm() ; 1985 1986 shared_ptr<CTransformFilter> transformFilter = shared_ptr<CTransformFilter>(gridAlgorithm->createTransformFilter(gc, detectMissingValues, defaultValue)) ; 1987 outputFilter->connectOutput(transformFilter,0) ; 1988 vector<string> auxFieldId = algo->getAuxFieldId() ; // better to do that at transformation not algo ?? 1989 int i=1; 1990 for (auto& it : auxFieldId) 1991 { 1992 CField* auxField = CField::get(it) ; 1993 auxField->buildWorkflowGraph(gc) ; 1994 auxField->getInstantDataFilter()->connectOutput(transformFilter,i) ; 1995 i++ ; 1996 } 1997 outputFilter = transformFilter ; 1998 } 1999 2000 if (hasRemainTransform) 2001 { 2002 gridSrc=newGrid ; 2003 pair<shared_ptr<CFilter>, shared_ptr<CFilter> > filters = this->buildTransformationGraph(gc, isSource, gridSrc, detectMissingValues, defaultValue, newGrid) ; 2004 outputFilter->connectOutput(filters.first,0) ; 2005 outputFilter=filters.second ; 2006 } 2007 } 2008 2009 return {inputFilter,outputFilter} ; 2295 2010 } 2296 2011 CATCH_DUMP_ATTR 2297 2012 2298 CGridTransformation* CGrid::getTransformations() 2299 TRY 2300 { 2301 return transformations_; 2302 } 2303 CATCH_DUMP_ATTR 2304 2305 void CGrid::addTransGridSource(CGrid* gridSrc) 2306 TRY 2307 { 2308 if (gridSrc_.end() == gridSrc_.find(gridSrc)) 2309 gridSrc_.insert(make_pair(gridSrc,make_pair(false,""))); 2310 } 2311 CATCH_DUMP_ATTR 2312 2313 std::map<CGrid*,std::pair<bool,StdString> >& CGrid::getTransGridSource() 2314 TRY 2315 { 2316 return gridSrc_; 2317 } 2318 CATCH_DUMP_ATTR 2319 2320 /*! 2321 Complete all the necessary (and lacking) attributes of a grid 2322 This function is similar to gridTransformation but works only (till now) on generate_rectilinear_domain transformation 2323 */ 2324 void CGrid::completeGrid(CGrid* transformGridSrc) 2325 TRY 2326 { 2327 if (0 != transformGridSrc) 2328 { 2329 if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements()) 2330 { 2331 ERROR("CGrid::completeGrid(CGrid* transformGridSrc)", 2332 << "Two grids have different number of elements. " << std::endl 2333 << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl 2334 << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements()); 2335 } 2336 } 2337 2338 if (isGenerated()) return; 2339 setGenerated(); 2340 2341 CGridGenerate gridGenerate(this, transformGridSrc); 2342 gridGenerate.completeGrid(); 2343 } 2344 CATCH_DUMP_ATTR 2345 2346 bool CGrid::isGenerated() 2347 TRY 2348 { 2349 return isGenerated_; 2350 } 2351 CATCH 2352 2353 void CGrid::setGenerated() 2354 TRY 2355 { 2356 isGenerated_ = true; 2357 } 2358 CATCH_DUMP_ATTR 2359 2360 void CGrid::transformGrid(CGrid* transformGridSrc) 2361 TRY 2362 { 2363 if (!transformGridSrc) 2364 ERROR("CGrid::transformGrid(CGrid* transformGridSrc)", 2365 << "Impossible to transform grid '" << getId() << "', the source grid is null."); 2366 2367 if (isTransformed()) return; 2368 setTransformed(); 2369 if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements()) 2370 { 2371 ERROR("CGrid::transformGrid(CGrid* transformGridSrc)", 2372 << "Two grids have different number of elements. " << std::endl 2373 << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl 2374 << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements()); 2375 } 2013 2014 //**************************************************************** 2015 //**************************************************************** 2016 2017 //---------------------------------------------------------------- 2018 2019 CGrid* CGrid::duplicateSentGrid(void) 2020 { 2021 CGrid* newGrid ; 2022 string sentGridId="sent__"+getId() ; 2023 if (has(sentGridId)) newGrid = get(sentGridId) ; 2376 2024 else 2377 2025 { 2378 } 2379 2380 transformations_ = new CGridTransformation(this, transformGridSrc); 2381 transformations_->computeAll(); 2382 if (0 < transformations_->getNbAlgo()) hasTransform_ = true; 2383 2384 // Ok, now need to compute index of grid source 2385 transformGridSrc->checkMaskIndex(false); 2386 } 2387 CATCH_DUMP_ATTR 2388 2389 bool CGrid::hasTransform() 2390 TRY 2391 { 2392 if (hasTransform_) return hasTransform_; 2393 2394 std::vector<CDomain*> domList = getDomains(); 2395 std::vector<CAxis*> axisList = getAxis(); 2396 std::vector<CScalar*> scalarList = getScalars(); 2397 2398 for (int idx = 0; idx < domList.size(); ++idx) hasTransform_ |= domList[idx]->hasTransformation(); 2399 for (int idx = 0; idx < axisList.size(); ++idx) hasTransform_ |= axisList[idx]->hasTransformation(); 2400 for (int idx = 0; idx < scalarList.size(); ++idx) hasTransform_ |= scalarList[idx]->hasTransformation(); 2401 2402 return hasTransform_; 2403 } 2404 CATCH_DUMP_ATTR 2405 2406 /*! 2407 \brief Get the list of domain pointers 2408 \return list of domain pointers 2409 */ 2410 std::vector<CDomain*> CGrid::getDomains() 2411 TRY 2412 { 2413 std::vector<CDomain*> domList; 2414 if (!domList_.empty()) 2415 { 2416 for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i])); 2417 } 2418 return domList; 2419 } 2420 CATCH_DUMP_ATTR 2421 2422 /*! 2423 \brief Get the list of axis pointers 2424 \return list of axis pointers 2425 */ 2426 std::vector<CAxis*> CGrid::getAxis() 2427 TRY 2428 { 2429 std::vector<CAxis*> aList; 2430 if (!axisList_.empty()) 2431 for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i])); 2432 2433 return aList; 2434 } 2435 CATCH_DUMP_ATTR 2436 2437 /*! 2438 \brief Get the list of axis pointers 2439 \return list of axis pointers 2440 */ 2441 std::vector<CScalar*> CGrid::getScalars() 2442 TRY 2443 { 2444 std::vector<CScalar*> sList; 2445 if (!scalarList_.empty()) 2446 for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i])); 2447 2448 return sList; 2449 } 2450 CATCH_DUMP_ATTR 2451 2452 /*! 2453 \brief Get domain pointer with index 2454 \return domain pointer 2455 */ 2456 CDomain* CGrid::getDomain(int domainIndex) 2457 TRY 2458 { 2459 std::vector<CDomain*> domainListP = this->getDomains(); 2460 if (domainListP.empty()) 2461 { 2462 ERROR("CGrid::getDomain(int domainIndex)", 2463 << "No domain associated to this grid. " << std::endl 2464 << "Grid id = " << this->getId()); 2465 } 2466 2467 if (domainIndex >= domainListP.size() || (domainIndex < 0)) 2468 ERROR("CGrid::getDomain(int domainIndex)", 2469 << "Domain with the index doesn't exist " << std::endl 2470 << "Grid id = " << this->getId() << std::endl 2471 << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl); 2472 2473 return domainListP[domainIndex]; 2474 } 2475 CATCH_DUMP_ATTR 2476 2477 /*! 2478 \brief Get the axis pointer with index 2479 \return axis pointer 2480 */ 2481 CAxis* CGrid::getAxis(int axisIndex) 2482 TRY 2483 { 2484 std::vector<CAxis*> axisListP = this->getAxis(); 2485 if (axisListP.empty()) 2486 { 2487 ERROR("CGrid::getDomain(int axisIndex)", 2488 << "No axis associated to this grid. " << std::endl 2489 << "Grid id = " << this->getId()); 2490 } 2491 2492 if (axisIndex >= axisListP.size() || (axisIndex < 0)) 2493 ERROR("CGrid::getDomain(int axisIndex)", 2494 << "Domain with the index doesn't exist " << std::endl 2495 << "Grid id = " << this->getId() << std::endl 2496 << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl); 2497 2498 return axisListP[axisIndex]; 2499 } 2500 CATCH_DUMP_ATTR 2501 2502 /*! 2503 \brief Get the a scalar pointer 2504 \return scalar pointer 2505 */ 2506 CScalar* CGrid::getScalar(int scalarIndex) 2507 TRY 2508 { 2509 std::vector<CScalar*> scalarListP = this->getScalars(); 2510 if (scalarListP.empty()) 2511 { 2512 ERROR("CGrid::getScalar(int scalarIndex)", 2513 << "No scalar associated to this grid. " << std::endl 2514 << "Grid id = " << this->getId()); 2515 } 2516 2517 if (scalarIndex >= scalarListP.size() || (scalarIndex < 0)) 2518 ERROR("CGrid::getScalar(int scalarIndex)", 2519 << "Scalar with the index doesn't exist " << std::endl 2520 << "Grid id = " << this->getId() << std::endl 2521 << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl); 2522 2523 return scalarListP[scalarIndex]; 2524 } 2525 CATCH_DUMP_ATTR 2526 2527 /*! 2528 \brief Set domain(s) of a grid from a list 2529 \param[in] domains list of domains 2530 */ 2531 void CGrid::setDomainList(const std::vector<CDomain*> domains) 2532 TRY 2533 { 2534 if (isDomListSet) return; 2535 std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 2536 if (!domains.empty() && domList.empty()) 2537 { 2538 for (int i = 0; i < domains.size(); ++i) 2539 this->getVirtualDomainGroup()->addChild(domains[i]); 2540 domList = this->getVirtualDomainGroup()->getAllChildren(); 2541 } 2542 2543 if (!domList.empty()) 2544 { 2545 int sizeDom = domList.size(); 2546 domList_.resize(sizeDom); 2547 for (int i = 0; i < sizeDom; ++i) 2548 { 2549 domList_[i] = domList[i]->getId(); 2550 } 2551 isDomListSet = true; 2552 } 2553 } 2554 CATCH_DUMP_ATTR 2555 2556 /*! 2557 \brief Set axis(s) of a grid from a list 2558 \param[in] axis list of axis 2559 */ 2560 void CGrid::setAxisList(const std::vector<CAxis*> axis) 2561 TRY 2562 { 2563 if (isAxisListSet) return; 2564 std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 2565 if (!axis.empty() && aList.empty()) 2566 { 2567 for (int i = 0; i < axis.size(); ++i) 2568 this->getVirtualAxisGroup()->addChild(axis[i]); 2569 aList = this->getVirtualAxisGroup()->getAllChildren(); 2570 } 2571 2572 if (!aList.empty()) 2573 { 2574 int sizeAxis = aList.size(); 2575 axisList_.resize(sizeAxis); 2576 for (int i = 0; i < sizeAxis; ++i) 2577 { 2578 axisList_[i] = aList[i]->getId(); 2579 } 2580 isAxisListSet = true; 2581 } 2582 } 2583 CATCH_DUMP_ATTR 2584 2585 /*! 2586 \brief Set scalar(s) of a grid from a list 2587 \param[in] scalars list of scalars 2588 */ 2589 void CGrid::setScalarList(const std::vector<CScalar*> scalars) 2590 TRY 2591 { 2592 if (isScalarListSet) return; 2593 std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 2594 if (!scalars.empty() && sList.empty()) 2595 { 2596 for (int i = 0; i < scalars.size(); ++i) 2597 this->getVirtualScalarGroup()->addChild(scalars[i]); 2598 sList = this->getVirtualScalarGroup()->getAllChildren(); 2599 } 2600 2601 if (!sList.empty()) 2602 { 2603 int sizeScalar = sList.size(); 2604 scalarList_.resize(sizeScalar); 2605 for (int i = 0; i < sizeScalar; ++i) 2606 { 2607 scalarList_[i] = sList[i]->getId(); 2608 } 2609 isScalarListSet = true; 2610 } 2611 } 2612 CATCH_DUMP_ATTR 2613 2614 /*! 2615 \brief Get list of id of domains 2616 \return id list of domains 2617 */ 2618 std::vector<StdString> CGrid::getDomainList() 2619 TRY 2620 { 2621 setDomainList(); 2622 return domList_; 2623 } 2624 CATCH 2625 2626 /*! 2627 \brief Get list of id of axis 2628 \return id list of axis 2629 */ 2630 std::vector<StdString> CGrid::getAxisList() 2631 TRY 2632 { 2633 setAxisList(); 2634 return axisList_; 2635 } 2636 CATCH 2637 2638 /*! 2639 \brief Get list of id of scalar 2640 \return id list of scalar 2641 */ 2642 std::vector<StdString> CGrid::getScalarList() 2643 TRY 2644 { 2645 setScalarList(); 2646 return scalarList_; 2647 } 2648 CATCH 2649 2650 /*! 2651 Send all attributes of domains from client to server 2652 */ 2653 void CGrid::sendAllDomains() 2654 TRY 2655 { 2656 std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 2657 int dSize = domList.size(); 2658 for (int i = 0; i < dSize; ++i) 2659 { 2660 sendAddDomain(domList[i]->getId()); 2661 domList[i]->sendAllAttributesToServer(); 2662 } 2663 } 2664 CATCH_DUMP_ATTR 2665 2666 /*! 2667 Send all attributes of axis from client to server 2668 */ 2669 void CGrid::sendAllAxis() 2670 TRY 2671 { 2672 std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 2673 int aSize = aList.size(); 2674 2675 for (int i = 0; i < aSize; ++i) 2676 { 2677 sendAddAxis(aList[i]->getId()); 2678 aList[i]->sendAllAttributesToServer(); 2679 } 2680 } 2681 CATCH_DUMP_ATTR 2682 2683 /*! 2684 Send all attributes of scalars from client to server 2685 */ 2686 void CGrid::sendAllScalars() 2687 TRY 2688 { 2689 std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 2690 int sSize = sList.size(); 2691 2692 for (int i = 0; i < sSize; ++i) 2693 { 2694 sendAddScalar(sList[i]->getId()); 2695 sList[i]->sendAllAttributesToServer(); 2696 } 2697 } 2698 CATCH_DUMP_ATTR 2026 newGrid = CGrid::create(sentGridId) ; 2027 for(auto element : elements_) 2028 { 2029 if (element.type==TYPE_DOMAIN) 2030 { 2031 CDomain* domain = CDomain::create(); 2032 domain->duplicateAttributes(element.domain) ; 2033 domain->name = element.domain->getId() ; 2034 newGrid->addDomain(domain->getId()) ; 2035 } 2036 else if (element.type==TYPE_AXIS) 2037 { 2038 CAxis* axis = CAxis::create(); 2039 axis->duplicateAttributes(element.axis) ; 2040 axis->name = element.axis->getId() ; 2041 newGrid->addAxis(axis->getId()) ; 2042 } 2043 else if (element.type==TYPE_SCALAR) 2044 { 2045 CScalar* scalar = CScalar::create(); 2046 scalar->duplicateAttributes(element.scalar) ; 2047 scalar->name = element.scalar->getId() ; 2048 newGrid->addScalar(scalar->getId()) ; 2049 } 2050 } 2051 newGrid->checkElementsAttributes() ; 2052 } 2053 return newGrid ; 2054 } 2055 2699 2056 2700 2057 void CGrid::setContextClient(CContextClient* contextClient) … … 2706 2063 clientsSet.insert(contextClient); 2707 2064 } 2708 for ( int i=0; i<this->getDomains().size(); i++)2709 this->getDomains()[i]->setContextClient(contextClient);2710 for ( int i=0; i<this->getAxis().size(); i++)2711 this->getAxis()[i]->setContextClient(contextClient);2065 for (auto domain : getDomains()) domain->setContextClient(contextClient); 2066 for (auto axis : getAxis()) axis->setContextClient(contextClient); 2067 for (auto scalar : getScalars()) scalar->setContextClient(contextClient); 2068 2712 2069 } 2713 2070 CATCH_DUMP_ATTR 2714 2071 2715 /*! 2716 Parse a grid, for now, it contains only domain, axis and scalar 2717 */ 2718 void CGrid::parse(xml::CXMLNode& node) 2719 TRY 2720 { 2721 SuperClass::parse(node); 2722 2723 if (node.goToChildElement()) 2724 { 2725 StdString domainName("domain"); 2726 StdString axisName("axis"); 2727 StdString scalarName("scalar"); 2728 do 2729 { 2730 if (node.getElementName() == domainName) { 2731 order_.push_back(2); 2732 this->getVirtualDomainGroup()->parseChild(node); 2733 } 2734 if (node.getElementName() == axisName) { 2735 order_.push_back(1); 2736 this->getVirtualAxisGroup()->parseChild(node); 2737 } 2738 if (node.getElementName() == scalarName) { 2739 order_.push_back(0); 2740 this->getVirtualScalarGroup()->parseChild(node); 2741 } 2742 } while (node.goToNextElement()); 2743 node.goToParentElement(); 2744 } 2745 2746 if (!order_.empty()) 2747 { 2748 int sizeOrd = order_.size(); 2749 axis_domain_order.resize(sizeOrd); 2750 for (int i = 0; i < sizeOrd; ++i) 2751 { 2752 axis_domain_order(i) = order_[i]; 2753 } 2754 } 2755 2756 setDomainList(); 2757 setAxisList(); 2758 setScalarList(); 2759 } 2760 CATCH_DUMP_ATTR 2761 2072 2073 void CGrid::computeGridLocalElements() 2074 { 2075 std::vector<CDomain*> domainList = this->getDomains(); 2076 std::vector<CAxis*> axisList = this->getAxis(); 2077 std::vector<CScalar*> scalarList = this->getScalars(); 2078 auto domain=domainList.begin() ; 2079 auto axis=axisList.begin() ; 2080 auto scalar=scalarList.begin() ; 2081 vector<CLocalElement*> elements; 2082 for(auto order : order_) 2083 { 2084 if (order==2) 2085 { 2086 elements.push_back((*domain)->getLocalElement()); 2087 domain++ ; 2088 } 2089 else if (order==1) 2090 { 2091 elements.push_back((*axis)->getLocalElement()); 2092 axis++ ; 2093 } 2094 else if (order==0) 2095 { 2096 elements.push_back((*scalar)->getLocalElement()); 2097 scalar++ ; 2098 } 2099 } 2100 if (hasMask()) 2101 { 2102 vector<bool> mask(getMask().getVector()) ; 2103 gridLocalElements_ = new CGridLocalElements(elements, mask) ; 2104 } 2105 else gridLocalElements_ = new CGridLocalElements(elements) ; 2106 } 2107 2108 void CGrid::computeModelToWorkflowConnector(void) 2109 { 2110 modelToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::MODEL,CElementView::WORKFLOW,true) ; 2111 } 2112 2113 void CGrid::computeWorkflowToFullConnector(void) 2114 { 2115 workflowToFullConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::FULL) ; 2116 } 2117 2118 void CGrid::computeWorkflowToModelConnector(void) 2119 { 2120 workflowToModelConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::MODEL,true) ; 2121 } 2122 2123 void CGrid::computeFullToWorkflowConnector(void) 2124 { 2125 fullToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::FULL,CElementView::WORKFLOW) ; 2126 } 2127 2128 void CGrid::computeServerFromClientConnector(void) 2129 { 2130 vector<CGathererConnector*> connectors ; 2131 for(auto& element : getElements()) 2132 { 2133 if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ; 2134 else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ; 2135 else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ; 2136 } 2137 serverFromClientConnector_ = new CGridGathererConnector(connectors) ; 2138 } 2139 2140 void CGrid::computeServerToClientConnector(void) 2141 { 2142 vector<CScattererConnector*> connectors ; 2143 for(auto& element : getElements()) 2144 { 2145 if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerToClientConnector()) ; 2146 else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerToClientConnector()) ; 2147 else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerToClientConnector()) ; 2148 } 2149 serverToClientConnector_ = new CGridScattererConnector(connectors) ; 2150 } 2151 2152 void CGrid::computeClientFromClientConnector(void) 2153 { 2154 vector<CGathererConnector*> connectors ; 2155 for(auto& element : getElements()) 2156 { 2157 if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ; 2158 else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ; 2159 else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ; 2160 } 2161 clientFromClientConnector_ = new CGridGathererConnector(connectors) ; 2162 } 2163 2164 2762 2165 } // namespace xios
Note: See TracChangeset
for help on using the changeset viewer.