Ignore:
Timestamp:
04/23/21 15:00:35 (3 years ago)
Author:
oabramkina
Message:

Merging branch dev_oa with tiling into trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/node/grid.cpp

    r1927 r2131  
    3939      , computedWrittenIndex_(false) 
    4040      , clients() 
     41      , nTiles_(0) 
     42      , isTiled_(false), isTiledOnly_(false) 
     43      , storeTileIndex() 
    4144   { 
    4245     setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group")); 
     
    6063      , computedWrittenIndex_(false) 
    6164      , clients() 
     65      , nTiles_(0) 
     66      , isTiled_(false), isTiledOnly_(false) 
     67      , storeTileIndex() 
    6268   { 
    6369     setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group")); 
     
    102108   } 
    103109   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   //--------------------------------------------------------------- 
    104180 
    105181   /*! 
     
    561637          if (sendAtt) domListP[i]->sendCheckedAttributes(); 
    562638          else domListP[i]->checkAttributesOnClient(); 
     639          if (domListP[i]->isTiled()) this->isTiled_ = true; 
     640          if (domListP[i]->isTiledOnly()) this->isTiledOnly_ = true; 
    563641        } 
    564642      } 
     
    725803          outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
    726804          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]; 
    727877          size_t nbIndex = 0; 
    728878 
     
    9011051     else 
    9021052     { 
    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(); 
    9041063       if (context->hasClient) 
    9051064       { 
     
    10971256   } 
    10981257   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 
    10991365//---------------------------------------------------------------- 
    11001366 
     
    13581624   CATCH 
    13591625 
    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(); 
    13631632      stored.resize(size); 
    13641633      const double nanValue = std::numeric_limits<double>::quiet_NaN(); 
    13651634 
    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; 
    13681637      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 
    13711677 
    13721678   void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 
     
    22532559        pDom->solveRefInheritance(apply); 
    22542560        pDom->solveInheritanceTransformation(); 
     2561        if (!pDom->ntiles.isEmpty() && pDom->ntiles.getValue()>0) nTiles_=pDom->ntiles.getValue(); 
    22552562      } 
    22562563    } 
     
    22812588  } 
    22822589  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 
    22832611 
    22842612  bool CGrid::isTransformed() 
Note: See TracChangeset for help on using the changeset viewer.