Changeset 1637
- Timestamp:
- 01/14/19 13:33:48 (6 years ago)
- Location:
- XIOS/trunk/src
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/distribution_client.cpp
r1593 r1637 15 15 , axisDomainOrder_() 16 16 , nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_() 17 , dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_() , domainMasks_(), axisMasks_()17 , dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_() 18 18 , gridMask_(), indexMap_() 19 19 , isDataDistributed_(true), axisNum_(0), domainNum_(0) … … 36 36 GlobalLocalMap void2 ; 37 37 std::vector<int> void3 ; 38 std::vector< int> void4 ;38 std::vector<bool> void4 ; 39 39 40 40 globalLocalDataSendToServerMap_.swap(void1) ; … … 61 61 // Then check mask of grid 62 62 int gridDim = domList.size() * 2 + axisList.size(); 63 grid->checkMask();64 63 switch (gridDim) { 65 64 case 0: … … 117 116 axisDomainOrder_ = axisDomainOrder; 118 117 119 // Each domain or axis has its mask, of course120 domainMasks_.resize(domainNum_);121 for (int i = 0; i < domainNum_;++i)122 {123 domainMasks_[i].resize(domList[i]->domainMask.numElements());124 domainMasks_[i] = domList[i]->domainMask;125 }126 127 axisMasks_.resize(axisNum_);128 for (int i = 0; i < axisNum_; ++i)129 {130 axisMasks_[i].resize(axisList[i]->mask.numElements());131 axisMasks_[i] = axisList[i]->mask;132 }133 134 118 // Because domain and axis can be in any order (axis1, domain1, axis2, axis3, ) 135 119 // their position should be specified. In axisDomainOrder, domain == true, axis == false … … 282 266 283 267 if ((iIdx >= nBeginLocal_[indexMap_[i]]) && (iIdx < nLocal_[indexMap_[i]]) && 284 (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]) && 285 (domainMasks_[idxDomain](iIdx + jIdx*nLocal_[indexMap_[i]]))) 268 (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1])) 286 269 { 287 270 ++count; … … 325 308 elementIndexData_[i].resize(dataNIndex_[i]); 326 309 elementIndexData_[i] = false; 327 int iIdx = 0, count = 0 , localIndex = 0;310 int iIdx = 0, count = 0; 328 311 for (int j = 0; j < dataNIndex_[i]; ++j) 329 312 { 330 313 iIdx = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]); 331 314 if ((iIdx >= nBeginLocal_[indexMap_[i]]) && 332 (iIdx < nLocal_[indexMap_[i]]) && (axisMasks_[idxAxis](iIdx)))315 (iIdx < nLocal_[indexMap_[i]]) )//&& (axisMasks_[idxAxis](iIdx))) 333 316 { 334 317 ++count; … … 413 396 414 397 for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i]; 415 while (idx < ssize) 416 { 417 for (int i = 0; i < numElement_-1; ++i) 418 { 419 if (idxLoop[i] == eachElementSize[i]) 420 { 421 idxLoop[i] = 0; 422 ++idxLoop[i+1]; 423 } 424 } 425 426 // Find out outer index 427 // Depending the inner-most element is axis or domain, 428 // The outer loop index begins correspondingly at one (1) or zero (0) 429 for (int i = 1; i < numElement_; ++i) 430 { 431 currentIndex[i] = elementLocalIndex_[i](idxLoop[i]); 432 } 433 434 // Inner most index 435 for (int i = 0; i < innerLoopSize; ++i) 436 { 437 int gridMaskIndex = 0; 438 currentIndex[0] = elementLocalIndex_[0](i); 439 440 // If defined, iterate on grid mask 441 if (!gridMask_.isEmpty()) 442 { 443 for (int k = 0; k < this->numElement_; ++k) 444 { 445 gridMaskIndex += (currentIndex[k])*elementNLocal_[k]; 446 } 447 if (gridMask_(gridMaskIndex)) ++indexLocalDataOnClientCount; 448 } 449 // If grid mask is not defined, iterate on elements' mask 450 else 451 { 452 bool maskTmp = true; 453 int idxDomain = 0, idxAxis = 0; 454 for (int elem = 0; elem < numElement_; ++elem) 455 { 456 if (2 == axisDomainOrder_(elem)) 457 { 458 maskTmp = maskTmp && domainMasks_[idxDomain](currentIndex[elem]); 459 ++idxDomain; 460 } 461 else if (1 == axisDomainOrder_(elem)) 462 { 463 maskTmp = maskTmp && axisMasks_[idxAxis](currentIndex[elem]); 464 ++idxAxis; 465 } 466 } 467 if (maskTmp) ++indexLocalDataOnClientCount; 468 } 469 470 } 471 idxLoop[0] += innerLoopSize; 472 idx += innerLoopSize; 473 } 474 475 // Now allocate these arrays 476 localDataIndex_.resize(indexLocalDataOnClientCount); 477 localMaskIndex_.resize(indexLocalDataOnClientCount); 478 localMaskedDataIndex_.resize(indexLocalDataOnClientCount); 479 globalDataIndex_.rehash(std::ceil(indexLocalDataOnClientCount/globalDataIndex_.max_load_factor())); 480 globalLocalDataSendToServerMap_.rehash(std::ceil(indexLocalDataOnClientCount/globalLocalDataSendToServerMap_.max_load_factor())); 398 399 localDataIndex_.resize(ssize); 400 if (!gridMask_.isEmpty()) localMaskIndex_.resize(ssize); 401 localMaskedDataIndex_.resize(ssize); 402 globalDataIndex_.rehash(std::ceil(ssize/globalDataIndex_.max_load_factor())); 403 globalLocalDataSendToServerMap_.rehash(std::ceil(ssize/globalLocalDataSendToServerMap_.max_load_factor())); 404 481 405 482 406 // We need to loop with data index … … 535 459 if (isCurrentIndexDataCorrect) 536 460 { 537 int gridMaskIndex = 0; 538 for (int k = 0; k < this->numElement_; ++k) 461 bool maskTmp = true; 462 bool maskGridTmp = true; 463 size_t globalIndex = 0; 464 for (int k = 0; k < numElement_; ++k) 539 465 { 540 g ridMaskIndex += (currentIndex[k])*elementNLocal_[k];466 globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k]; 541 467 } 542 543 bool maskTmp = true; 544 // If defined, apply grid mask 545 if (!gridMask_.isEmpty()) 468 globalDataIndex_[globalIndex] = indexLocalDataOnClientCount; 469 localDataIndex_[indexLocalDataOnClientCount] = countLocalData; 470 globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount; 471 localMaskedDataIndex_[indexLocalDataOnClientCount] = indexLocalDataOnClientCount; 472 473 // Grid mask: unmasked values will be replaces by NaN and then all values will be sent 474 if (!gridMask_.isEmpty()) 546 475 { 547 maskTmp = gridMask_(gridMaskIndex); 476 int gridMaskIndex = 0; 477 for (int k = 0; k < this->numElement_; ++k) 478 { 479 gridMaskIndex += (currentIndex[k])*elementNLocal_[k]; 480 } 481 maskGridTmp = gridMask_(gridMaskIndex); 482 if (maskGridTmp) 483 localMaskIndex_[indexLocalDataOnClientCount] = true; 484 else 485 localMaskIndex_[indexLocalDataOnClientCount] = false; 548 486 } 549 // If grid mask is not defined, apply elements' mask 550 else 551 { 552 int idxDomain = 0, idxAxis = 0; 553 for (int elem = 0; elem < numElement_; ++elem) 554 { 555 if (2 == axisDomainOrder_(elem)) 556 { 557 maskTmp = maskTmp && domainMasks_[idxDomain](currentIndex[elem]); 558 ++idxDomain; 559 } 560 else if (1 == axisDomainOrder_(elem)) 561 { 562 maskTmp = maskTmp && axisMasks_[idxAxis](currentIndex[elem]); 563 ++idxAxis; 564 } 565 } 566 } 567 568 if (maskTmp) 569 { 570 size_t globalIndex = 0; 571 for (int k = 0; k < numElement_; ++k) 572 { 573 globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k]; 574 } 575 globalDataIndex_[globalIndex] = indexLocalDataOnClientCount; 576 localDataIndex_[indexLocalDataOnClientCount] = countLocalData; 577 globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount; 578 localMaskIndex_[indexLocalDataOnClientCount] = gridMaskIndex; 579 localMaskedDataIndex_[indexLocalDataOnClientCount] = indexLocalDataOnClientCount; 580 ++indexLocalDataOnClientCount; 581 } 487 488 ++indexLocalDataOnClientCount; 489 582 490 } 583 491 ++countLocalData; … … 586 494 } 587 495 else countLocalData+=innerLoopSize ; 588 496 589 497 idxLoop[0] += innerLoopSize; 590 498 idx += innerLoopSize; … … 614 522 const int& dataDim, const int& ni, int& j) 615 523 { 524 int i; 616 525 int tempI = dataIIndex + dataIBegin, 617 526 tempJ = (dataJIndex + dataJBegin); 618 527 if (ni == 0) 619 528 { 620 i nt i = 0;621 j = 0;529 i = -1; 530 j = -1; 622 531 return i; 623 532 } 624 int i = (dataDim == 1) ? (tempI) % ni 625 : (tempI) ; 626 j = (dataDim == 1) ? (tempI) / ni 627 : (tempJ) ; 628 533 if ((tempI < 0) || (tempJ < 0)) 534 { 535 i = -1; 536 j = -1; 537 return i; 538 } 539 else 540 { 541 i = (dataDim == 1) ? (tempI) % ni : (tempI) ; 542 j = (dataDim == 1) ? (tempI) / ni : (tempJ) ; 543 } 629 544 return i; 630 545 } … … 643 558 return -1; 644 559 } 645 int tempI = dataIndex + dataBegin;560 int tempI = dataIndex; 646 561 if ((tempI < 0) || (tempI > ni)) 647 562 return -1; … … 677 592 Return local mask index of client 678 593 */ 679 const std::vector< int>& CDistributionClient::getLocalMaskIndexOnClient()594 const std::vector<bool>& CDistributionClient::getLocalMaskIndexOnClient() 680 595 { 681 596 if (!isComputed_) createGlobalIndexSendToServer(); -
XIOS/trunk/src/distribution_client.hpp
r1562 r1637 33 33 34 34 public: 35 /** Default constructor */ 35 /** Default constructor */ 36 36 CDistributionClient(int rank, CGrid* grid); 37 37 … … 44 44 GlobalLocalDataMap& getGlobalLocalDataSendToServer(); 45 45 GlobalLocalDataMap& getGlobalDataIndexOnClient(); 46 const std::vector< int>& getLocalMaskIndexOnClient();46 const std::vector<bool>& getLocalMaskIndexOnClient(); 47 47 const std::vector<int>& getLocalMaskedDataIndexOnClient(); 48 48 … … 83 83 GlobalLocalDataMap globalLocalDataSendToServerMap_; 84 84 GlobalLocalDataMap globalDataIndex_; 85 86 /*! Array holding masked data indexes. 87 * It includes: 88 * masking on data (data_i/j_index or data_ni/nj and data_ibegin) 89 * masking on grid elements (domains, axes or scalars) 90 * It DOES NOT include grid mask. 91 * The array size defines the data size entering the workflow. It is used by source filter of client or server1. 92 */ 85 93 std::vector<int> localDataIndex_; 86 std::vector<int> localMaskIndex_; 94 95 /*! Array holding grid mask. If grid mask is not defined, its size is zero. 96 * It is used by source filter of client for replacing unmasked data by NaN. 97 */ 98 std::vector<bool> localMaskIndex_; 99 87 100 std::vector<int> localMaskedDataIndex_; 88 101 … … 104 117 std::vector<CArray<int,1> > dataIndex_; //!< Data index 105 118 std::vector<CArray<int,1> > infoIndex_; //!< i_index, j_index 106 107 std::vector<CArray<bool,1> > domainMasks_; //!< Domain mask108 std::vector<CArray<bool,1> > axisMasks_; //!< Axis mask109 119 110 120 std::vector<int> indexMap_; //!< Mapping element index to dimension index -
XIOS/trunk/src/filter/file_writer_filter.cpp
r1474 r1637 17 17 void CFileWriterFilter::onInputReady(std::vector<CDataPacketPtr> data) 18 18 { 19 const bool detectMissingValue = ( !field->detect_missing_value.isEmpty()20 && !field->default_value.isEmpty()21 && field->detect_missing_value == true);19 const bool detectMissingValue = ( !field->default_value.isEmpty() && 20 ( (!field->detect_missing_value.isEmpty() || field->detect_missing_value == true) 21 || field->hasGridMask()) ); 22 22 23 23 CArray<double, 1> dataArray = (detectMissingValue) ? data[0]->data.copy() : data[0]->data; -
XIOS/trunk/src/filter/source_filter.cpp
r1250 r1637 7 7 namespace xios 8 8 { 9 CSourceFilter::CSourceFilter(CGarbageCollector& gc, CGrid* grid, bool compression, 9 CSourceFilter::CSourceFilter(CGarbageCollector& gc, CGrid* grid, 10 bool compression /*= true*/, bool mask /*= false*/, 10 11 const CDuration offset /*= NoneDu*/, bool manualTrigger /*= false*/, 11 12 bool hasMissingValue /*= false*/, … … 14 15 , grid(grid) 15 16 , compression(compression) 17 , mask(mask) 16 18 , offset(offset) 17 19 , hasMissingValue(hasMissingValue), defaultValue(defaultValue) … … 40 42 } 41 43 else 42 grid->inputField(data, packet->data); 43 44 45 46 // if (compression) grid->inputField(data, packet->data) ; 47 // else 48 // { 49 // // just make a flat copy 50 // CArray<double, N> data_tmp(data.copy()) ; // supress const attribute 51 // CArray<double,1> dataTmp2(data_tmp.dataFirst(),shape(data.numElements()),neverDeleteData) ; 52 // packet->data = dataTmp2 ; 53 // } 44 { 45 if (mask) 46 grid->maskField(data, packet->data); 47 else 48 grid->inputField(data, packet->data); 49 } 54 50 // Convert missing values to NaN 55 51 if (hasMissingValue) -
XIOS/trunk/src/filter/source_filter.hpp
r1241 r1637 21 21 * \param gc the garbage collector associated with this filter 22 22 * \param grid the grid to which the data is attached 23 * \param compression 24 * \param mask 23 25 * \param offset the offset applied to the timestamp of all packets 24 26 * \param manualTrigger whether the output should be triggered manually … … 27 29 */ 28 30 CSourceFilter(CGarbageCollector& gc, CGrid* grid, 29 bool compression=true, 31 bool compression = true, 32 bool mask = false, 30 33 const CDuration offset = NoneDu, bool manualTrigger = false, 31 34 bool hasMissingValue = false, … … 61 64 62 65 private: 63 CGrid* grid; //!< The grid attached to the data the filter can accept64 const CDuration offset; //!< The offset applied to the timestamp of all packets66 CGrid* grid; //!< The grid attached to the data the filter can accept 67 const CDuration offset; //!< The offset applied to the timestamp of all packets 65 68 const bool hasMissingValue; 66 69 const double defaultValue; 67 const bool compression ; //!< indicate if the data need to be compressed : on client size : true, on server side : false 70 const bool compression ; //!< indicates if data need to be compressed : on client side : true, on server side : false 71 const bool mask ; //!< indicates whether grid mask should be applied (true for clients, false for servers) 68 72 }; // class CSourceFilter 69 73 } // namespace xios -
XIOS/trunk/src/filter/spatial_transform_filter.cpp
r1542 r1637 68 68 onOutputReady(outputPacket); 69 69 } 70 71 72 73 74 70 75 71 CSpatialTemporalFilter::CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, CGridTransformation* gridTransformation, double outputValue, size_t inputSlotsCount) … … 201 197 const std::list<CGridTransformation::RecvIndexGridDestinationMap>& listLocalIndexToReceive = gridTransformation->getLocalIndexToReceiveOnGridDest(); 202 198 const std::list<size_t>& listNbLocalIndexToReceive = gridTransformation->getNbLocalIndexToReceiveOnGridDest(); 203 const std::list<std::vector<bool> >& listLocalIndexMaskOnDest = gridTransformation->getLocalMaskIndexOnGridDest();204 199 const std::vector<CGenericAlgorithmTransformation*>& listAlgos = gridTransformation->getAlgos(); 205 200 … … 210 205 std::list<CGridTransformation::RecvIndexGridDestinationMap>::const_iterator itListRecv = listLocalIndexToReceive.begin(); 211 206 std::list<size_t>::const_iterator itNbListRecv = listNbLocalIndexToReceive.begin(); 212 std::list<std::vector<bool> >::const_iterator itLocalMaskIndexOnDest = listLocalIndexMaskOnDest.begin();213 207 std::vector<CGenericAlgorithmTransformation*>::const_iterator itAlgo = listAlgos.begin(); 214 208 215 for (; itListSend != iteListSend; ++itListSend, ++itListRecv, ++itNbListRecv, ++it LocalMaskIndexOnDest, ++itAlgo)209 for (; itListSend != iteListSend; ++itListSend, ++itListRecv, ++itNbListRecv, ++itAlgo) 216 210 { 217 211 CArray<double,1> dataCurrentSrc(dataCurrentDest); … … 266 260 267 261 dataCurrentDest.resize(*itNbListRecv); 268 const std::vector<bool>& localMaskDest = *itLocalMaskIndexOnDest; 269 for (int i = 0; i < localMaskDest.size(); ++i) 270 if (localMaskDest[i]) dataCurrentDest(i) = 0.0; 271 else dataCurrentDest(i) = defaultValue; 262 dataCurrentDest = 0.0; 272 263 273 264 std::vector<bool> localInitFlag(dataCurrentDest.numElements(), true); -
XIOS/trunk/src/io/nc4_data_output.cpp
r1622 r1637 155 155 */ 156 156 157 CArray< size_t, 1>& indexToWrite = domain->localIndexToWriteOnServer;157 CArray<int, 1>& indexToWrite = domain->localIndexToWriteOnServer; 158 158 int nbWritten = indexToWrite.numElements(); 159 159 CArray<double,1> writtenLat, writtenLon; … … 167 167 for (int idx = 0; idx < nbWritten; ++idx) 168 168 { 169 if (idx < domain->latvalue.numElements())170 171 writtenLat(idx) = domain->latvalue(indexToWrite(idx));172 writtenLon(idx) = domain->lonvalue(indexToWrite(idx));173 174 175 176 writtenLat(idx) = 0.;177 writtenLon(idx) = 0.;178 169 if (indexToWrite(idx) < 0) 170 { 171 writtenLat(idx) = -1.; // hole 172 writtenLon(idx) = -1.; 173 } 174 else 175 { 176 writtenLat(idx) = domain->latvalue(indexToWrite(idx)); 177 writtenLon(idx) = domain->lonvalue(indexToWrite(idx)); 178 } 179 179 } 180 181 180 182 181 if (domain->hasBounds) … … 190 189 for (int nv = 0; nv < nvertex; ++nv) 191 190 { 192 if (idx < boundslat.columns()) 193 { 191 if (indexToWrite(idx) < 0) 192 { 193 writtenBndsLat(nv, idx) = -1.; // hole 194 writtenBndsLon(nv, idx) = -1.; 195 } 196 else 197 { 194 198 writtenBndsLat(nv, idx) = boundslat(nv, int(indexToWrite(idx))); 195 199 writtenBndsLon(nv, idx) = boundslon(nv, int(indexToWrite(idx))); 196 } 197 else 198 { 199 writtenBndsLat(nv, idx) = 0.; 200 writtenBndsLon(nv, idx) = 0.; 201 } 200 } 202 201 } 203 202 } … … 209 208 for (int idx = 0; idx < nbWritten; ++idx) 210 209 { 211 if (i dx < domain->areavalue.numElements())212 writtenArea(idx) = domain->areavalue(indexToWrite(idx));210 if (indexToWrite(idx) < 0) 211 writtenArea(idx) = -1.; 213 212 else 214 writtenArea(idx) = 0.;213 writtenArea(idx) = domain->areavalue(indexToWrite(idx)); 215 214 } 216 215 } … … 427 426 std::vector<StdSize> start(2) ; 428 427 std::vector<StdSize> count(2) ; 429 if (domain->isEmpty()) 430 { 431 start[0]=0 ; start[1]=0 ; 432 count[0]=0 ; count[1]=0 ; 433 } 434 else 428 // Comment out: it is not working for a hole 429 // if (domain->isEmpty()) 430 // { 431 // start[0]=0 ; start[1]=0 ; 432 // count[0]=0 ; count[1]=0 ; 433 // } 434 // else 435 435 { 436 436 start[1]=domain->ibegin; … … 877 877 case (MULTI_FILE) : 878 878 { 879 ERROR("CNc4DataOutput::writeDomain(domain)", 880 << "[ type = multiple_file ]" 881 << " is not yet implemented for UGRID files !"); 879 882 break; 880 883 } … … 942 945 int nvertex = (domain->nvertex.isEmpty()) ? 0 : domain->nvertex; 943 946 944 CArray< size_t, 1>& indexToWrite = domain->localIndexToWriteOnServer;947 CArray<int, 1>& indexToWrite = domain->localIndexToWriteOnServer; 945 948 int nbWritten = indexToWrite.numElements(); 946 949 CArray<double,1> writtenLat, writtenLon; … … 954 957 for (int idx = 0; idx < nbWritten; ++idx) 955 958 { 956 if (i dx < domain->latvalue.numElements())957 {958 writtenLat(idx) = domain->latvalue(indexToWrite(idx));959 writtenLon(idx) = domain->lonvalue(indexToWrite(idx));960 }961 else962 {963 writtenLat(idx) = 0.;964 writtenLon(idx) = 0.;965 }959 if (indexToWrite(idx) < 0) 960 { 961 writtenLat(idx) = -1.; 962 writtenLon(idx) = -1.; 963 } 964 else 965 { 966 writtenLat(idx) = domain->latvalue(indexToWrite(idx)); 967 writtenLon(idx) = domain->lonvalue(indexToWrite(idx)); 968 } 966 969 } 967 970 } … … 978 981 for (int nv = 0; nv < nvertex; ++nv) 979 982 { 980 if (idx < boundslat.columns()) 983 if (indexToWrite(idx) < 0) 984 { 985 writtenBndsLat(nv, idx) = -1.; 986 writtenBndsLon(nv, idx) = -1.; 987 } 988 else 981 989 { 982 990 writtenBndsLat(nv, idx) = boundslat(nv, int(indexToWrite(idx))); 983 991 writtenBndsLon(nv, idx) = boundslon(nv, int(indexToWrite(idx))); 984 }985 else986 {987 writtenBndsLat(nv, idx) = 0.;988 writtenBndsLon(nv, idx) = 0.;989 992 } 990 993 } … … 997 1000 for (int idx = 0; idx < nbWritten; ++idx) 998 1001 { 999 if (idx < domain->areavalue.numElements())1000 writtenArea(idx) = domain->areavalue(indexToWrite(idx));1001 1002 writtenArea(idx) = 0.;1002 if (indexToWrite(idx) < 0) 1003 writtenArea(idx) = -1.; 1004 else 1005 writtenArea(idx) = domain->areavalue(indexToWrite(idx)); 1003 1006 } 1004 1007 } … … 1277 1280 SuperClassWriter::definition_end(); 1278 1281 1279 CArray< size_t, 1>& indexToWrite = axis->localIndexToWriteOnServer;1282 CArray<int, 1>& indexToWrite = axis->localIndexToWriteOnServer; 1280 1283 int nbWritten = indexToWrite.numElements(); 1281 1284 CArray<double,1> axis_value(indexToWrite.numElements()); … … 1284 1287 for (int i = 0; i < nbWritten; i++) 1285 1288 { 1286 if (i < axis->value.numElements()) 1289 if (indexToWrite(i) < 0) 1290 axis_value(i) = -1; // Some value in case of a hole 1291 else 1287 1292 axis_value(i) = axis->value(indexToWrite(i)); 1288 else1289 axis_value(i) = 0.;1290 1293 } 1291 1294 } … … 1297 1300 for (int i = 0; i < nbWritten; i++) 1298 1301 { 1299 if (i < axis->label.numElements()) 1302 if (indexToWrite(i) < 0) 1303 axis_label(i) = boost::lexical_cast<string>(-1); // Some value in case of a hole 1304 else 1300 1305 axis_label(i) = axis->label(indexToWrite(i)); 1301 else1302 axis_label(i) = boost::lexical_cast<string>(0); // Write 0 as a label1303 1306 } 1304 1307 } … … 1318 1321 for (int i = 0; i < nbWritten; ++i) 1319 1322 { 1320 if (i < axis->bounds.columns()) 1323 if (indexToWrite(i) < 0) 1324 { 1325 axis_bounds(0, i) = -1.; // Some value in case of a hole 1326 axis_bounds(1, i) = -1.; 1327 } 1328 else 1321 1329 { 1322 1330 axis_bounds(0, i) = axis->bounds(0, int(indexToWrite(i))); 1323 1331 axis_bounds(1, i) = axis->bounds(1, int(indexToWrite(i))); 1324 }1325 else1326 {1327 axis_bounds(0, i) = 0.;1328 axis_bounds(1, i) = 0.;1329 1330 1332 } 1331 1333 } … … 1358 1360 for (int i = 0; i < nbWritten; ++i) 1359 1361 { 1360 if (i < axis->bounds.columns()) 1362 if (indexToWrite(i) < 0) 1363 { 1364 axis_bounds(0, i) = -1.; 1365 axis_bounds(1, i) = -1.; 1366 } 1367 else 1361 1368 { 1362 1369 axis_bounds(0, i) = axis->bounds(0, int(indexToWrite(i))); 1363 1370 axis_bounds(1, i) = axis->bounds(1, int(indexToWrite(i))); 1364 }1365 else1366 {1367 axis_bounds(0, i) = 0.;1368 axis_bounds(1, i) = 0.;1369 1371 } 1370 1372 } -
XIOS/trunk/src/node/axis.cpp
r1622 r1637 274 274 TRY 275 275 { 276 if (this->n_glo.isEmpty()) 276 CContext* context=CContext::getCurrent(); 277 278 if (this->n_glo.isEmpty()) 277 279 ERROR("CAxis::checkAttributes(void)", 278 280 << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " … … 314 316 } 315 317 316 // Remove this check because it doesn't make sense in case of a hole or overlapping axes317 318 if (!this->value.isEmpty()) 318 319 { 319 // StdSize true_size = value.numElements(); 320 // if (this->n.getValue() != true_size) 321 // ERROR("CAxis::checkAttributes(void)", 322 // << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 323 // << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 320 // Avoid this check at writing because it fails in case of a hole 321 if (context->hasClient) 322 { 323 StdSize true_size = value.numElements(); 324 if (this->n.getValue() != true_size) 325 ERROR("CAxis::checkAttributes(void)", 326 << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 327 << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size 328 << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 329 } 324 330 this->hasValue = true; 325 331 } … … 327 333 this->checkBounds(); 328 334 329 CContext* context=CContext::getCurrent();330 335 if (context->hasClient) 331 336 { 337 this->checkMask(); 332 338 this->checkData(); 333 this->checkMask();334 339 this->checkLabel(); 335 340 } … … 338 343 339 344 /*! 340 Check the validity of data and fill in values if any.345 Check the validity of data, fill in values if any, and apply mask. 341 346 */ 342 347 void CAxis::checkData() … … 359 364 { 360 365 data_index.resize(data_n); 361 for (int i = 0; i < data_n; ++i) data_index(i) = i; 362 } 366 for (int i = 0; i < data_n; ++i) 367 { 368 if ((i+data_begin) >= 0 && (i+data_begin<n)) 369 { 370 if (mask(i+data_begin)) 371 data_index(i) = i+data_begin; 372 else 373 data_index(i) = -1; 374 } 375 else 376 data_index(i) = -1; 377 } 378 } 379 else 380 { 381 if (data_index.numElements() != data_n) 382 { 383 ERROR("CAxis::checkData(void)", 384 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 385 << "The size of data_index = "<< data_index.numElements() << "is not equal to the data size data_n = " << data_n.getValue() << ")."); 386 } 387 for (int i = 0; i < data_n; ++i) 388 { 389 if ((i+data_begin) >= 0 && (i+data_begin<n) && !mask(i+data_begin)) 390 data_index(i) = -1; 391 } 392 } 393 363 394 } 364 395 CATCH_DUMP_ATTR … … 377 408 if (!mask.isEmpty()) 378 409 { 379 if (mask.extent(0) != n) 380 ERROR("CAxis::checkMask(void)", 381 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 382 << "The mask does not have the same size as the local domain." << std::endl 383 << "Local size is " << n.getValue() << "." << std::endl 384 << "Mask size is " << mask.extent(0) << "."); 385 } 386 else // (mask.isEmpty()) 387 { // If no mask was defined, we create a default one without any masked point. 388 mask.resize(n); 389 for (int i = 0; i < n; ++i) 390 { 391 mask(i) = true; 392 } 410 if (mask.extent(0) != n) 411 { 412 ERROR("CAxis::checkMask(void)", 413 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 414 << "The mask does not have the same size as the local domain." << std::endl 415 << "Local size is " << n.getValue() << "." << std::endl 416 << "Mask size is " << mask.extent(0) << "."); 417 } 418 } 419 else 420 { 421 mask.resize(n); 422 mask = true; 393 423 } 394 424 } … … 598 628 599 629 // Calculate the compressed index if any 600 std::set<int> writtenInd;601 if (isCompressible_)602 {603 for (int idx = 0; idx < data_index.numElements(); ++idx)604 {605 int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);606 607 if (ind >= 0 && ind < ni && mask(ind))608 {609 ind += ibegin;610 writtenInd.insert(ind);611 }612 }613 }630 // std::set<int> writtenInd; 631 // if (isCompressible_) 632 // { 633 // for (int idx = 0; idx < data_index.numElements(); ++idx) 634 // { 635 // int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 636 // 637 // if (ind >= 0 && ind < ni && mask(ind)) 638 // { 639 // ind += ibegin; 640 // writtenInd.insert(ind); 641 // } 642 // } 643 // } 614 644 615 645 // Compute the global index of the current client (process) hold … … 680 710 connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 681 711 682 712 nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 683 713 684 714 delete clientServerMap; … … 718 748 CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 719 749 itSrve = writtenGlobalIndex.end(), itSrv; 750 751 localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 752 nbWritten = 0; 720 753 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 721 754 { … … 723 756 if (ite != globalLocalIndexMap_.find(indGlo)) 724 757 { 725 ++nbWritten;726 }727 }728 729 localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements());730 // localIndexToWriteOnServer.resize(nbWritten);731 732 nbWritten = 0;733 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)734 {735 indGlo = *itSrv;736 if (ite != globalLocalIndexMap_.find(indGlo))737 {738 758 localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 739 ++nbWritten; 740 } 741 } 759 } 760 else 761 { 762 localIndexToWriteOnServer(nbWritten) = -1; 763 } 764 ++nbWritten; 765 } 766 742 767 } 743 768 CATCH_DUMP_ATTR … … 780 805 } 781 806 } 807 // 808 // nbWritten = 0; 809 // for (int idx = 0; idx < data_index.numElements(); ++idx) 810 // { 811 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 812 // { 813 // ++nbWritten; 814 // } 815 // } 816 // 817 // compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten); 818 // nbWritten = 0; 819 // for (int idx = 0; idx < data_index.numElements(); ++idx) 820 // { 821 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 822 // { 823 // compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)]; 824 // ++nbWritten; 825 // } 826 // } 782 827 783 828 nbWritten = 0; … … 1027 1072 1028 1073 /* 1029 Send a ttributes of axis from a group of client to other group of clients/servers1030 onsupposing that these attributes are distributed among the clients of the sending group1031 In thefuture, if new attributes are added, they should also be processed in this function1074 Send axis attributes from a group of clients to another group of clients/servers 1075 supposing that these attributes are distributed among the clients of the sending group 1076 In future, if new attributes are added, they should also be processed in this function 1032 1077 */ 1033 1078 void CAxis::sendDistributedAttributes(void) 1034 1079 TRY 1035 1080 { 1036 int ns, n, i, j, ind, nv, idx;1081 int ind, idx; 1037 1082 std::list<CContextClient*>::iterator it; 1038 1083 … … 1046 1091 list<CMessage> listData; 1047 1092 list<CArray<int,1> > list_indi, list_dataInd; 1048 list<CArray<bool,1> > list_mask;1049 1093 list<CArray<double,1> > list_val; 1050 1094 list<CArray<double,2> > list_bounds; 1051 1095 list<CArray<string,1> > list_label; 1052 1096 1097 // Cut off the ghost points 1053 1098 int nbIndex = index.numElements(); 1054 1099 CArray<int,1> dataIndex(nbIndex); … … 1057 1102 { 1058 1103 if (0 <= data_index(idx) && data_index(idx) < nbIndex) 1059 dataIndex( idx) = 1;1104 dataIndex(data_index(idx)) = 1; 1060 1105 } 1061 1106 … … 1064 1109 for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k) 1065 1110 { 1066 int nbData = 0 ;1111 int nbData = 0, nbDataCount = 0; 1067 1112 int rank = connectedServerRank_[nbServer][k]; 1068 1113 it = indSrv_[nbServer].find(rank); … … 1071 1116 1072 1117 list_indi.push_back(CArray<int,1>(nbData)); 1073 list_dataInd.push_back(CArray<int,1>(nbData)); 1074 list_mask.push_back(CArray<bool,1>(nbData)); 1118 list_dataInd.push_back(CArray<int,1>(nbData)); 1075 1119 1076 1120 if (hasValue) … … 1084 1128 1085 1129 CArray<int,1>& indi = list_indi.back(); 1086 CArray<int,1>& dataIndi = list_dataInd.back(); 1087 CArray<bool,1>& maskIndi = list_mask.back();1088 1089 for ( n = 0; n < nbData; ++n)1130 CArray<int,1>& dataIndi = list_dataInd.back(); 1131 dataIndi = -1; 1132 1133 for (int n = 0; n < nbData; ++n) 1090 1134 { 1091 1135 idx = static_cast<int>(it->second[n]); … … 1094 1138 ind = globalLocalIndexMap_[idx]; 1095 1139 dataIndi(n) = dataIndex(ind); 1096 maskIndi(n) = mask(ind);1097 1140 1098 1141 if (hasValue) … … 1118 1161 listData.push_back(CMessage()); 1119 1162 listData.back() << this->getId() 1120 << list_indi.back() << list_dataInd.back() << list_mask.back();1163 << list_indi.back() << list_dataInd.back(); 1121 1164 1122 1165 listData.back() << hasValue; … … 1173 1216 int nbReceived = ranks.size(), idx, ind, gloInd, locInd; 1174 1217 vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived); 1175 vector<CArray<bool,1> > vec_mask(nbReceived);1176 1218 vector<CArray<double,1> > vec_val(nbReceived); 1177 1219 vector<CArray<double,2> > vec_bounds(nbReceived); … … 1183 1225 buffer >> vec_indi[idx]; 1184 1226 buffer >> vec_dataInd[idx]; 1185 buffer >> vec_mask[idx];1186 1227 1187 1228 buffer >> hasValue; … … 1220 1261 if (0 == globalLocalIndexMap_.count(gloInd)) 1221 1262 { 1222 index(nbInd Loc) = gloInd % n_glo;1223 globalLocalIndexMap_[gloInd] = nbInd Loc;1263 index(nbIndexGlob) = gloInd % n_glo; 1264 globalLocalIndexMap_[gloInd] = nbIndexGlob; 1224 1265 ++nbIndexGlob; 1225 1266 } … … 1234 1275 CArray<int,1> nonCompressedData(nbData); 1235 1276 nonCompressedData = -1; 1236 mask.resize(nbData); 1277 // Mask is incorporated into data_index and is not sent/received anymore 1278 mask.resize(0); 1237 1279 if (hasValue) 1238 1280 value.resize(nbData); … … 1247 1289 CArray<int,1>& indi = vec_indi[idx]; 1248 1290 CArray<int,1>& dataIndi = vec_dataInd[idx]; 1249 CArray<bool,1>& maskIndi = vec_mask[idx];1250 1291 int nb = indi.numElements(); 1251 1292 for (int n = 0; n < nb; ++n) … … 1255 1296 nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd); 1256 1297 1257 if (!mask(locInd)) // Only rewrite mask if it's not true1258 mask(locInd) = maskIndi(n);1259 1260 1298 if (hasValue) 1261 1299 value(locInd) = vec_val[idx](n); … … 1272 1310 } 1273 1311 1274 int nbCompressedData = 0; 1312 int nbCompressedData = 0; 1275 1313 for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 1276 1314 { 1277 1315 if (0 <= nonCompressedData(idx)) 1278 ++nbCompressedData; 1316 ++nbCompressedData; 1279 1317 } 1280 1318 … … 1286 1324 { 1287 1325 data_index(nbCompressedData) = idx % n; 1288 ++nbCompressedData; 1326 ++nbCompressedData; 1289 1327 } 1290 1328 } 1291 1329 1292 1330 data_begin.setValue(0); 1331 data_n.setValue(data_index.numElements()); 1293 1332 } 1294 1333 CATCH_DUMP_ATTR -
XIOS/trunk/src/node/axis.hpp
r1562 r1637 126 126 bool hasLabel; 127 127 128 CArray< size_t,1> localIndexToWriteOnServer;128 CArray<int,1> localIndexToWriteOnServer; 129 129 130 130 private: -
XIOS/trunk/src/node/domain.cpp
r1622 r1637 179 179 // size estimation for sendIndex (and sendArea which is always smaller or equal) 180 180 size_t sizeIndexEvent = 2 * sizeof(size_t) + 2 * CArray<int,1>::size(idxCount); 181 // if (isCompressible_)182 // {183 // std::map<int, std::vector<int> >::const_iterator itWritten = indWrittenSrv_.find(rank);184 // size_t writtenIdxCount = (itWritten != itWrittenIndexEnd) ? itWritten->second.size() : 0;185 // sizeIndexEvent += CArray<int,1>::size(writtenIdxCount);186 // }187 181 188 182 // size estimation for sendLonLat … … 1139 1133 TRY 1140 1134 { 1135 int i,j,ind; 1141 1136 if (!data_i_index.isEmpty()) 1142 1137 { … … 1159 1154 << "'data_j_index' must be defined when 'data_i_index' is set and 'data_dim' is 2."); 1160 1155 } 1156 for (int k=0; k<data_i_index.numElements(); ++k) 1157 { 1158 i = data_i_index(k)+data_ibegin ; 1159 j = data_j_index(k)+data_jbegin ; 1160 if (i>=0 && i<ni && j>=0 && j<nj) 1161 { 1162 ind=j*ni+i ; 1163 if (!domainMask(ind)) 1164 { 1165 data_i_index(k) = -1; 1166 data_j_index(k) = -1; 1167 } 1168 } 1169 else 1170 { 1171 data_i_index(k) = -1; 1172 data_j_index(k) = -1; 1173 } 1174 } 1161 1175 } 1162 1176 else // (1 == data_dim) … … 1165 1179 { 1166 1180 data_j_index.resize(data_ni); 1167 for (int j = 0; j < data_ni; ++j) data_j_index(j) = 0; 1181 data_j_index = 0; 1182 } 1183 for (int k=0; k<data_i_index.numElements(); ++k) 1184 { 1185 i=data_i_index(k)+data_ibegin ; 1186 if (i>=0 && i < domainMask.size()) 1187 { 1188 if (!domainMask(i)) data_i_index(k) = -1; 1189 } 1190 else 1191 data_i_index(k) = -1; 1192 1193 if (!domainMask(i)) data_i_index(k) = -1; 1168 1194 } 1169 1195 } … … 1180 1206 data_i_index.resize(data_ni); 1181 1207 data_j_index.resize(data_ni); 1182 1183 for (int i = 0; i < data_ni; ++i) 1208 data_j_index = 0; 1209 1210 for (int k = 0; k < data_ni; ++k) 1184 1211 { 1185 data_i_index(i) = i; 1186 data_j_index(i) = 0; 1212 i=k+data_ibegin ; 1213 if (i>=0 && i < domainMask.size()) 1214 { 1215 if (domainMask(i)) 1216 data_i_index(k) = k; 1217 else 1218 data_i_index(k) = -1; 1219 } 1220 else 1221 data_i_index(k) = -1; 1187 1222 } 1188 1223 } … … 1193 1228 data_j_index.resize(dsize); 1194 1229 1195 for(int count = 0, j = 0; j < data_nj; ++j)1230 for(int count = 0, kj = 0; kj < data_nj; ++kj) 1196 1231 { 1197 for(int i = 0; i < data_ni; ++i, ++count)1232 for(int ki = 0; ki < data_ni; ++ki, ++count) 1198 1233 { 1199 data_i_index(count) = i; 1200 data_j_index(count) = j; 1234 i = ki + data_ibegin; 1235 j = kj + data_jbegin; 1236 ind=j*ni+i ; 1237 if (i>=0 && i<ni && j>=0 && j<nj) 1238 { 1239 if (domainMask(ind)) 1240 { 1241 data_i_index(count) = ki; 1242 data_j_index(count) = kj; 1243 } 1244 else 1245 { 1246 data_i_index(count) = -1; 1247 data_j_index(count) = -1; 1248 } 1249 } 1250 else 1251 { 1252 data_i_index(count) = -1; 1253 data_j_index(count) = -1; 1254 } 1201 1255 } 1202 1256 } … … 1872 1926 connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 1873 1927 1928 // Now check if all servers have data to receive. If not, master client will send empty data. 1929 // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 1930 std::vector<int> counts (clientSize); 1931 std::vector<int> displs (clientSize); 1932 displs[0] = 0; 1933 int localCount = connectedServerRank_[nbServer].size() ; 1934 MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 1935 for (int i = 0; i < clientSize-1; ++i) 1936 { 1937 displs[i+1] = displs[i] + counts[i]; 1938 } 1939 std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]); 1940 MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 1941 1942 if ((allConnectedServers.size() != nbServer) && (rank == 0)) 1943 { 1944 std::vector<bool> isSrvConnected (nbServer, false); 1945 for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 1946 for (int i = 0; i < nbServer; ++i) 1947 { 1948 if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i); 1949 } 1950 } 1874 1951 nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 1875 1952 delete clientServerMap; … … 1908 1985 itSrve = writtenGlobalIndex.end(), itSrv; 1909 1986 1910 // for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)1911 // {1912 // indGlo = *itSrv;1913 // if (ite != globalLocalIndexMap_.find(indGlo))1914 // {1915 // ++nbWritten;1916 // }1917 // }1918 1919 // localIndexToWriteOnServer.resize(nbWritten);1920 1987 localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 1921 1922 1988 nbWritten = 0; 1923 1989 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) … … 1927 1993 { 1928 1994 localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 1929 ++nbWritten;1930 1995 } 1931 1996 else 1932 1997 { 1933 localIndexToWriteOnServer(nbWritten) = 0; 1934 ++nbWritten; 1935 } 1936 } 1937 1938 // if (isCompressible()) 1939 // { 1940 // nbWritten = 0; 1941 // std::unordered_map<size_t,size_t> localGlobalIndexMap; 1942 // for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 1943 // { 1944 // indGlo = *itSrv; 1945 // if (ite != globalLocalIndexMap_.find(indGlo)) 1946 // { 1947 // localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 1948 // ++nbWritten; 1949 // } 1950 // } 1951 1952 // nbWritten = 0; 1953 // for (int idx = 0; idx < data_i_index.numElements(); ++idx) 1954 // { 1955 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx))) 1956 // { 1957 // ++nbWritten; 1958 // } 1959 // } 1960 1961 // compressedIndexToWriteOnServer.resize(nbWritten); 1962 // nbWritten = 0; 1963 // for (int idx = 0; idx < data_i_index.numElements(); ++idx) 1964 // { 1965 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx))) 1966 // { 1967 // compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_i_index(idx)]; 1968 // ++nbWritten; 1969 // } 1970 // } 1971 1972 // numberWrittenIndexes_ = nbWritten; 1973 // if (isDistributed()) 1974 // { 1975 // MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 1976 // MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 1977 // offsetWrittenIndexes_ -= numberWrittenIndexes_; 1978 // } 1979 // else 1980 // totalNumberWrittenIndexes_ = numberWrittenIndexes_; 1981 // } 1998 localIndexToWriteOnServer(nbWritten) = -1; 1999 } 2000 ++nbWritten; 2001 } 1982 2002 } 1983 2003 CATCH_DUMP_ATTR … … 2063 2083 sendDistributionAttributes(); 2064 2084 sendIndex(); 2065 sendMask();2066 2085 sendLonLat(); 2067 2086 sendArea(); … … 2174 2193 2175 2194 /*! 2176 Send mask index from client to connected(s) clients2177 */2178 void CDomain::sendMask()2179 TRY2180 {2181 int ns, n, i, j, ind, nv, idx;2182 std::list<CContextClient*>::iterator it;2183 for (it=clients.begin(); it!=clients.end(); ++it)2184 {2185 CContextClient* client = *it;2186 int serverSize = client->serverSize;2187 2188 // send area for each connected server2189 CEventClient eventMask(getType(), EVENT_ID_MASK);2190 2191 list<CMessage> list_msgsMask;2192 list<CArray<bool,1> > list_mask;2193 2194 std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;2195 iteMap = indSrv_[serverSize].end();2196 for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)2197 {2198 int nbData = 0;2199 int rank = connectedServerRank_[serverSize][k];2200 it = indSrv_[serverSize].find(rank);2201 if (iteMap != it)2202 nbData = it->second.size();2203 list_mask.push_back(CArray<bool,1>(nbData));2204 2205 const std::vector<size_t>& temp = it->second;2206 for (n = 0; n < nbData; ++n)2207 {2208 idx = static_cast<int>(it->second[n]);2209 list_mask.back()(n) = domainMask(globalLocalIndexMap_[idx]);2210 }2211 2212 list_msgsMask.push_back(CMessage());2213 list_msgsMask.back() << this->getId() << list_mask.back();2214 eventMask.push(rank, nbSenders[serverSize][rank], list_msgsMask.back());2215 }2216 client->sendEvent(eventMask);2217 }2218 }2219 CATCH_DUMP_ATTR2220 2221 /*!2222 2195 Send area from client to connected client(s) 2223 2196 */ … … 2458 2431 case EVENT_ID_INDEX: 2459 2432 recvIndex(event); 2460 return true;2461 break;2462 case EVENT_ID_MASK:2463 recvMask(event);2464 2433 return true; 2465 2434 break; … … 2555 2524 jIndex = (jIndex < 0) ? 0 : jIndex; 2556 2525 nbIndLoc = iIndex + ni * jIndex; 2557 if (nbIndLoc < nbIndexGlobMax) 2558 { 2559 i_index(nbIndLoc) = index % ni_glo; 2560 j_index(nbIndLoc) = index / ni_glo; 2561 globalLocalIndexMap_[index] = nbIndLoc; 2562 ++nbIndGlob; 2563 } 2564 // i_index(nbIndGlob) = index % ni_glo; 2565 // j_index(nbIndGlob) = index / ni_glo; 2566 // globalLocalIndexMap_[index] = nbIndGlob; 2567 // ++nbIndGlob; 2526 i_index(nbIndGlob) = index % ni_glo; 2527 j_index(nbIndGlob) = index / ni_glo; 2528 globalLocalIndexMap_[index] = nbIndGlob; 2529 ++nbIndGlob; 2568 2530 } 2569 2531 } … … 2580 2542 j_index.resizeAndPreserve(nbIndGlob); 2581 2543 } 2544 2545 domainMask.resize(0); // Mask is not defined anymore on servers 2582 2546 } 2583 2547 CATCH … … 2619 2583 2620 2584 } 2621 CATCH_DUMP_ATTR 2622 2623 /*! 2624 Receive area event from clients(s) 2625 \param[in] event event contain info about rank and associated area 2626 */ 2627 void CDomain::recvMask(CEventServer& event) 2628 TRY 2629 { 2630 string domainId; 2631 std::map<int, CBufferIn*> rankBuffers; 2632 2633 list<CEventServer::SSubEvent>::iterator it; 2634 for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 2635 { 2636 CBufferIn* buffer = it->buffer; 2637 *buffer >> domainId; 2638 rankBuffers[it->rank] = buffer; 2639 } 2640 get(domainId)->recvMask(rankBuffers); 2641 } 2642 CATCH 2643 2644 /*! 2645 Receive mask information from client(s) 2646 \param[in] rankBuffers rank of sending client and the corresponding receive buffer 2647 */ 2648 void CDomain::recvMask(std::map<int, CBufferIn*>& rankBuffers) 2649 TRY 2650 { 2651 int nbReceived = rankBuffers.size(), i, ind, index, lInd; 2652 if (nbReceived != recvClientRanks_.size()) 2653 ERROR("void CDomain::recvMask(std::map<int, CBufferIn*>& rankBuffers)", 2654 << "The number of sending clients is not correct." 2655 << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived); 2656 2657 vector<CArray<bool,1> > recvMaskValue(nbReceived); 2658 for (i = 0; i < recvClientRanks_.size(); ++i) 2659 { 2660 int rank = recvClientRanks_[i]; 2661 CBufferIn& buffer = *(rankBuffers[rank]); 2662 buffer >> recvMaskValue[i]; 2663 } 2664 2665 int nbMaskInd = 0; 2666 for (i = 0; i < nbReceived; ++i) 2667 { 2668 nbMaskInd += recvMaskValue[i].numElements(); 2669 } 2670 2671 if (nbMaskInd != globalLocalIndexMap_.size()) 2672 info (0) << "If domain " << this->getDomainOutputName() <<" does not have overlapped regions between processes " 2673 << "something must be wrong with mask index "<< std::endl; 2674 2675 nbMaskInd = globalLocalIndexMap_.size(); 2676 mask_1d.resize(nbMaskInd); 2677 domainMask.resize(nbMaskInd); 2678 mask_1d = false; 2679 2680 for (i = 0; i < nbReceived; ++i) 2681 { 2682 CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]]; 2683 CArray<bool,1>& tmp = recvMaskValue[i]; 2684 for (ind = 0; ind < tmp.numElements(); ++ind) 2685 { 2686 lInd = globalLocalIndexMap_[size_t(tmpInd(ind))]; 2687 if (!mask_1d(lInd)) // Only rewrite mask_1d if it's not true 2688 mask_1d(lInd) = tmp(ind); 2689 } 2690 } 2691 domainMask=mask_1d ; 2692 } 2693 CATCH_DUMP_ATTR 2694 2585 CATCH_DUMP_ATTR 2695 2586 /*! 2696 2587 Receive longitude event from clients(s) … … 3046 2937 dataIIndex(lInd) = (-1 == dataIIndex(lInd)) ? tmpI(ind) : dataIIndex(lInd); // Only fill in dataIndex if there is no data 3047 2938 dataJIndex(lInd) = (-1 == dataJIndex(lInd)) ? tmpJ(ind) : dataJIndex(lInd); 3048 3049 if (!domainMask(lInd)) // Include mask info into data index on the RECEIVE getServerDimensionSizes3050 {3051 dataIIndex(lInd) = dataJIndex(lInd) = -1;3052 }3053 2939 } 3054 2940 } -
XIOS/trunk/src/node/domain.hpp
r1578 r1637 49 49 { 50 50 EVENT_ID_INDEX, EVENT_ID_LON, EVENT_ID_LAT, 51 EVENT_ID_AREA, EVENT_ID_MASK,51 EVENT_ID_AREA, 52 52 EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT 53 53 } ; … … 142 142 CArray<double, 1> areavalue; 143 143 144 CArray< size_t,1> localIndexToWriteOnServer;144 CArray<int,1> localIndexToWriteOnServer; 145 145 146 146 CArray<bool, 1> domainMask; // mask_1d, mask_2d -> domainMask … … 175 175 void sendIndex(); 176 176 void sendDistributionAttributes(); 177 void sendMask();178 177 void sendArea(); 179 178 void sendLonLat(); … … 186 185 static void recvDistributionAttributes(CEventServer& event); 187 186 static void recvIndex(CEventServer& event); 188 static void recvMask(CEventServer& event);189 187 static void recvLon(CEventServer& event); 190 188 static void recvLat(CEventServer& event); … … 193 191 void recvDistributionAttributes(CBufferIn& buffer); 194 192 void recvIndex(std::map<int, CBufferIn*>& rankBuffers); 195 void recvMask(std::map<int, CBufferIn*>& rankBuffers);196 193 void recvLon(std::map<int, CBufferIn*>& rankBuffers); 197 194 void recvLat(std::map<int, CBufferIn*>& rankBuffers); -
XIOS/trunk/src/node/field.cpp
r1622 r1637 1122 1122 { 1123 1123 if (!instantDataFilter) 1124 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true));1124 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false)); 1125 1125 1126 1126 … … 1138 1138 { 1139 1139 if (!instantDataFilter) 1140 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true));1140 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, false)); 1141 1141 1142 1142 // If the field data is to be read by the client or/and written to a file … … 1184 1184 { 1185 1185 checkTimeAttributes(); 1186 instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, f req_offset, true,1186 instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 1187 1187 detectMissingValues, defaultValue)); 1188 1188 } … … 1190 1190 { 1191 1191 if (check_if_active.isEmpty()) check_if_active = false; 1192 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, NoneDu, false,1192 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, true, NoneDu, false, 1193 1193 detectMissingValues, defaultValue)); 1194 1194 } … … 1275 1275 { 1276 1276 checkTimeAttributes(); 1277 serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, f req_offset, true,1277 serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 1278 1278 detectMissingValues, defaultValue)); 1279 1279 } … … 1292 1292 { 1293 1293 if (check_if_active.isEmpty()) check_if_active = false; 1294 clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, NoneDu, false,1294 clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, true, NoneDu, false, 1295 1295 detectMissingValues, defaultValue)); 1296 1296 } … … 1887 1887 CATCH 1888 1888 1889 bool CField::hasGridMask(void) const 1890 TRY 1891 { 1892 return (this->grid->hasMask()); 1893 } 1894 CATCH 1895 1889 1896 DEFINE_REF_FUNC(Field,field) 1890 1897 } // namespace xios -
XIOS/trunk/src/node/field.hpp
r1542 r1637 209 209 bool hasExpression(void) const; 210 210 211 bool hasGridMask(void) const; 212 211 213 public: 212 214 /// Propriétés privées /// -
XIOS/trunk/src/node/grid.cpp
r1622 r1637 364 364 } 365 365 CATCH_DUMP_ATTR 366 bool CGrid::hasMask() const 367 TRY 368 { 369 return (!mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty() || 370 !mask_4d.isEmpty() || !mask_5d.isEmpty() || !mask_6d.isEmpty() || !mask_7d.isEmpty()); 371 } 372 CATCH 366 373 367 374 /* … … 453 460 CATCH_DUMP_ATTR 454 461 455 /*!456 A grid can have multiple dimension, so can its mask in the form of multi-dimension array.457 It's not a good idea to store all multi-dimension arrays corresponding to each mask.458 One of the ways is to convert this array into 1-dimension one and every process is taken place on it.459 \param [in] multi-dimension array grid mask460 */461 462 void CGrid::getLocalMask(CArray<bool,1>& localMask)463 TRY464 {465 std::vector<CDomain*> domainP = this->getDomains();466 std::vector<CAxis*> axisP = this->getAxis();467 int dim = domainP.size() * 2 + axisP.size();468 469 switch (dim)470 {471 case 0:472 getLocalMask(mask_0d, localMask);473 break;474 case 1:475 getLocalMask(mask_1d, localMask);476 break;477 case 2:478 getLocalMask(mask_2d, localMask);479 break;480 case 3:481 getLocalMask(mask_3d, localMask);482 break;483 case 4:484 getLocalMask(mask_4d, localMask);485 break;486 case 5:487 getLocalMask(mask_5d, localMask);488 break;489 case 6:490 getLocalMask(mask_6d, localMask);491 break;492 case 7:493 getLocalMask(mask_7d, localMask);494 break;495 default:496 break;497 }498 }499 CATCH_DUMP_ATTR500 501 462 /* 502 463 Modify value of mask in a certain index … … 736 697 CContext* context = CContext::getCurrent(); 737 698 738 CContextClient* client = context->client; // Here it's not important which contextClient to recuperate699 CContextClient* client = context->client; 739 700 int rank = client->clientRank; 740 701 741 702 clientDistribution_ = new CDistributionClient(rank, this); 742 703 // Get local data index on client 743 storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 744 int nbStoreIndex = storeIndex_client.numElements(); 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); 745 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]; 746 711 747 712 if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); … … 884 849 if (connectedServerRank_[receiverSize].empty()) 885 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 } 886 875 887 876 nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); … … 1369 1358 CATCH 1370 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 1371 1372 void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 1372 1373 TRY … … 1836 1837 nGlob.push_back(1); 1837 1838 } 1838 1839 modifyMaskSize(nSize, false);1840 1841 // These below codes are reserved for future1842 CDistributionServer srvDist(server->intraCommRank, nBegin, nSize, nBeginGlobal, nGlob);1843 map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),1844 ite = outGlobalIndexFromClient.end(), it;1845 const CDistributionServer::GlobalLocalMap& globalLocalMask = srvDist.getGlobalLocalIndex();1846 CDistributionServer::GlobalLocalMap::const_iterator itSrv;1847 size_t nb = 0;1848 for (it = itb; it != ite; ++it)1849 {1850 CArray<size_t,1>& globalInd = it->second;1851 for (size_t idx = 0; idx < globalInd.numElements(); ++idx)1852 {1853 if (globalLocalMask.end() != globalLocalMask.find(globalInd(idx))) ++nb;1854 }1855 }1856 1857 CArray<int,1> indexToModify(nb);1858 nb = 0;1859 for (it = itb; it != ite; ++it)1860 {1861 CArray<size_t,1>& globalInd = it->second;1862 for (size_t idx = 0; idx < globalInd.numElements(); ++idx)1863 {1864 itSrv = globalLocalMask.find(globalInd(idx));1865 if (globalLocalMask.end() != itSrv)1866 {1867 indexToModify(nb) = itSrv->second;1868 ++nb;1869 }1870 }1871 }1872 1873 modifyMask(indexToModify, true);1874 1839 } 1875 1840 -
XIOS/trunk/src/node/grid.hpp
r1622 r1637 94 94 template <int n> 95 95 void inputField(const CArray<double,n>& field, CArray<double,1>& stored) const; 96 template <int n> 97 void maskField(const CArray<double,n>& field, CArray<double,1>& stored) const; 96 98 template <int n> 97 99 void outputField(const CArray<double,1>& stored, CArray<double,n>& field) const; … … 203 205 bool hasTransform(); 204 206 size_t getGlobalWrittenSize(void) ; 205 void getLocalMask(CArray<bool,1>& localMask) ;206 template<int N>207 void getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask) ;208 207 public: 209 208 CArray<int, 1> storeIndex_client; 209 CArray<bool, 1> storeMask_client; 210 210 211 211 /** Map containing indexes that will be sent in sendIndex(). */ … … 247 247 CArray<size_t,1> indexFromClients; 248 248 249 bool hasMask(void) const; 249 250 void checkMask(void); 250 251 void createMask(void); … … 273 274 void restoreField_arr(const CArray<double, 1>& stored, double* const data) const; 274 275 void uncompressField_arr(const double* const data, CArray<double, 1>& outData) const; 276 void maskField_arr(const double* const data, CArray<double, 1>& stored) const; 275 277 276 278 void setVirtualDomainGroup(CDomainGroup* newVDomainGroup); … … 387 389 388 390 template <int n> 391 void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored) const 392 { 393 //#ifdef __XIOS_DEBUG 394 if (this->getDataSize() != field.numElements()) 395 ERROR("void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const", 396 << "[ Awaiting data of size = " << this->getDataSize() << ", " 397 << "Received data size = " << field.numElements() << " ] " 398 << "The data array does not have the right size! " 399 << "Grid = " << this->getId()) 400 //#endif 401 this->maskField_arr(field.dataFirst(), stored); 402 } 403 404 template <int n> 389 405 void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const 390 406 TRY … … 424 440 TRY 425 441 { 426 if (!gridMask.isEmpty() || createMask) 427 { 428 int idx = 0; 429 int numElement = axisDomainOrder.numElements(); 430 int dim = domainMasks.size() * 2 + axisMasks.size(); 431 std::vector<CDomain*> domainP = this->getDomains(); 432 std::vector<CAxis*> axisP = this->getAxis(); 433 434 std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim); 435 std::vector<int> currentIndex(dim); 436 int idxDomain = 0, idxAxis = 0; 442 int idx = 0; 443 int numElement = axisDomainOrder.numElements(); 444 int dim = domainMasks.size() * 2 + axisMasks.size(); 445 std::vector<CDomain*> domainP = this->getDomains(); 446 std::vector<CAxis*> axisP = this->getAxis(); 447 448 std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim); 449 std::vector<int> currentIndex(dim); 450 int idxDomain = 0, idxAxis = 0; 451 for (int i = 0; i < numElement; ++i) 452 { 453 indexMap[i] = idx; 454 if (2 == axisDomainOrder(i)) { 455 eachDimSize[indexMap[i]] = domainP[idxDomain]->ni; 456 eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj; 457 idx += 2; ++idxDomain; 458 } 459 else if (1 == axisDomainOrder(i)) { 460 // eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements(); 461 eachDimSize[indexMap[i]] = axisP[idxAxis]->n; 462 ++idx; ++idxAxis; 463 } 464 else {}; 465 } 466 467 if (!gridMask.isEmpty() && !createMask) 468 { 469 for (int i = 0; i < dim; ++i) 470 { 471 if (gridMask.extent(i) != eachDimSize[i]) 472 ERROR("CGrid::checkMask(void)", 473 << "The mask has one dimension whose size is different from the one of the local grid." << std::endl 474 << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl 475 << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl 476 << "Grid = " << this->getId()) 477 } 478 } 479 else { 480 CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 481 gridMask = true; 482 } 483 484 int ssize = gridMask.numElements(); 485 idx = 0; 486 while (idx < ssize) 487 { 488 for (int i = 0; i < dim-1; ++i) 489 { 490 if (idxLoop[i] == eachDimSize[i]) 491 { 492 idxLoop[i] = 0; 493 ++idxLoop[i+1]; 494 } 495 } 496 497 // Find out outer index 498 idxDomain = idxAxis = 0; 499 bool maskValue = true; 437 500 for (int i = 0; i < numElement; ++i) 438 501 { 439 indexMap[i] = idx; 440 if (2 == axisDomainOrder(i)) { 441 eachDimSize[indexMap[i]] = domainP[idxDomain]->ni; 442 eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj; 443 idx += 2; ++idxDomain; 502 if (2 == axisDomainOrder(i)) 503 { 504 int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]; 505 if (idxTmp < (*domainMasks[idxDomain]).numElements()) 506 maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp); 507 else 508 maskValue = false; 509 ++idxDomain; 444 510 } 445 else if (1 == axisDomainOrder(i)) { 446 // eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements(); 447 eachDimSize[indexMap[i]] = axisP[idxAxis]->n; 448 ++idx; ++idxAxis; 511 else if (1 == axisDomainOrder(i)) 512 { 513 int idxTmp = idxLoop[indexMap[i]]; 514 if (idxTmp < (*axisMasks[idxAxis]).numElements()) 515 maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp); 516 else 517 maskValue = false; 518 519 ++idxAxis; 449 520 } 450 else {};451 } 452 453 // if (!gridMask.isEmpty() && !createMask) 454 if (!createMask)521 } 522 523 int maskIndex = idxLoop[0]; 524 int mulDim = 1; 525 for (int k = 1; k < dim; ++k) 455 526 { 456 for (int i = 0; i < dim; ++i) 457 { 458 if (gridMask.extent(i) != eachDimSize[i]) 459 ERROR("CGrid::checkMask(void)", 460 << "The mask has one dimension whose size is different from the one of the local grid." << std::endl 461 << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl 462 << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl 463 << "Grid = " << this->getId()) 464 } 465 } 466 else { 467 CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 468 gridMask = true; 469 } 470 471 int ssize = gridMask.numElements(); 472 idx = 0; 473 while (idx < ssize) 474 { 475 for (int i = 0; i < dim-1; ++i) 476 { 477 if (idxLoop[i] == eachDimSize[i]) 478 { 479 idxLoop[i] = 0; 480 ++idxLoop[i+1]; 481 } 482 } 483 484 // Find out outer index 485 idxDomain = idxAxis = 0; 486 bool maskValue = true; 487 for (int i = 0; i < numElement; ++i) 488 { 489 if (2 == axisDomainOrder(i)) 490 { 491 int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]; 492 if (idxTmp < (*domainMasks[idxDomain]).numElements()) 493 maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp); 494 else 495 maskValue = false; 496 ++idxDomain; 497 } 498 else if (1 == axisDomainOrder(i)) 499 { 500 int idxTmp = idxLoop[indexMap[i]]; 501 if (idxTmp < (*axisMasks[idxAxis]).numElements()) 502 maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp); 503 else 504 maskValue = false; 505 506 ++idxAxis; 507 } 508 } 509 510 int maskIndex = idxLoop[0]; 511 int mulDim = 1; 512 for (int k = 1; k < dim; ++k) 513 { 514 mulDim *= eachDimSize[k-1]; 515 maskIndex += idxLoop[k]*mulDim; 516 } 517 *(gridMask.dataFirst()+maskIndex) &= maskValue; 518 519 ++idxLoop[0]; 520 ++idx; 521 } 522 } 527 mulDim *= eachDimSize[k-1]; 528 maskIndex += idxLoop[k]*mulDim; 529 } 530 *(gridMask.dataFirst()+maskIndex) &= maskValue; 531 532 ++idxLoop[0]; 533 ++idx; 534 } 523 535 } 524 536 CATCH_DUMP_ATTR … … 565 577 ///-------------------------------------------------------------- 566 578 567 /*! 568 A grid can have multiple dimension, so can its mask in the form of multi-dimension array. 569 It's not a good idea to store all multi-dimension arrays corresponding to each mask. 570 One of the ways is to convert this array into 1-dimension one and every process is taken place on it. 571 \param [in] multi-dimension array grid mask 572 */ 573 template<int N> 574 void CGrid::getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask) 575 TRY 576 { 577 if (gridMask.isEmpty()) return ; 578 int dim = gridMask.dimensions(); 579 std::vector<int> dimensionSizes(dim); 580 for (int i = 0; i < dim; ++i) dimensionSizes[i] = gridMask.extent(i); 581 582 std::vector<int> idxLoop(dim,0); 583 int ssize = gridMask.numElements(), idx = 0; 584 localMask.resize(ssize); 585 while (idx < ssize) 586 { 587 for (int i = 0; i < dim-1; ++i) 588 { 589 if (idxLoop[i] == dimensionSizes[i]) 590 { 591 idxLoop[i] = 0; 592 ++idxLoop[i+1]; 593 } 594 } 595 596 int maskIndex = idxLoop[0]; 597 int mulDim = 1; 598 for (int k = 1; k < dim; ++k) 599 { 600 mulDim *= dimensionSizes[k-1]; 601 maskIndex += idxLoop[k]*mulDim; 602 } 603 localMask(maskIndex) = *(gridMask.dataFirst()+maskIndex); 604 605 ++idxLoop[0]; 606 ++idx; 607 } 608 } 609 CATCH_DUMP_ATTR 579 610 580 611 581 // Declare/Define CGridGroup and CGridDefinition -
XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
r1622 r1637 856 856 857 857 void CGenericAlgorithmTransformation::computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, 858 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest) 858 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, 859 int& nlocalIndexDest) 859 860 TRY 860 861 { … … 883 884 884 885 int nlocalIndexSrc=1 ; 885 int nlocalIndexDest=1 ; 886 // int nlocalIndexDest=1 ; 887 nlocalIndexDest=1 ; 886 888 CArray<bool,1> maskScalar(1) ; 887 889 maskScalar = true ; … … 992 994 } 993 995 994 // just get the local src mask995 CArray<bool,1> localMaskOnSrcGrid;996 gridSrc->getLocalMask(localMaskOnSrcGrid) ;997 // intermediate grid, mask is not initialized => set up mask to true998 if (localMaskOnSrcGrid.isEmpty())999 {1000 localMaskOnSrcGrid.resize(nlocalIndexSrc) ;1001 localMaskOnSrcGrid=true ;1002 }1003 1004 1005 localMaskOnGridDest.resize(nlocalIndexDest,false) ;1006 1007 996 vector<vector<vector<pair<int,double> > > > dstIndWeight(transformationMapping_.size()) ; 1008 997 … … 1031 1020 1032 1021 nonDistributedrecursiveFunct(nElement-1,true,elementPositionInGrid,maskSrc,maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight, 1033 currentInd,localSrc,localDst,weight , localMaskOnSrcGrid, localMaskOnGridDest);1022 currentInd,localSrc,localDst,weight); 1034 1023 1035 1024 } 1036 1025 CATCH 1037 1026 1038 void CGenericAlgorithmTransformation::nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd, 1039 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest ) 1027 1028 void CGenericAlgorithmTransformation::nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, 1029 vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, 1030 int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, 1031 int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd, 1032 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight) 1040 1033 TRY 1041 1034 { … … 1051 1044 masked_=masked ; 1052 1045 if (!mask(i)) masked_=false ; 1053 nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight, currentInd, localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ; 1046 nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, 1047 dstIndWeight, currentInd, localSrc, localDst, weight); 1054 1048 } 1055 1049 } … … 1065 1059 for(vector<pair<int,double> >::iterator it = dstIndWeight[t][currentInd].begin(); it!=dstIndWeight[t][currentInd].end(); ++it) 1066 1060 { 1067 if (localMaskOnGridSrc(srcInd)) 1068 { 1069 localSrc.push_back(srcIndCompressed) ; 1070 localDst.push_back(it->first) ; 1071 weight.push_back(it->second) ; 1072 localMaskOnGridDest[it->first]=true ; 1073 } 1061 localSrc.push_back(srcIndCompressed) ; 1062 localDst.push_back(it->first) ; 1063 weight.push_back(it->second) ; 1074 1064 (it->first)++ ; 1075 1065 } 1076 1066 } 1077 1067 if (t < dstIndWeight.size()-1) t++ ; 1078 if (localMaskOnGridSrc(srcInd))srcIndCompressed ++ ;1068 srcIndCompressed ++ ; 1079 1069 } 1080 1070 srcInd++ ; … … 1094 1084 masked_=masked ; 1095 1085 if (!mask(i)) masked_=false ; 1096 nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight , i, localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ; 1086 nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, 1087 srcIndCompressed, nIndexSrc, t, dstIndWeight , i, localSrc, localDst, weight); 1097 1088 } 1098 1089 } … … 1108 1099 for(vector<pair<int,double> >::iterator it = dstIndWeight[t][i].begin(); it!=dstIndWeight[t][i].end(); ++it) 1109 1100 { 1110 if (localMaskOnGridSrc(srcInd)) 1111 { 1112 localSrc.push_back(srcIndCompressed) ; 1113 localDst.push_back(it->first) ; 1114 weight.push_back(it->second) ; 1115 localMaskOnGridDest[it->first]=true ; 1116 } 1101 localSrc.push_back(srcIndCompressed) ; 1102 localDst.push_back(it->first) ; 1103 weight.push_back(it->second) ; 1117 1104 (it->first)++ ; 1118 1105 } 1119 1106 } 1120 1107 if (t < dstIndWeight.size()-1) t++ ; 1121 if (localMaskOnGridSrc(srcInd))srcIndCompressed ++ ;1108 srcIndCompressed ++ ; 1122 1109 } 1123 1110 srcInd++ ; -
XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
r1542 r1637 88 88 void computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs = std::vector<CArray<double,1>* >()); 89 89 void computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, 90 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest); 91 void nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd, 92 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest) ; 90 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, int& nbLocalIndexOnGridDest); 91 void nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, 92 int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, 93 int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd, 94 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight) ; 93 95 94 96 protected: -
XIOS/trunk/src/transformation/grid_transformation.cpp
r1622 r1637 359 359 std::list<RecvIndexGridDestinationMap>().swap(localIndexToReceiveOnGridDest_); 360 360 std::list<size_t>().swap(nbLocalIndexOnGridDest_); 361 std::list<std::vector<bool> >().swap(localMaskOnGridDest_);362 361 } 363 362 else … … 412 411 vector<int> localDst ; 413 412 vector<double> weight ; 414 localMaskOnGridDest_.push_back(vector<bool>());413 int nbLocalIndexOnGridDest; 415 414 CTimer::get("computeTransformationMappingNonDistributed").resume(); 416 415 algo->computeTransformationMappingNonDistributed(elementPosition, gridSource_, tmpGridDestination_, 417 localSrc, localDst, weight, localMaskOnGridDest_.back()) ;416 localSrc, localDst, weight, nbLocalIndexOnGridDest) ; 418 417 CTimer::get("computeTransformationMappingNonDistributed").suspend(); 419 418 420 419 CTimer::get("computeTransformationMappingConvert").resume(); 421 nbLocalIndexOnGridDest_.push_back( localMaskOnGridDest_.back().size()) ;420 nbLocalIndexOnGridDest_.push_back(nbLocalIndexOnGridDest) ; 422 421 int clientRank=client->clientRank ; 423 422 { … … 487 486 size_t nbLocalIndex = globalLocalIndexGridDestSendToServer.size(); 488 487 nbLocalIndexOnGridDest_.push_back(nbLocalIndex); 489 localMaskOnGridDest_.push_back(std::vector<bool>());490 std::vector<bool>& tmpMask = localMaskOnGridDest_.back();491 tmpMask.resize(nbLocalIndex,false);488 // localMaskOnGridDest_.push_back(std::vector<bool>()); 489 // std::vector<bool>& tmpMask = localMaskOnGridDest_.back(); 490 // tmpMask.resize(nbLocalIndex,false); 492 491 493 492 // Find out number of index sent from grid source and number of index received on grid destination … … 672 671 recvTmp[recvRank][realRecvSize].first = globalLocalIndexGridDestSendToServer[recvIndexDst(idx)]; 673 672 recvTmp[recvRank][realRecvSize].second = recvWeightDst(idx); 674 tmpMask[globalLocalIndexGridDestSendToServer[recvIndexDst(idx)]] = true;675 673 ++realRecvSize; 676 674 } … … 732 730 CATCH 733 731 734 /*! 735 Local mask of data which will be received on the grid destination 736 \return local mask of data 737 */ 738 const std::list<std::vector<bool> >& CGridTransformation::getLocalMaskIndexOnGridDest() const 739 TRY 740 { 741 return localMaskOnGridDest_; 742 } 743 CATCH 744 745 } 732 } -
XIOS/trunk/src/transformation/grid_transformation.hpp
r978 r1637 49 49 const std::list<RecvIndexGridDestinationMap>& getLocalIndexToReceiveOnGridDest() const; 50 50 const std::list<size_t>& getNbLocalIndexToReceiveOnGridDest() const; 51 const std::list<std::vector<bool> >& getLocalMaskIndexOnGridDest() const;52 51 53 52 CGrid* getGridSource() { return originalGridSource_; } … … 84 83 //! Number of local index of data to receive on grid destination 85 84 std::list<size_t> nbLocalIndexOnGridDest_; 86 std::list<std::vector<bool> > localMaskOnGridDest_;87 85 88 86 bool dynamicalTransformation_;
Note: See TracChangeset
for help on using the changeset viewer.