Changeset 2319


Ignore:
Timestamp:
03/30/22 13:51:10 (3 years ago)
Author:
jderouillat
Message:

Add a checksum ability in xios_send/recv_field, enabled with info_level > 100.

Location:
XIOS/trunk/src/node
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/node/field.hpp

    r2131 r2319  
    161161 
    162162        template <int N> void setData(const CArray<double, N>& _data, int ntile = -1); 
     163        void checkSumLike( const double* array, int numElements, bool output ) const; 
    163164        static bool dispatchEvent(CEventServer& event); 
    164165        void sendAllAttributesToServer(CContextClient* client) ;  
  • XIOS/trunk/src/node/field_impl.hpp

    r2131 r2319  
    2222    { 
    2323      if (check_if_active.isEmpty() || (!check_if_active.isEmpty() && (!check_if_active) || isActive(true))) 
     24      { 
     25        if ( info.getLevel()>100  ) 
     26        { 
     27          const double* array = _data.dataFirst(); 
     28          int numElements( _data.numElements() ); 
     29          checkSumLike( array, numElements, true ); 
     30        } 
    2431        if (tileid > -1) 
    2532          clientSourceFilter->streamTile(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data, tileid); // tiled domain 
    2633        else 
    2734          clientSourceFilter->streamData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data); 
     35      } 
    2836    } 
    2937    else if (instantDataFilter) 
     
    4048    { 
    4149      CDataPacket::StatusCode status = storeFilter->getData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data); 
     50      if ( info.getLevel()>100  ) 
     51      { 
     52        const double* array = _data.dataFirst(); 
     53        int numElements( _data.numElements() ); 
     54        checkSumLike( array, numElements, false ); 
     55      } 
    4256 
    4357      if (status == CDataPacket::END_OF_STREAM) 
     
    5266  } 
    5367  CATCH 
     68 
     69  void CField::checkSumLike( const double* array, int numElements, bool output ) const 
     70  { 
     71    int rk = CContext::getCurrent()->client->clientRank; 
     72    int sz = CContext::getCurrent()->client->clientSize; 
     73    MPI_Comm comm = CContext::getCurrent()->client->intraComm; 
     74     
     75    double localSum( 0. ); 
     76    double error( 0. ); 
     77    unsigned long long checkSum( 0 ); 
     78    for ( int i=0 ; i<numElements ; i++ ) { 
     79      bool contributes( true );       
     80      if ( (!output) && ( !default_value.isEmpty() ) ) 
     81      { 
     82        if ( fabs(array[i]) > 0) 
     83          if ( fabs(array[i]-default_value.getValue())/array[i] < 2e-16 ) 
     84            contributes = false; 
     85      } 
     86      if (contributes) 
     87      { 
     88        double y = array[i] - error; 
     89        double t = localSum + y; 
     90        error = (t - localSum) - y; 
     91        localSum = t; 
     92 
     93        checkSum += *((unsigned long long*)(&array[i])); 
     94        checkSum = checkSum%LLONG_MAX; 
     95      } 
     96    } 
     97 
     98    double globalSum( 0. ); 
     99    unsigned long long globalCheck( 0 ); 
     100 
     101    if ( rk ==0 ) 
     102    { 
     103      MPI_Status status; 
     104      globalSum = localSum; // rank 0 contribution 
     105      globalCheck = checkSum; 
     106      for ( int irk = 1 ; irk < sz ; irk++ ) 
     107      { 
     108        MPI_Recv( &localSum, 1, MPI_DOUBLE, irk, 0, comm, &status ); 
     109        double y = localSum - error; 
     110        double t = globalSum + y; 
     111        error = (t - globalSum) - y; 
     112        globalSum = t; 
     113     
     114        MPI_Recv( &checkSum, 1, MPI_UNSIGNED_LONG_LONG, irk, 1, comm, &status ); 
     115        globalCheck += checkSum; 
     116        globalCheck = globalCheck%LLONG_MAX; 
     117      } 
     118    } 
     119    else 
     120    { 
     121      MPI_Send( &localSum, 1, MPI_DOUBLE, 0, 0, comm ); 
     122      MPI_Send( &checkSum, 1, MPI_UNSIGNED_LONG_LONG, 0, 1, comm ); 
     123    } 
     124     
     125    if ( rk == 0 ) 
     126    { 
     127      info(100) << setprecision(DBL_DIG); 
     128      if (output ) 
     129        info(100) << "Check Output key field for : " << getId() << ", key =  " << globalCheck << ", sum = " << globalSum << endl; 
     130      else 
     131        info(100) << "Check Input key field for : " << getId() << ", key =  " << globalCheck << ", sum = " << globalSum << endl; 
     132      info(100) << setprecision(6); 
     133    } 
     134  } 
     135   
    54136} // namespace xios 
    55137 
Note: See TracChangeset for help on using the changeset viewer.