Changeset 2256


Ignore:
Timestamp:
11/10/21 15:28:22 (3 years ago)
Author:
jderouillat
Message:

Implement axis_inverse such as a no_data_modification transformation

Location:
XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_inverse.cpp

    r2117 r2256  
    4949 
    5050CAxisAlgorithmInverse::CAxisAlgorithmInverse(bool isSource, CAxis* axisDestination, CAxis* axisSource, CInverseAxis* inverseAxis) 
    51  : CAlgorithmTransformationTransfer(isSource), axisDest_(axisDestination), axisSrc_(axisSource) 
     51 : CAlgorithmTransformationNoDataModification(isSource), axisDest_(axisDestination), axisSrc_(axisSource) 
    5252TRY 
    5353{ 
    54   axisDestination->checkAttributes() ; 
     54   
     55  axisDestination->axis_type.reset(); 
     56  axisDestination->n_glo.reset(); 
     57  axisDestination->index.reset(); 
     58  axisDestination->n.reset(); 
     59  axisDestination->begin.reset(); 
     60 
     61  axisDestination->mask.reset(); 
     62  axisDestination->data_index.reset(); 
     63  axisDestination->data_n.reset(); 
     64  axisDestination->data_begin.reset(); 
     65 
     66  axisDestination->value.reset(); 
     67  axisDestination->bounds.reset(); 
     68 
     69  axisDestination->n_glo.setValue( axisSource->n_glo.getValue() ); 
     70 
    5571  if (axisDestination->n_glo.getValue() != axisSource->n_glo.getValue()) 
    5672  { 
     
    6177  } 
    6278 
    63   auto& transMap = this->transformationMapping_; 
    64  
    65   int globalIndexSize = axisDestination->n_glo.getValue(); 
    66   for (int idx = 0; idx < axisDestination->index.numElements(); ++idx) 
     79  int n_glo =axisDestination->n_glo.getValue() ; 
     80   
     81  CArray<size_t,1> sourceGlobalIdx = axisSource->getLocalElement()->getGlobalIndex(); 
     82  int indexSize = sourceGlobalIdx.numElements(); 
     83   
     84  axisDestination->index.resize( indexSize ); 
     85  axisDestination->data_index.resize( indexSize ); 
     86  axisDestination->data_index = -1; 
     87  for (size_t i = 0; i < indexSize ; ++i) 
    6788  { 
    68     transMap[axisDestination->index(idx)] = globalIndexSize-axisDestination->index(idx)-1; 
     89    axisDestination->index(i) = (n_glo-1)-sourceGlobalIdx(i); 
    6990  } 
    7091 
    71   int niSrc   = axisSrc_->n.getValue(); 
    72   int sizeSrc = axisSrc_->n_glo.getValue(); 
    73   if (niSrc != sizeSrc) updateAxisValue(); 
    74   else 
     92  int idxMin = INT_MAX; 
     93  for (int countSrc = 0; countSrc < indexSize ; ++countSrc) 
    7594  { 
    76     for (int idx = 0; idx < sizeSrc; ++idx) 
     95    if ( sourceGlobalIdx(countSrc) < idxMin ) 
     96      idxMin = sourceGlobalIdx(countSrc); 
     97  } 
     98 
     99  CArray<int,1> sourceWorkflowIdx = axisSource->getLocalView(CElementView::WORKFLOW)->getIndex(); 
     100  int srcWorkflowSize = sourceWorkflowIdx.numElements(); 
     101  for (size_t i = 0; i < indexSize ; ++i) 
     102  { 
     103    // ------------------ define transformation only if in the WF ------------------  
     104    int iIdxSrc2 = (i+idxMin)%axisSource->n_glo; 
     105    int convert_locally_global_idx = (iIdxSrc2-idxMin) ; 
     106    bool concerned_by_WF(false); 
     107    int i2; 
     108    for ( i2 = 0 ; i2<sourceWorkflowIdx.numElements() ; ++i2 ) 
    77109    { 
    78       axisDest_->value(idx) = axisSrc_->value(sizeSrc-idx-1); 
     110      if (sourceWorkflowIdx(i2)==convert_locally_global_idx) 
     111      { 
     112        concerned_by_WF = true; 
     113        break; 
     114      } 
     115    } 
     116 
     117    if (concerned_by_WF) 
     118      { 
     119        axisDestination->data_index(sourceWorkflowIdx(i2)) = sourceWorkflowIdx(i2); 
     120      } 
     121    // ----------------------------------------------------------------------------- 
     122 
     123  } 
     124 
     125  if (axisSrc_->hasValue) 
     126  { 
     127    axisDestination->value.resize(indexSize); 
     128    for (size_t i = 0; i < indexSize ; ++i) 
     129    { 
     130      axisDestination->value(i) = axisSource->value(i); 
     131    } 
     132  } 
     133 
     134  if (axisSrc_->hasBounds) 
     135  { 
     136    axisDestination->bounds.resize(indexSize); 
     137    for (size_t i = 0; i < indexSize ; ++i) 
     138    { 
     139      axisDestination->bounds(i) = axisSource->bounds(i); 
    79140    } 
    80141  } 
    81142 
    82143  axisDestination->checkAttributes() ; 
    83   this->computeAlgorithm(axisSource->getLocalView(CElementView::WORKFLOW), axisDestination->getLocalView(CElementView::WORKFLOW)) ; 
    84144 
    85145} 
    86146CATCH 
    87147 
    88  
    89 /*! 
    90   Update value on axis after inversing 
    91   After an axis is inversed, not only the data on it must be inversed but also the value 
    92 */ 
    93 void CAxisAlgorithmInverse::updateAxisValue() 
    94 TRY 
    95 { 
    96   CContext* context = CContext::getCurrent(); 
    97   int clientRank = context->intraCommRank_; 
    98   int nbClient = context->intraCommSize_; 
    99  
    100   int niSrc     = axisSrc_->n.getValue(); 
    101   int ibeginSrc = axisSrc_->begin.getValue(); 
    102   int nSrc = axisSrc_->index.numElements(); 
    103  
    104   CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 
    105   for (int idx = 0; idx < nSrc; ++idx) 
    106   { 
    107     if ((axisSrc_->mask)(idx)) 
    108     { 
    109       globalIndex2ProcRank[(axisSrc_->index)(idx)].resize(1); 
    110       globalIndex2ProcRank[(axisSrc_->index)(idx)][0] = clientRank; 
    111     } 
    112   } 
    113  
    114   typedef std::unordered_map<size_t, std::vector<double> > GlobalIndexMapFromSrcToDest; 
    115   GlobalIndexMapFromSrcToDest globalIndexMapFromSrcToDest; 
    116   auto& transMap = this->transformationMapping_; 
    117   CArray<size_t,1> globalSrcIndex(transMap.size()); 
    118   int localIndex = 0; 
    119   for (auto it = transMap.begin(); it != transMap.end(); ++it) 
    120   { 
    121     size_t srcIndex = it->second; 
    122     globalIndexMapFromSrcToDest[srcIndex].resize(1); 
    123     globalIndexMapFromSrcToDest[srcIndex][0] = it->first; 
    124     globalSrcIndex(localIndex) = srcIndex; 
    125     ++localIndex; 
    126   } 
    127  
    128   CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, context->intraComm_); 
    129   dhtIndexProcRank.computeIndexInfoMapping(globalSrcIndex); 
    130   CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap(); 
    131   std::unordered_map<int, std::vector<size_t> > globalSrcIndexSendToProc; 
    132   for (int idx = 0; idx < localIndex; ++idx) 
    133   { 
    134     size_t tmpIndex = globalSrcIndex(idx); 
    135     if (1 == computedGlobalIndexOnProc.count(tmpIndex)) 
    136     { 
    137       std::vector<int>& tmpVec = computedGlobalIndexOnProc[tmpIndex]; 
    138       globalSrcIndexSendToProc[tmpVec[0]].push_back(tmpIndex); 
    139     } 
    140   } 
    141  
    142   std::unordered_map<int, std::vector<size_t> >::const_iterator itbIndex = globalSrcIndexSendToProc.begin(), itIndex, 
    143                                                                   iteIndex = globalSrcIndexSendToProc.end(); 
    144   std::map<int,int> sendRankSizeMap,recvRankSizeMap; 
    145   int connectedClient = globalSrcIndexSendToProc.size(); 
    146   int* recvCount=new int[nbClient]; 
    147   int* displ=new int[nbClient]; 
    148   int* sendRankBuff=new int[connectedClient]; 
    149   int* sendSizeBuff=new int[connectedClient]; 
    150   int n = 0; 
    151   for (itIndex = itbIndex; itIndex != iteIndex; ++itIndex, ++n) 
    152   { 
    153     sendRankBuff[n] = itIndex->first; 
    154     int sendSize = itIndex->second.size(); 
    155     sendSizeBuff[n] = sendSize; 
    156     sendRankSizeMap[itIndex->first] = sendSize; 
    157   } 
    158   MPI_Allgather(&connectedClient,1,MPI_INT,recvCount,1,MPI_INT,context->intraComm_); 
    159  
    160   displ[0]=0 ; 
    161   for(int n=1;n<nbClient;n++) displ[n]=displ[n-1]+recvCount[n-1]; 
    162   int recvSize=displ[nbClient-1]+recvCount[nbClient-1]; 
    163   int* recvRankBuff=new int[recvSize]; 
    164   int* recvSizeBuff=new int[recvSize]; 
    165   MPI_Allgatherv(sendRankBuff,connectedClient,MPI_INT,recvRankBuff,recvCount,displ,MPI_INT,context->intraComm_); 
    166   MPI_Allgatherv(sendSizeBuff,connectedClient,MPI_INT,recvSizeBuff,recvCount,displ,MPI_INT,context->intraComm_); 
    167   for (int i = 0; i < nbClient; ++i) 
    168   { 
    169     int currentPos = displ[i]; 
    170     for (int j = 0; j < recvCount[i]; ++j) 
    171       if (recvRankBuff[currentPos+j] == clientRank) 
    172       { 
    173         recvRankSizeMap[i] = recvSizeBuff[currentPos+j]; 
    174       } 
    175   } 
    176  
    177   // Sending global index of grid source to corresponding process as well as the corresponding mask 
    178   std::vector<MPI_Request> requests; 
    179   std::vector<MPI_Status> status; 
    180   std::unordered_map<int, unsigned long* > recvGlobalIndexSrc; 
    181   std::unordered_map<int, double* > sendValueToDest; 
    182   for (std::map<int,int>::const_iterator itRecv = recvRankSizeMap.begin(); itRecv != recvRankSizeMap.end(); ++itRecv) 
    183   { 
    184     int recvRank = itRecv->first; 
    185     int recvSize = itRecv->second; 
    186     recvGlobalIndexSrc[recvRank] = new unsigned long [recvSize]; 
    187     sendValueToDest[recvRank] = new double [recvSize]; 
    188  
    189     requests.push_back(MPI_Request()); 
    190     MPI_Irecv(recvGlobalIndexSrc[recvRank], recvSize, MPI_UNSIGNED_LONG, recvRank, 46, context->intraComm_, &requests.back()); 
    191   } 
    192  
    193   std::unordered_map<int, unsigned long* > sendGlobalIndexSrc; 
    194   std::unordered_map<int, double* > recvValueFromSrc; 
    195   for (itIndex = itbIndex; itIndex != iteIndex; ++itIndex) 
    196   { 
    197     int sendRank = itIndex->first; 
    198     int sendSize = sendRankSizeMap[sendRank]; 
    199     const std::vector<size_t>& sendIndexMap = itIndex->second; 
    200     std::vector<size_t>::const_iterator itbSend = sendIndexMap.begin(), iteSend = sendIndexMap.end(), itSend; 
    201     sendGlobalIndexSrc[sendRank] = new unsigned long [sendSize]; 
    202     recvValueFromSrc[sendRank] = new double [sendSize]; 
    203     int countIndex = 0; 
    204     for (itSend = itbSend; itSend != iteSend; ++itSend) 
    205     { 
    206       sendGlobalIndexSrc[sendRank][countIndex] = *itSend; 
    207       ++countIndex; 
    208     } 
    209  
    210     // Send global index source and mask 
    211     requests.push_back(MPI_Request()); 
    212     MPI_Isend(sendGlobalIndexSrc[sendRank], sendSize, MPI_UNSIGNED_LONG, sendRank, 46, context->intraComm_, &requests.back()); 
    213   } 
    214  
    215   status.resize(requests.size()); 
    216   MPI_Waitall(requests.size(), &requests[0], &status[0]); 
    217  
    218  
    219   std::vector<MPI_Request>().swap(requests); 
    220   std::vector<MPI_Status>().swap(status); 
    221  
    222   // Okie, on destination side, we will wait for information of masked index of source 
    223   for (std::map<int,int>::const_iterator itSend = sendRankSizeMap.begin(); itSend != sendRankSizeMap.end(); ++itSend) 
    224   { 
    225     int recvRank = itSend->first; 
    226     int recvSize = itSend->second; 
    227  
    228     requests.push_back(MPI_Request()); 
    229     MPI_Irecv(recvValueFromSrc[recvRank], recvSize, MPI_DOUBLE, recvRank, 48, context->intraComm_, &requests.back()); 
    230   } 
    231  
    232   for (std::map<int,int>::const_iterator itRecv = recvRankSizeMap.begin(); itRecv != recvRankSizeMap.end(); ++itRecv) 
    233   { 
    234     int recvRank = itRecv->first; 
    235     int recvSize = itRecv->second; 
    236     double* sendValue = sendValueToDest[recvRank]; 
    237     unsigned long* recvIndexSrc = recvGlobalIndexSrc[recvRank]; 
    238     int realSendSize = 0; 
    239     for (int idx = 0; idx < recvSize; ++idx) 
    240     { 
    241       size_t globalIndex = *(recvIndexSrc+idx); 
    242       int localIndex = globalIndex - ibeginSrc; 
    243       *(sendValue + idx) = axisSrc_->value(localIndex); 
    244     } 
    245     // Okie, now inform the destination which source index are masked 
    246     requests.push_back(MPI_Request()); 
    247     MPI_Isend(sendValueToDest[recvRank], recvSize, MPI_DOUBLE, recvRank, 48, context->intraComm_, &requests.back()); 
    248   } 
    249   status.resize(requests.size()); 
    250   MPI_Waitall(requests.size(), &requests[0], &status[0]); 
    251  
    252  
    253   size_t nGloAxisDest = axisDest_->n_glo.getValue() - 1; 
    254   for (std::map<int,int>::const_iterator itSend = sendRankSizeMap.begin(); itSend != sendRankSizeMap.end(); ++itSend) 
    255   { 
    256     int recvRank = itSend->first; 
    257     int recvSize = itSend->second; 
    258  
    259     double* recvValue = recvValueFromSrc[recvRank]; 
    260     unsigned long* recvIndex = sendGlobalIndexSrc[recvRank]; 
    261     for (int idx = 0; idx < recvSize; ++idx) 
    262     { 
    263       size_t globalIndex = *(recvIndex+idx); 
    264       int localIndex = ((nGloAxisDest-globalIndex) - axisDest_->begin); 
    265       axisDest_->value(localIndex) = *(recvValue + idx); 
    266     } 
    267   } 
    268  
    269   delete [] recvCount; 
    270   delete [] displ; 
    271   delete [] sendRankBuff; 
    272   delete [] recvRankBuff; 
    273   delete [] sendSizeBuff; 
    274   delete [] recvSizeBuff; 
    275  
    276   std::unordered_map<int, double* >::const_iterator itChar; 
    277   for (itChar = sendValueToDest.begin(); itChar != sendValueToDest.end(); ++itChar) 
    278     delete [] itChar->second; 
    279   for (itChar = recvValueFromSrc.begin(); itChar != recvValueFromSrc.end(); ++itChar) 
    280     delete [] itChar->second; 
    281   std::unordered_map<int, unsigned long* >::const_iterator itLong; 
    282   for (itLong = sendGlobalIndexSrc.begin(); itLong != sendGlobalIndexSrc.end(); ++itLong) 
    283     delete [] itLong->second; 
    284   for (itLong = recvGlobalIndexSrc.begin(); itLong != recvGlobalIndexSrc.end(); ++itLong) 
    285     delete [] itLong->second; 
    286148} 
    287 CATCH 
    288  
    289 } 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_inverse.hpp

    r2145 r2256  
    1010#define __XIOS_AXIS_ALGORITHM_INVERSE_HPP__ 
    1111 
    12 #include "algorithm_transformation_transfer.hpp" 
     12#include "algorithm_transformation_no_data_modification.hpp" 
    1313#include "transformation.hpp" 
    1414 
     
    2222  Inversing an axis 
    2323*/ 
    24 class CAxisAlgorithmInverse : public CAlgorithmTransformationTransfer 
     24class CAxisAlgorithmInverse : public CAlgorithmTransformationNoDataModification 
    2525{ 
    2626public: 
     
    3636  CAxis* axisSrc_; 
    3737  CAxis* axisDest_; 
    38   void updateAxisValue(); 
    3938 
    4039public: 
Note: See TracChangeset for help on using the changeset viewer.