Ignore:
Timestamp:
08/25/15 16:52:45 (9 years ago)
Author:
rlacroix
Message:

Add support for indexed output.

If the new field attribute "indexed_output" is set to true and a mask is defined (either at grid, domain or axis level), the indexed data will be outputed instead of the full data with missing values.

See http://cfconventions.org/Data/cf-conventions/cf-conventions-1.5/build/cf-conventions.html#compression-by-gathering for more information.

File:
1 edited

Legend:

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

    r675 r676  
    1313#include "context.hpp" 
    1414#include "context_client.hpp" 
     15#include "context_server.hpp" 
    1516#include "array_new.hpp" 
     17#include "distribution_client.hpp" 
    1618#include "server_distribution_description.hpp" 
    1719#include "client_server_mapping_distributed.hpp" 
     
    1921#include "interpolate_from_file_domain.hpp" 
    2022 
     23#include <algorithm> 
     24 
    2125namespace xios { 
    2226 
     
    2630      : CObjectTemplate<CDomain>(), CDomainAttributes() 
    2731      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_() 
    28       , hasBounds(false), hasArea(false), isDistributed_(false), nGlobDomain_(), isUnstructed_(false) 
     32      , hasBounds(false), hasArea(false), isDistributed_(false), nGlobDomain_(), isCompressible_(false), isUnstructed_(false) 
    2933      , global_zoom_ni(0), global_zoom_ibegin(0), global_zoom_nj(0), global_zoom_jbegin(0) 
    3034      , isClientAfterTransformationChecked(false), hasLonLat(false) 
     
    3539      : CObjectTemplate<CDomain>(id), CDomainAttributes() 
    3640      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_() 
    37       , hasBounds(false), hasArea(false), isDistributed_(false), nGlobDomain_(), isUnstructed_(false) 
     41      , hasBounds(false), hasArea(false), isDistributed_(false), nGlobDomain_(), isCompressible_(false), isUnstructed_(false) 
    3842      , global_zoom_ni(0), global_zoom_ibegin(0), global_zoom_nj(0), global_zoom_jbegin(0) 
    3943      , isClientAfterTransformationChecked(false), hasLonLat(false) 
     
    6468 
    6569   //---------------------------------------------------------------- 
     70 
     71   const std::vector<int>& CDomain::getIndexesToWrite(void) const 
     72   { 
     73     return indexesToWrite; 
     74   } 
     75 
     76   /*! 
     77     Returns the number of indexes written by each server. 
     78     \return the number of indexes written by each server 
     79   */ 
     80   int CDomain::getNumberWrittenIndexes() const 
     81   { 
     82     return numberWrittenIndexes_; 
     83   } 
     84 
     85   /*! 
     86     Returns the total number of indexes written by the servers. 
     87     \return the total number of indexes written by the servers 
     88   */ 
     89   int CDomain::getTotalNumberWrittenIndexes() const 
     90   { 
     91     return totalNumberWrittenIndexes_; 
     92   } 
     93 
     94   /*! 
     95     Returns the offset of indexes written by each server. 
     96     \return the offset of indexes written by each server 
     97   */ 
     98   int CDomain::getOffsetWrittenIndexes() const 
     99   { 
     100     return offsetWrittenIndexes_; 
     101   } 
     102 
     103   //---------------------------------------------------------------- 
     104 
    66105   bool CDomain::isEmpty(void) const 
    67106   { 
     
    71110 
    72111   //---------------------------------------------------------------- 
     112 
    73113   bool CDomain::IsWritten(const StdString & filename) const 
    74114   { 
     
    76116   } 
    77117 
     118   bool CDomain::isWrittenCompressed(const StdString& filename) const 
     119   { 
     120      return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end()); 
     121   } 
     122 
    78123   //---------------------------------------------------------------- 
     124 
    79125   bool CDomain::isDistributed(void) const 
    80126   { 
     
    83129 
    84130   //---------------------------------------------------------------- 
     131 
     132   /*! 
     133    * Test whether the data defined on the domain can be outputted in a compressed way. 
     134    *  
     135    * \return true if and only if a mask was defined for this domain 
     136    */ 
     137   bool CDomain::isCompressible(void) const 
     138   { 
     139      return isCompressible_; 
     140   } 
     141 
     142   //---------------------------------------------------------------- 
     143 
    85144   void CDomain::addRelFile(const StdString & filename) 
    86145   { 
    87146      this->relFiles.insert(filename); 
     147   } 
     148 
     149   void CDomain::addRelFileCompressed(const StdString& filename) 
     150   { 
     151      this->relFilesCompressed.insert(filename); 
    88152   } 
    89153 
     
    246310   } 
    247311 
    248  
    249312   //---------------------------------------------------------------- 
     313 
    250314   void CDomain::checkDomainData(void) 
    251315   { 
     
    357421 
    358422   //---------------------------------------------------------------- 
     423 
     424   void CDomain::checkEligibilityForCompressedOutput(void) 
     425   { 
     426     // We don't check if the mask or the indexes are valid here, just if they have been defined at this point. 
     427     isCompressible_ = !mask_1d.isEmpty() || !mask_2d.isEmpty() || !data_i_index.isEmpty(); 
     428   } 
     429 
     430   //---------------------------------------------------------------- 
     431 
    359432   void CDomain::completeLonLatClient(void) 
    360433   { 
     
    746819        msg << ni_srv << ibegin_srv << iend_srv << nj_srv << jbegin_srv << jend_srv; 
    747820        msg << global_zoom_ni << global_zoom_ibegin << global_zoom_nj << global_zoom_jbegin; 
     821        msg << isCompressible_; 
    748822 
    749823        event.push(*itRank,1,msg); 
     
    783857      { 
    784858        ++globalIndexCountZoom; 
     859      } 
     860    } 
     861 
     862    int globalIndexWrittenCount = 0; 
     863    if (isCompressible_) 
     864    { 
     865      for (i = 0; i < data_i_index.numElements(); ++i) 
     866      { 
     867        i_ind = CDistributionClient::getDomainIndex(data_i_index(i), data_j_index(i), 
     868                                                    data_ibegin, data_jbegin, data_dim, ni, 
     869                                                    j_ind); 
     870        if (i_ind >= 0 && i_ind < ni && j_ind >= 0 && j_ind < nj && mask_1d(i_ind + j_ind * ni)) 
     871        { 
     872          i_ind += ibegin; 
     873          j_ind += jbegin; 
     874          if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend) 
     875            ++globalIndexWrittenCount; 
     876        } 
    785877      } 
    786878    } 
     
    809901    } 
    810902 
    811      size_t globalSizeIndex = 1, indexBegin, indexEnd; 
    812      int range, clientSize = client->clientSize; 
    813      for (int i = 0; i < nGlobDomain_.size(); ++i) globalSizeIndex *= nGlobDomain_[i]; 
    814      indexBegin = 0; 
    815      for (int i = 0; i < clientSize; ++i) 
    816      { 
    817        range = globalSizeIndex / clientSize; 
    818        if (i < (globalSizeIndex%clientSize)) ++range; 
    819        if (i == client->clientRank) break; 
    820        indexBegin += range; 
    821      } 
    822      indexEnd = indexBegin + range - 1; 
     903    CArray<int,1> globalIndexWrittenDomain(globalIndexWrittenCount); 
     904    if (isCompressible_) 
     905    { 
     906      globalIndexWrittenCount = 0; 
     907      for (i = 0; i < data_i_index.numElements(); ++i) 
     908      { 
     909        i_ind = CDistributionClient::getDomainIndex(data_i_index(i), data_j_index(i), 
     910                                                    data_ibegin, data_jbegin, data_dim, ni, 
     911                                                    j_ind); 
     912        if (i_ind >= 0 && i_ind < ni && j_ind >= 0 && j_ind < nj && mask_1d(i_ind + j_ind * ni)) 
     913        { 
     914          i_ind += ibegin; 
     915          j_ind += jbegin; 
     916          if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend) 
     917          { 
     918            globalIndexWrittenDomain(globalIndexWrittenCount) = i_ind + j_ind * ni_glo; 
     919            ++globalIndexWrittenCount; 
     920          } 
     921        } 
     922      } 
     923    } 
     924 
     925    size_t globalSizeIndex = 1, indexBegin, indexEnd; 
     926    int range, clientSize = client->clientSize; 
     927    for (int i = 0; i < nGlobDomain_.size(); ++i) globalSizeIndex *= nGlobDomain_[i]; 
     928    indexBegin = 0; 
     929    for (int i = 0; i < clientSize; ++i) 
     930    { 
     931      range = globalSizeIndex / clientSize; 
     932      if (i < (globalSizeIndex%clientSize)) ++range; 
     933      if (i == client->clientRank) break; 
     934      indexBegin += range; 
     935    } 
     936    indexEnd = indexBegin + range - 1; 
    823937 
    824938    CServerDistributionDescription serverDescription(nGlobDomain_); 
     
    837951 
    838952    indSrv_.clear(); 
     953    indWrittenSrv_.clear(); 
    839954    for (; it != ite; ++it) 
    840955    { 
     
    853968        } 
    854969      } 
     970      for (int i = 0; i < globalIndexWrittenDomain.numElements(); ++i) 
     971      { 
     972        if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexWrittenDomain(i), itVec)) 
     973        { 
     974          indWrittenSrv_[rank].push_back(globalIndexWrittenDomain(i)); 
     975        } 
     976      } 
    855977    } 
    856978 
     
    8881010 
    8891011    list<CMessage> list_msgsIndex; 
    890     list<CArray<int,1> > list_indi, list_indj; 
     1012    list<CArray<int,1> > list_indi, list_indj, list_writtenInd; 
    8911013 
    8921014    std::map<int, std::vector<size_t> >::const_iterator it, iteMap; 
     
    9181040      list_msgsIndex.back() << isCurvilinear; 
    9191041      list_msgsIndex.back() << list_indi.back() << list_indj.back(); 
     1042 
     1043      if (isCompressible_) 
     1044      { 
     1045        std::vector<int>& writtenIndSrc = indWrittenSrv_[rank]; 
     1046        list_writtenInd.push_back(CArray<int,1>(writtenIndSrc.size())); 
     1047        CArray<int,1>& writtenInd = list_writtenInd.back(); 
     1048 
     1049        for (n = 0; n < writtenInd.numElements(); ++n) 
     1050          writtenInd(n) = writtenIndSrc[n]; 
     1051 
     1052        list_msgsIndex.back() << writtenInd; 
     1053      } 
    9201054 
    9211055      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back()); 
     
    11181252  { 
    11191253    buffer >> ni_srv >> ibegin_srv >> iend_srv >> nj_srv >> jbegin_srv >> jend_srv 
    1120            >> global_zoom_ni >> global_zoom_ibegin >> global_zoom_nj >> global_zoom_jbegin; 
     1254           >> global_zoom_ni >> global_zoom_ibegin >> global_zoom_nj >> global_zoom_jbegin 
     1255           >> isCompressible_; 
    11211256 
    11221257    int zoom_iend = global_zoom_ibegin + global_zoom_ni - 1; 
     
    11581293  void CDomain::recvIndex(CEventServer& event) 
    11591294  { 
     1295    CDomain* domain; 
     1296 
    11601297    list<CEventServer::SSubEvent>::iterator it; 
    11611298    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
     
    11641301      string domainId; 
    11651302      *buffer >> domainId; 
    1166       get(domainId)->recvIndex(it->rank, *buffer); 
     1303      domain = get(domainId); 
     1304      domain->recvIndex(it->rank, *buffer); 
     1305    } 
     1306 
     1307    if (domain->isCompressible_) 
     1308    { 
     1309      std::sort(domain->indexesToWrite.begin(), domain->indexesToWrite.end()); 
     1310 
     1311      CContextServer* server = CContext::getCurrent()->server; 
     1312      domain->numberWrittenIndexes_ = domain->indexesToWrite.size(); 
     1313      MPI_Allreduce(&domain->numberWrittenIndexes_, &domain->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
     1314      MPI_Scan(&domain->numberWrittenIndexes_, &domain->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
     1315      domain->offsetWrittenIndexes_ -= domain->numberWrittenIndexes_; 
    11671316    } 
    11681317  } 
     
    11781327    buffer >> type_int >> isCurvilinear >> indiSrv[rank] >> indjSrv[rank]; 
    11791328    type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix 
     1329 
     1330    if (isCompressible_) 
     1331    { 
     1332      CArray<int, 1> writtenIndexes; 
     1333      buffer >> writtenIndexes; 
     1334      indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements()); 
     1335      for (int i = 0; i < writtenIndexes.numElements(); ++i) 
     1336        indexesToWrite.push_back(writtenIndexes(i)); 
     1337    } 
    11801338  } 
    11811339 
Note: See TracChangeset for help on using the changeset viewer.