Changeset 2381


Ignore:
Timestamp:
07/12/22 16:39:07 (22 months ago)
Author:
jderouillat
Message:

Fix a bug on element names introduced in CGrid::duplicateSentGrid (commit 2351), the bug appeared with many grids in a file.

Location:
XIOS3/trunk/src/io
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • XIOS3/trunk/src/io/nc4_data_output.cpp

    r2267 r2381  
    2020            , SuperClassWriter(filename, exist) 
    2121            , filename(filename) 
    22             , file(file),hasTimeInstant(false),hasTimeCentered(false), timeCounterType(none) 
     22            , file(file),hasTimeInstant(false),hasTimeCentered(false), timeCounterType(none), relElements_() 
    2323      { 
    2424        SuperClass::type = MULTI_FILE; 
     
    3434            , filename(filename) 
    3535            , isCollective(isCollective) 
    36             , file(file),hasTimeInstant(false),hasTimeCentered(false), timeCounterType(none) 
     36            , file(file),hasTimeInstant(false),hasTimeCentered(false), timeCounterType(none), relElements_() 
    3737      { 
    3838        SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE; 
     
    6868 
    6969         CContext* context = CContext::getCurrent() ; 
    70  
    7170         if (domain->IsWritten(this->filename)) return; 
    7271         domain->checkAttributes(); 
     
    7574           if (SuperClass::type==MULTI_FILE) return; 
    7675 
     76 
     77         // Check that the name associated to the current element is not in conflict with an existing element (due to CGrid::duplicateSentGrid) 
     78         if (!domain->lonvalue.isEmpty() ) 
     79         { 
     80           int comm_file_rank(0); 
     81           MPI_Comm_rank( comm_file, &comm_file_rank ); 
     82           int comm_file_size(1); 
     83           MPI_Comm_size( comm_file, &comm_file_size ); 
     84          
     85           // Get element current FULL view 
     86           shared_ptr<CLocalView> srcView = domain->getLocalView(CElementView::FULL) ; 
     87           vector<shared_ptr<CLocalView>> srcViews; 
     88           srcViews.push_back( srcView ); 
     89          
     90           // Compute a without redundancy element FULL view to enable a consistent hash computation 
     91           vector<shared_ptr<CLocalView>> remoteViews; 
     92           shared_ptr<CLocalView> remoteView; 
     93           // define the remote view without redundancy (naive distribution of the remote view) 
     94           int globalSize = domain->ni_glo.getValue()*domain->nj_glo.getValue(); 
     95           int localSize = globalSize/comm_file_size; 
     96           if ( (comm_file_rank==comm_file_size-1) && (localSize*comm_file_size != globalSize ) ) 
     97             localSize += globalSize-localSize*comm_file_size; 
     98           CArray<size_t,1> globalIndex( localSize ); 
     99           CArray<int,1> index( localSize ); 
     100           for (int iloc=0; iloc<localSize ; iloc++ ) 
     101           { 
     102             globalIndex(iloc) = comm_file_rank*(globalSize/comm_file_size) + iloc; 
     103             index(iloc) = iloc; 
     104           } 
     105           shared_ptr<CLocalElement> localElement = make_shared<CLocalElement>(comm_file_rank, globalSize, globalIndex) ; 
     106           localElement->addView(CElementView::FULL, index) ; 
     107           remoteView = localElement->getView(CElementView::FULL) ; 
     108           remoteViews.push_back( remoteView ); 
     109          
     110           // Compute the connector between current and without redundancy FULL views 
     111           shared_ptr<CGridTransformConnector> gridTransformConnector = make_shared<CGridTransformConnector>(srcViews, remoteViews, comm_file ) ; 
     112           gridTransformConnector->computeConnector(true) ; // eliminateRedondant = true 
     113           CArray<double,1> lon_distributedValue, lat_distributedValue ; 
     114           gridTransformConnector->transfer(domain->lonvalue, lon_distributedValue ); 
     115           gridTransformConnector->transfer(domain->latvalue, lat_distributedValue ); 
     116 
     117           // Compute the distributed hash (v0) of the element 
     118           // it will be associated to the default element name (= map key), and to the name really written 
     119           int localHash = 0; 
     120           for (int iloc=0; iloc<localSize ; iloc++ ) localHash+=globalIndex(iloc)*lon_distributedValue(iloc)*lat_distributedValue(iloc); 
     121           int globalHash(0); 
     122           globalHash = localHash; 
     123           MPI_Allreduce( &localHash, &globalHash, 1, MPI_INT, MPI_SUM, comm_file  ); 
     124          
     125           StdString defaultNameKey = domain->getDomainOutputName(); 
     126           if ( !relElements_.count ( defaultNameKey ) ) 
     127           { 
     128             // if defaultNameKey not in the map, write the element such as it is defined 
     129             relElements_.insert( make_pair( defaultNameKey, make_pair(globalHash, defaultNameKey) ) ); 
     130           } 
     131           else // look if a hash associated this key is equal 
     132           { 
     133             bool elementIsInMap(false); 
     134             auto defaultNameKeyElements = relElements_.equal_range( defaultNameKey ); 
     135             for (auto it = defaultNameKeyElements.first; it != defaultNameKeyElements.second; it++) 
     136             { 
     137               if ( it->second.first == globalHash ) 
     138               { 
     139                 // if yes, associate the same ids to current element 
     140                 domain->name = it->second.second; 
     141                 // lon/lat names must be updated too, check that its exist, if not "lon"/"lat" (default values) are used 
     142                 StdString lon_name = "lon_"+it->second.second; 
     143                 int ncid = SuperClassWriter::getCurrentGroup(); 
     144                 int varId = 0; 
     145                 nc_inq_varid(ncid, lon_name.c_str(), &varId); 
     146                 if (!varId) //lon_name = "lon" 
     147                 { 
     148                   domain->lon_name = "lon"; 
     149                   domain->lat_name = "lat"; 
     150                 } 
     151                 else 
     152                 { 
     153                   domain->lon_name = "lon_"+it->second.second; 
     154                   domain->lat_name = "lat_"+it->second.second; 
     155                 } 
     156                 elementIsInMap = true; 
     157               } 
     158             } 
     159             // if no : inheritance has been excessive, define new names and store it (could be used by another grid) 
     160             if (!elementIsInMap)  // ! in MAP 
     161             { 
     162               domain->name =  domain->getId(); 
     163               domain->lon_name = "lon_"+domain->getId(); 
     164               domain->lat_name = "lat_"+domain->getId(); 
     165               relElements_.insert( make_pair( defaultNameKey, make_pair(globalHash, domain->getDomainOutputName()) ) ) ;// = domain->getId()           
     166             } 
     167           } 
     168         } 
     169 
     170          
    77171         std::vector<StdString> dim0, dim1; 
    78172         StdString domid = domain->getDomainOutputName(); 
     
    9981092      { 
    9991093        if (axis->IsWritten(this->filename)) return; 
     1094 
     1095        // Check that the name associated to the current element is not in conflict with an existing element (due to CGrid::duplicateSentGrid) 
     1096        if (!axis->value.isEmpty() ) 
     1097        { 
     1098          int comm_file_rank(0); 
     1099          MPI_Comm_rank( comm_file, &comm_file_rank ); 
     1100          int comm_file_size(1); 
     1101          MPI_Comm_size( comm_file, &comm_file_size ); 
     1102 
     1103          // Get element current FULL view 
     1104          shared_ptr<CLocalView> srcView = axis->getLocalView(CElementView::FULL) ; 
     1105          vector<shared_ptr<CLocalView>> srcViews; 
     1106          srcViews.push_back( srcView ); 
     1107           
     1108          // Compute a without redundancy element FULL view to enable a consistent hash computation 
     1109          vector<shared_ptr<CLocalView>> remoteViews; 
     1110          shared_ptr<CLocalView> remoteView; 
     1111          // define the remote view without redundancy (naive distribution of the remote view) 
     1112          int globalSize = axis->n_glo.getValue(); 
     1113          int localSize = globalSize/comm_file_size; 
     1114          if ( (comm_file_rank==comm_file_size-1) && (localSize*comm_file_size != globalSize ) ) 
     1115            localSize += globalSize-localSize*comm_file_size; 
     1116          CArray<size_t,1> globalIndex( localSize ); 
     1117          CArray<int,1> index( localSize ); 
     1118          for (int iloc=0; iloc<localSize ; iloc++ ) 
     1119          { 
     1120            globalIndex(iloc) = comm_file_rank*(globalSize/comm_file_size) + iloc; 
     1121            index(iloc) = iloc; 
     1122          } 
     1123          shared_ptr<CLocalElement> localElement = make_shared<CLocalElement>(comm_file_rank, globalSize, globalIndex) ; 
     1124          localElement->addView(CElementView::FULL, index) ; 
     1125          remoteView = localElement->getView(CElementView::FULL) ; 
     1126          remoteViews.push_back( remoteView ); 
     1127         
     1128          // Compute the connector between current and without redundancy FULL views 
     1129          shared_ptr<CGridTransformConnector> gridTransformConnector = make_shared<CGridTransformConnector>(srcViews, remoteViews, comm_file ) ; 
     1130          gridTransformConnector->computeConnector(true) ; // eliminateRedondant = true 
     1131          CArray<double,1> distributedValue ; 
     1132          gridTransformConnector->transfer(axis->value, distributedValue ); 
     1133         
     1134          // Compute the distributed hash (v0) of the element 
     1135          // it will be associated to the default element name (= map key), and to the name really written 
     1136          int localHash = 0; 
     1137          for (int iloc=0; iloc<localSize ; iloc++ ) localHash+=globalIndex(iloc)*distributedValue(iloc); 
     1138          int globalHash(0); 
     1139          globalHash = localHash; 
     1140          MPI_Allreduce( &localHash, &globalHash, 1, MPI_INT, MPI_SUM, comm_file  ); 
     1141 
     1142          StdString defaultNameKey = axis->getAxisOutputName(); 
     1143          if ( !relElements_.count ( defaultNameKey ) ) 
     1144          { 
     1145            // if defaultNameKey not in the map, write the element such as it is defined 
     1146            relElements_.insert( make_pair( defaultNameKey, make_pair(globalHash, defaultNameKey) ) ); 
     1147          } 
     1148          else // look if a hash associated this key is equal 
     1149          { 
     1150            bool elementIsInMap(false); 
     1151            auto defaultNameKeyElements = relElements_.equal_range( defaultNameKey ); 
     1152            for (auto it = defaultNameKeyElements.first; it != defaultNameKeyElements.second; it++) 
     1153            { 
     1154              if ( it->second.first == globalHash ) 
     1155              { 
     1156                // if yes, associate the same ids to current element 
     1157                axis->name = it->second.second; 
     1158                elementIsInMap = true; 
     1159              } 
     1160            } 
     1161             // if no : inheritance has been excessive, define new names and store it (could be used by another grid) 
     1162            if (!elementIsInMap)  // ! in MAP 
     1163            { 
     1164              axis->name =  axis->getId(); 
     1165              relElements_.insert( make_pair( defaultNameKey, make_pair(globalHash, axis->getAxisOutputName()) ) ) ;// = axis->getId()           
     1166            } 
     1167          } 
     1168        } 
     1169 
    10001170        axis->checkAttributes(); 
    10011171 
  • XIOS3/trunk/src/io/nc4_data_output.hpp

    r1961 r2381  
    128128            bool hasTimeInstant ; 
    129129            bool hasTimeCentered ; 
     130         
     131            std::unordered_multimap< StdString, pair<int,StdString> > relElements_; 
     132 
    130133      }; // class CNc4DataOutput 
    131134 
Note: See TracChangeset for help on using the changeset viewer.