Changeset 2131 for XIOS/trunk/src/node/grid.cpp
- Timestamp:
- 04/23/21 15:00:35 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/node/grid.cpp
r1927 r2131 39 39 , computedWrittenIndex_(false) 40 40 , clients() 41 , nTiles_(0) 42 , isTiled_(false), isTiledOnly_(false) 43 , storeTileIndex() 41 44 { 42 45 setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group")); … … 60 63 , computedWrittenIndex_(false) 61 64 , clients() 65 , nTiles_(0) 66 , isTiled_(false), isTiledOnly_(false) 67 , storeTileIndex() 62 68 { 63 69 setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group")); … … 102 108 } 103 109 CATCH 110 111 //--------------------------------------------------------------- 112 /*! 113 * Returns size of tile data 114 */ 115 116 StdSize CGrid::getTileDataSize(int tileId) 117 TRY 118 { 119 StdSize tileGridSize =1 ; 120 int numElement = axis_domain_order.numElements(); 121 122 std::vector<CAxis*> axisListP = this->getAxis(); 123 std::vector<CDomain*> domainListP = this->getDomains(); 124 125 int axisIndex = 0, domIndex = 0; 126 for (int idx = 0; idx < numElement; ++idx) 127 { 128 int eleDim = axis_domain_order(idx); 129 if (2 == eleDim) 130 { 131 tileGridSize *= domainListP[domIndex]->tile_data_ni(tileId); 132 tileGridSize *= domainListP[domIndex]->tile_data_nj(tileId); 133 ++domIndex; 134 } 135 else if (1 == eleDim) 136 { 137 tileGridSize *= axisListP[axisIndex]->n.getValue(); 138 ++axisIndex; 139 } 140 } // loop over grid elements 141 return tileGridSize; 142 } 143 CATCH 144 145 //--------------------------------------------------------------- 146 /*! 147 * Returns tile size 148 */ 149 150 StdSize CGrid::getTileSize(int tileId) 151 TRY 152 { 153 StdSize tileGridSize =1 ; 154 int numElement = axis_domain_order.numElements(); 155 156 std::vector<CAxis*> axisListP = this->getAxis(); 157 std::vector<CDomain*> domainListP = this->getDomains(); 158 159 int axisIndex = 0, domIndex = 0; 160 for (int idx = 0; idx < numElement; ++idx) 161 { 162 int eleDim = axis_domain_order(idx); 163 if (2 == eleDim) 164 { 165 tileGridSize *= domainListP[domIndex]->tile_ni(tileId); 166 tileGridSize *= domainListP[domIndex]->tile_nj(tileId); 167 ++domIndex; 168 } 169 else if (1 == eleDim)// So it's an axis 170 { 171 tileGridSize *= axisListP[axisIndex]->n.getValue(); 172 ++axisIndex; 173 } 174 } // loop over grid elements 175 return tileGridSize; 176 } 177 CATCH 178 179 //--------------------------------------------------------------- 104 180 105 181 /*! … … 561 637 if (sendAtt) domListP[i]->sendCheckedAttributes(); 562 638 else domListP[i]->checkAttributesOnClient(); 639 if (domListP[i]->isTiled()) this->isTiled_ = true; 640 if (domListP[i]->isTiledOnly()) this->isTiledOnly_ = true; 563 641 } 564 642 } … … 725 803 outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 726 804 CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 805 size_t nbIndex = 0; 806 807 // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 808 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 809 { 810 if (itGloe != globalDataIndex.find(globalIndex(idx))) 811 { 812 ++nbIndex; 813 } 814 } 815 816 if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 817 ERROR("void CGrid::computeClientIndex()", 818 << "Number of local index on client is different from number of received global index" 819 << "Rank of sent client " << rank <<"." 820 << "Number of local index " << nbIndex << ". " 821 << "Number of received global index " << localIndex.numElements() << "."); 822 823 nbIndex = 0; 824 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 825 { 826 if (itGloe != globalDataIndex.find(globalIndex(idx))) 827 { 828 localIndex(idx) = globalDataIndex[globalIndex(idx)]; 829 } 830 } 831 } 832 } 833 } 834 CATCH_DUMP_ATTR 835 836 //--------------------------------------------------------------- 837 838 /* 839 Compute the global index and its local index taking account mask and data index. 840 These global indexes will be used to compute the connection of this client (sender) to its servers (receivers) 841 (via function computeConnectedClient) 842 These global indexes also correspond to data sent to servers (if any) 843 */ 844 void CGrid::computeClientIndexTiled() 845 TRY 846 { 847 CContext* context = CContext::getCurrent(); 848 849 CContextClient* client = context->client; 850 int rank = client->clientRank; 851 852 clientDistributionTiled_ = new CDistributionClient(rank, this, true); 853 // Get local data index on client 854 int nbStoreIndex = clientDistributionTiled_->getLocalDataIndexOnClient().size(); 855 int nbStoreGridMask = clientDistributionTiled_->getLocalMaskIndexOnClient().size(); 856 // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise 857 storeIndexTiled_client.resize(nbStoreIndex); 858 storeMaskTiled_client.resize(nbStoreGridMask); 859 for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndexTiled_client(idx) = (clientDistributionTiled_->getLocalDataIndexOnClient())[idx]; 860 for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMaskTiled_client(idx) = (clientDistributionTiled_->getLocalMaskIndexOnClient())[idx]; 861 862 if (0 == serverDistribution_) isDataDistributed_= clientDistributionTiled_->isDataDistributed(); 863 else 864 { 865 // Mapping global index received from clients to the storeIndex_client 866 CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistributionTiled_->getGlobalDataIndexOnClient(); 867 CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 868 map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClientTiled.begin(), 869 ite = outGlobalIndexFromClientTiled.end(), it; 870 871 for (it = itb; it != ite; ++it) 872 { 873 int rank = it->first; 874 CArray<size_t,1>& globalIndex = outGlobalIndexFromClientTiled[rank]; 875 outLocalIndexStoreOnClientTiled.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 876 CArray<size_t,1>& localIndex = outLocalIndexStoreOnClientTiled[rank]; 727 877 size_t nbIndex = 0; 728 878 … … 901 1051 else 902 1052 { 903 computeClientIndex(); 1053 if (this->isTiled_) 1054 { 1055 computeClientIndexTiled(); 1056 if (!this->isTiledOnly_) 1057 computeClientIndex(); 1058 } 1059 else 1060 computeClientIndex(); 1061 1062 if (this->isTiled_) computeTileIndex(); 904 1063 if (context->hasClient) 905 1064 { … … 1097 1256 } 1098 1257 CATCH_DUMP_ATTR 1258 1259 //--------------------------------------------------------------- 1260 1261 /* 1262 */ 1263 void CGrid::computeTileIndex() 1264 TRY 1265 { 1266 int numElement = axis_domain_order.numElements(); 1267 storeTileIndex.resize(nTiles_); 1268 1269 std::vector<CAxis*> axisListP = this->getAxis(); 1270 std::vector<CDomain*> domainListP = this->getDomains(); 1271 1272 // First, allocate storeTileIndex[0..ntiles] 1273 for (int iTile = 0; iTile < nTiles_; ++iTile) 1274 { 1275 int tileGridSize = 1; 1276 int axisIndex = 0, domIndex = 0; 1277 for (int idx = 0; idx < numElement; ++idx) 1278 { 1279 int eleDim = axis_domain_order(idx); 1280 if (2 == eleDim) 1281 { 1282 tileGridSize *= domainListP[domIndex]->getTileDataISize(iTile); 1283 tileGridSize *= domainListP[domIndex]->getTileDataJSize(iTile); 1284 ++domIndex; 1285 } 1286 else if (1 == eleDim)// So it's an axis 1287 { 1288 tileGridSize *= axisListP[axisIndex]->n.getValue(); 1289 ++axisIndex; 1290 } 1291 } // loop over grid elements 1292 storeTileIndex[iTile].resize(tileGridSize); 1293 storeTileIndex[iTile] = -1; 1294 } // loop over tiles 1295 1296 // Now fill in storeTileIndex 1297 // Currently assuming two possible situations : (1) domain x axis or (2) domain 1298 std::vector<int> tileIndexCount (nTiles_,0); 1299 int axisSize = 1; 1300 if (axisListP.size() != 0) axisSize = axisListP[0]->n.getValue(); 1301 int ni = domainListP[0]->ni.getValue(); 1302 int nj = domainListP[0]->nj.getValue(); 1303 1304 for (int idxAxis = 0; idxAxis < axisSize; ++idxAxis) 1305 { 1306 for (int jIdxDom = 0; jIdxDom < nj; ++jIdxDom) 1307 { 1308 for (int iIdxDom = 0; iIdxDom < ni; ++iIdxDom) 1309 { 1310 int tile = domainListP[0]->getTileId(iIdxDom, jIdxDom); 1311 int tileOffset = domainListP[0]->tile_data_ibegin(tile); // only sign of offset matters 1312 1313 // case 1: data size corresponds to tile size 1314 if (tileOffset == 0) 1315 { 1316 storeTileIndex[tile](tileIndexCount[tile]) = idxAxis*nj*ni + jIdxDom * ni + iIdxDom; 1317 ++tileIndexCount[tile]; 1318 } 1319 // case 2: masked data 1320 else if (tileOffset > 0) 1321 { 1322 int iBegin = domainListP[0]->tile_ibegin(tile) + domainListP[0]->tile_data_ibegin(tile); // tile data relative to domain 1323 int jBegin = domainListP[0]->tile_jbegin(tile) + domainListP[0]->tile_data_jbegin(tile); // tile data relative to domain 1324 int iEnd = iBegin + domainListP[0]->tile_data_ni(tile); 1325 int jEnd = jBegin + domainListP[0]->tile_data_nj(tile); 1326 if ((jIdxDom >= jBegin) && (jIdxDom < jEnd) && (iIdxDom >= iBegin) && (iIdxDom < iEnd)) 1327 { 1328 storeTileIndex[tile](tileIndexCount[tile]) = idxAxis*nj*ni + jIdxDom * ni + iIdxDom; 1329 } 1330 ++tileIndexCount[tile]; 1331 } 1332 // case 3: ghost zones 1333 else 1334 { 1335 int tileDataNi = domainListP[0]->tile_data_ni(tile); 1336 int tileDataNj = domainListP[0]->tile_data_nj(tile); 1337 int tileDomSize = tileDataNi * tileDataNj; 1338 int tileNi = domainListP[0]->tile_ni(tile); 1339 int iBegin = domainListP[0]->tile_data_ibegin(tile); 1340 int jBegin = domainListP[0]->tile_data_jbegin(tile); 1341 1342 // add the ghost zone at the beginning of a domain tile 1343 if (tileIndexCount[tile] % tileDomSize == 0) 1344 tileIndexCount[tile] += (abs(jBegin)*tileDataNi + abs(iBegin)); 1345 1346 storeTileIndex[tile](tileIndexCount[tile]) = idxAxis*nj*ni + jIdxDom*ni + iIdxDom; 1347 1348 // add two ghost zones at the right end of a tile 1349 if ( (iIdxDom+1) % tileNi == 0 ) 1350 tileIndexCount[tile] += (2*abs(iBegin)); 1351 1352 // add ghost zone at the end of a domain tile 1353 if ((tileIndexCount[tile] + abs(jBegin)*tileDataNi-abs(iBegin) + 1) % tileDomSize == 0) 1354 tileIndexCount[tile] += (abs(jBegin)*tileDataNi -abs(iBegin)); 1355 1356 ++tileIndexCount[tile]; 1357 } 1358 } // loop over domain first dimension 1359 } // loop over domain second dimension 1360 } // loop over axis dimension 1361 1362 } 1363 CATCH_DUMP_ATTR 1364 1099 1365 //---------------------------------------------------------------- 1100 1366 … … 1358 1624 CATCH 1359 1625 1360 void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const 1361 { 1362 const StdSize size = storeIndex_client.numElements(); 1626 void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored, bool isTiled) const 1627 TRY 1628 { 1629 const CArray<int, 1>& storeIndex_clientP = isTiled ? storeIndexTiled_client : storeIndex_client; 1630 const CArray<bool, 1>& storeMask_clientP = isTiled ? storeMaskTiled_client : storeMask_client; 1631 const StdSize size = storeIndex_clientP.numElements(); 1363 1632 stored.resize(size); 1364 1633 const double nanValue = std::numeric_limits<double>::quiet_NaN(); 1365 1634 1366 if (storeMask_client .numElements() != 0)1367 for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client (i)) ? data[storeIndex_client(i)] : nanValue;1635 if (storeMask_clientP.numElements() != 0) 1636 for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_clientP(i)) ? data[storeIndex_clientP(i)] : nanValue; 1368 1637 else 1369 for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 1370 } 1638 for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_clientP(i)]; 1639 } 1640 CATCH 1641 1642 void CGrid::copyTile_arr(const double* const tileData, CArray<double, 1>& stored, int tileId) 1643 TRY 1644 { 1645 StdSize tileSize = this->getTileSize(tileId); 1646 const StdSize tileDataSize = this->getTileDataSize(tileId); 1647 1648 // case 1: data correspond in size to a tile 1649 if (tileSize == tileDataSize) 1650 { 1651 for(StdSize i = 0; i < tileDataSize; i++) 1652 stored(storeTileIndex[tileId](i)) = tileData[i]; 1653 } 1654 // case 2: masked data 1655 else if (tileSize > tileDataSize) 1656 { 1657 int tileDataCount = 0; 1658 for(StdSize i = 0; i < tileSize; i++) 1659 if (storeTileIndex[tileId](i) >= 0) 1660 { 1661 stored(storeTileIndex[tileId](i)) = tileData[tileDataCount]; 1662 ++tileDataCount; 1663 } 1664 } 1665 // case 3: ghost zones 1666 else 1667 { 1668 for(StdSize i = 0; i < tileDataSize; i++) 1669 if (storeTileIndex[tileId](i) >= 0) 1670 { 1671 stored(storeTileIndex[tileId](i)) = tileData[i]; 1672 } 1673 1674 } 1675 } 1676 CATCH 1371 1677 1372 1678 void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const … … 2253 2559 pDom->solveRefInheritance(apply); 2254 2560 pDom->solveInheritanceTransformation(); 2561 if (!pDom->ntiles.isEmpty() && pDom->ntiles.getValue()>0) nTiles_=pDom->ntiles.getValue(); 2255 2562 } 2256 2563 } … … 2281 2588 } 2282 2589 CATCH_DUMP_ATTR 2590 2591 int CGrid::getNTiles() 2592 TRY 2593 { 2594 return nTiles_; 2595 } 2596 CATCH_DUMP_ATTR 2597 2598 bool CGrid::isTiled(void) const 2599 TRY 2600 { 2601 return isTiled_; 2602 } 2603 CATCH 2604 2605 bool CGrid::isTiledOnly(void) const 2606 TRY 2607 { 2608 return isTiledOnly_; 2609 } 2610 CATCH 2283 2611 2284 2612 bool CGrid::isTransformed()
Note: See TracChangeset
for help on using the changeset viewer.