Changeset 1973


Ignore:
Timestamp:
11/05/20 12:58:34 (3 years ago)
Author:
ymipsl
Message:

Big cleaning on XIOS coupling branch
YM

Location:
XIOS/dev/dev_ym/XIOS_COUPLING/src
Files:
2 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.cpp

    r1934 r1973  
    1 #include "source_filter.hpp" 
    21#include "grid.hpp" 
    32#include "exception.hpp" 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.cpp

    r1956 r1973  
    898898   CATCH_DUMP_ATTR 
    899899 
    900    void CContext::postProcessingGlobalAttributes() 
    901    TRY 
    902    { 
    903      if (allProcessed) return;   
    904       
    905     // create intercommunicator with servers.  
    906     // not sure it is the good place to be called here  
    907     createServerInterComm() ; 
    908  
    909  
    910      // After xml is parsed, there are some more works with post processing 
    911      postProcessing(); 
    912  
    913      // Distribute files between secondary servers according to the data size 
    914      distributeFiles(this->enabledWriteModeFiles); 
    915  
    916      // Check grid and calculate its distribution 
    917      checkGridEnabledFields(); 
    918  
    919      setClientServerBuffer(client, (serviceType_==CServicesManager::CLIENT) ) ; 
    920      for (int i = 0; i < clientPrimServer.size(); ++i) 
    921          setClientServerBuffer(clientPrimServer[i], true); 
    922  
    923      
    924      if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) 
    925      {  
    926        if (serviceType_==CServicesManager::GATHERER) 
    927        {  
    928          for (auto it=clientPrimServer.begin(); it!=clientPrimServer.end();++it)  
    929          { 
    930            this->sendAllAttributesToServer(*it); // Send all attributes of current context to server 
    931            CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(*it); // Send all attributes of current calendar 
    932          } 
    933        } 
    934        else  
    935        { 
    936          this->sendAllAttributesToServer(client);   // Send all attributes of current context to server 
    937          CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(client); // Send all attributes of current calendar 
    938        } 
    939  
    940  
    941       // We have enough information to send to server 
    942       // First of all, send all enabled files 
    943       sendEnabledFiles(this->enabledWriteModeFiles); 
    944       // We only use server-level 1 (for now) to read data 
    945       if (serviceType_==CServicesManager::CLIENT)  sendEnabledFiles(this->enabledReadModeFiles); 
    946  
    947       // Then, send all enabled fields       
    948       sendEnabledFieldsInFiles(this->enabledWriteModeFiles); 
    949        
    950       if (serviceType_==CServicesManager::CLIENT) sendEnabledFieldsInFiles(this->enabledReadModeFiles); 
    951  
    952       // Then, check whether we have domain_ref, axis_ref or scalar_ref attached to the enabled fields 
    953       // If any, so send them to server 
    954        sendRefDomainsAxisScalars(this->enabledWriteModeFiles);  
    955       
    956       if (serviceType_==CServicesManager::CLIENT) sendRefDomainsAxisScalars(this->enabledReadModeFiles);         
    957  
    958        // Check whether enabled fields have grid_ref, if any, send this info to server 
    959       sendRefGrid(this->enabledFiles); 
    960       // This code may be useful in the future when we want to seperate completely read and write 
    961       // sendRefGrid(this->enabledWriteModeFiles); 
    962       // if (!hasServer) 
    963       //   sendRefGrid(this->enabledReadModeFiles); 
    964        
    965       // A grid of enabled fields composed of several components which must be checked then their 
    966       // checked attributes should be sent to server 
    967       sendGridComponentEnabledFieldsInFiles(this->enabledFiles); // This code can be seperated in two (one for reading, another for writing) 
    968  
    969        // We have a xml tree on the server side and now, it should be also processed 
    970       sendPostProcessing(); 
    971         
    972       // Finally, we send information of grid itself to server  
    973       sendGridEnabledFieldsInFiles(this->enabledWriteModeFiles);        
    974       
    975       if (serviceType_==CServicesManager::CLIENT) sendGridEnabledFieldsInFiles(this->enabledReadModeFiles);        
    976       
    977      } 
    978      allProcessed = true; 
    979    } 
    980    CATCH_DUMP_ATTR 
    981  
    982    void CContext::sendPostProcessingGlobalAttributes() 
    983    TRY 
    984    { 
    985  
    986     int nbSrvPools ; 
    987     if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ; 
    988     else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ; 
    989     else nbSrvPools = 0 ; 
    990     CContextClient* contextClientTmp ; 
    991  
    992     for (int i = 0; i < nbSrvPools; ++i) 
    993      { 
    994        if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ; 
    995        else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ; 
    996        
    997        CEventClient event(getType(),EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES); 
    998  
    999        if (contextClientTmp->isServerLeader()) 
    1000        { 
    1001          CMessage msg; 
    1002          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    1003          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1004            event.push(*itRank,1,msg); 
    1005          contextClientTmp->sendEvent(event); 
    1006        } 
    1007        else contextClientTmp->sendEvent(event); 
    1008      } 
    1009    } 
    1010    CATCH_DUMP_ATTR 
    1011  
    1012    void CContext::recvPostProcessingGlobalAttributes(CEventServer& event) 
    1013    TRY 
    1014    { 
    1015       CBufferIn* buffer=event.subEvents.begin()->buffer; 
    1016       getCurrent()->recvPostProcessingGlobalAttributes(*buffer); 
    1017    } 
    1018    CATCH 
    1019  
    1020    void CContext::recvPostProcessingGlobalAttributes(CBufferIn& buffer) 
    1021    TRY 
    1022    {       
    1023       postProcessingGlobalAttributes(); 
    1024    } 
    1025    CATCH_DUMP_ATTR 
    1026  
     900    
    1027901   /*! 
    1028902   \brief Close all the context defintion and do processing data 
     
    11361010      for(auto field : couplerOutField)  
    11371011      { 
    1138         field->computeGridIndexToFileServer() ; // same kind of index than for file server -> in future distribution may change 
    1139       } 
    1140       if (first) setClientServerBuffer(couplerOutField, true) ; // set buffer context 
    1141  
     1012        // connect to couplerOut -> to do 
     1013      } 
     1014      if (first) setClientServerBuffer(couplerOutField, true) ; // set buffer context --> to check 
     1015    
    11421016      bool couplersReady ; 
    11431017      do  
     
    11791053      { 
    11801054        field->connectToFileServer(garbageCollector) ; // connect the field to server filter 
    1181         field->computeGridIndexToFileServer() ; // compute grid index for transfer to the server context 
    1182       } 
    1183       setClientServerBuffer(fileOutField, true) ; // set buffer context 
     1055      } 
     1056      setClientServerBuffer(fileOutField, true) ; // set buffer context --> to review 
    11841057      for(auto field : fileOutField) field->sendFieldToFileServer() ; 
    11851058    } 
     
    12471120      { 
    12481121        field->connectToServerInput(garbageCollector) ; // connect the field to server filter 
    1249     // obsolete    field->computeGridIndexToFileServer() ; // compute grid index for transfer to the server context 
    12501122        field->sendFieldToInputFileServer() ; 
    12511123        fileInFields_.push_back(field) ; 
     
    12911163    } while (!ok) ; 
    12921164 
    1293     return ; 
    1294  
    1295  
    1296  
    1297  
    1298  
    1299  
    1300  
    1301  
    1302  
    1303  
    1304     // For now, only read files with client and only one level server 
    1305     // if (hasClient && !hasServer) findEnabledReadModeFiles();       
    1306  
    1307     // Find all enabled fields of each file       
    1308     findAllEnabledFieldsInFiles(this->enabledWriteModeFiles); 
    1309     findAllEnabledFieldsInFiles(this->enabledReadModeFiles); 
    1310  
    1311     // For now, only read files with client and only one level server 
    1312     // if (hasClient && !hasServer)  
    1313     //   findAllEnabledFieldsInFiles(this->enabledReadModeFiles);       
    1314  
    1315     if (serviceType_==CServicesManager::CLIENT) 
    1316     { 
    1317       initReadFiles(); 
    1318       // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis) 
    1319       this->readAttributesOfEnabledFieldsInReadModeFiles(); 
    1320     } 
    1321  
    1322     // Only search and rebuild all reference objects of enable fields, don't transform 
    1323     this->solveOnlyRefOfEnabledFields(); 
    1324  
    1325     // Search and rebuild all reference object of enabled fields, and transform 
    1326     this->solveAllRefOfEnabledFieldsAndTransform(); 
    1327  
    1328     // Find all fields with read access from the public API 
    1329     if (serviceType_==CServicesManager::CLIENT) findFieldsWithReadAccess(); 
    1330     // and solve the all reference for them 
    1331     if (serviceType_==CServicesManager::CLIENT) solveAllRefOfFieldsWithReadAccess(); 
    1332  
    1333     isPostProcessed = true; 
    1334  
    1335  
    1336  
    1337     // Distribute files between secondary servers according to the data size 
    1338     distributeFiles(this->enabledWriteModeFiles); 
    1339  
    1340     // Check grid and calculate its distribution 
    1341     checkGridEnabledFields(); 
    1342  
    1343     setClientServerBuffer(client, (serviceType_==CServicesManager::CLIENT) ) ; 
    1344     for (int i = 0; i < clientPrimServer.size(); ++i) 
    1345          setClientServerBuffer(clientPrimServer[i], true); 
    1346  
    1347      
    1348     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) 
    1349     {  
    1350       if (serviceType_==CServicesManager::GATHERER) 
    1351       {  
    1352         for (auto it=clientPrimServer.begin(); it!=clientPrimServer.end();++it)  
    1353         { 
    1354           this->sendAllAttributesToServer(*it); // Send all attributes of current context to server 
    1355           CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(*it); // Send all attributes of current calendar 
    1356         } 
    1357       } 
    1358       else  
    1359       { 
    1360         this->sendAllAttributesToServer(client);   // Send all attributes of current context to server 
    1361         CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(client); // Send all attributes of current calendar 
    1362       } 
    1363  
    1364       // We have enough information to send to server 
    1365       // First of all, send all enabled files 
    1366       sendEnabledFiles(this->enabledWriteModeFiles); 
    1367       // We only use server-level 1 (for now) to read data 
    1368       if (serviceType_==CServicesManager::CLIENT)  sendEnabledFiles(this->enabledReadModeFiles); 
    1369  
    1370       // Then, send all enabled fields       
    1371       sendEnabledFieldsInFiles(this->enabledWriteModeFiles); 
    1372        
    1373       if (serviceType_==CServicesManager::CLIENT) sendEnabledFieldsInFiles(this->enabledReadModeFiles); 
    1374  
    1375       // Then, check whether we have domain_ref, axis_ref or scalar_ref attached to the enabled fields 
    1376       // If any, so send them to server 
    1377       sendRefDomainsAxisScalars(this->enabledWriteModeFiles);  
    1378       
    1379       if (serviceType_==CServicesManager::CLIENT) sendRefDomainsAxisScalars(this->enabledReadModeFiles);         
    1380  
    1381       // Check whether enabled fields have grid_ref, if any, send this info to server 
    1382       sendRefGrid(this->enabledFiles); 
    1383       // This code may be useful in the future when we want to seperate completely read and write 
    1384       // sendRefGrid(this->enabledWriteModeFiles); 
    1385       // if (!hasServer) 
    1386       //   sendRefGrid(this->enabledReadModeFiles); 
    1387        
    1388       // A grid of enabled fields composed of several components which must be checked then their 
    1389       // checked attributes should be sent to server 
    1390       sendGridComponentEnabledFieldsInFiles(this->enabledFiles); // This code can be seperated in two (one for reading, another for writing) 
    1391  
    1392       // We have a xml tree on the server side and now, it should be also processed 
    1393       sendPostProcessing(); 
    1394         
    1395       // Finally, we send information of grid itself to server  
    1396       sendGridEnabledFieldsInFiles(this->enabledWriteModeFiles);        
    1397       
    1398       if (serviceType_==CServicesManager::CLIENT) sendGridEnabledFieldsInFiles(this->enabledReadModeFiles);        
    1399     } 
    1400     allProcessed = true; 
    1401  
    1402  
    1403     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendPostProcessingGlobalAttributes(); 
    1404  
    1405     // There are some processings that should be done after all of above. For example: check mask or index 
    1406     this->buildFilterGraphOfEnabledFields(); 
    1407      
    1408      if (serviceType_==CServicesManager::CLIENT) 
    1409     { 
    1410       buildFilterGraphOfFieldsWithReadAccess(); 
    1411       postProcessFilterGraph(); // For coupling in, modify this later 
    1412     } 
    1413      
    1414     checkGridEnabledFields();    
    1415  
    1416     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendProcessingGridOfEnabledFields(); 
    1417     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendCloseDefinition(); 
    1418  
    1419     // Nettoyage de l'arborescence 
    1420     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) CleanTree(); // Only on client side?? 
    1421  
    1422     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendCreateFileHeader(); 
    1423     if (serviceType_==CServicesManager::CLIENT) startPrefetchingOfEnabledReadModeFiles(); 
    1424      
    1425     CTimer::get("Context : close definition").suspend() ; 
     1165     CTimer::get("Context : close definition").suspend() ; 
    14261166  } 
    14271167  CATCH_DUMP_ATTR 
     1168 
     1169 
     1170  vector<CField*> CContext::findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles) 
     1171   TRY 
     1172   { 
     1173     vector<CField*> fields ; 
     1174     for(auto file : activeFiles) 
     1175     { 
     1176        const vector<CField*>&& fieldList=file->getEnabledFields() ; 
     1177        for(auto field : fieldList) field->setFileOut(file) ; 
     1178        fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
     1179     } 
     1180     return fields ; 
     1181   } 
     1182   CATCH_DUMP_ATTR 
     1183 
     1184   vector<CField*> CContext::findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles) 
     1185   TRY 
     1186   { 
     1187     vector<CField*> fields ; 
     1188     for(auto file : activeFiles) 
     1189     { 
     1190        const vector<CField*>&& fieldList=file->getEnabledFields() ; 
     1191        for(auto field : fieldList) field->setFileIn(file) ; 
     1192        fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
     1193     } 
     1194     return fields ; 
     1195   } 
     1196   CATCH_DUMP_ATTR 
     1197 
     1198   vector<CField*> CContext::findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut) 
     1199   TRY 
     1200   { 
     1201     vector<CField*> fields ; 
     1202     for (auto couplerOut :activeCouplerOut) 
     1203     { 
     1204        const vector<CField*>&& fieldList=couplerOut->getEnabledFields() ; 
     1205        for(auto field : fieldList) field->setCouplerOut(couplerOut) ; 
     1206        fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
     1207     } 
     1208     return fields ; 
     1209   } 
     1210   CATCH_DUMP_ATTR 
     1211 
     1212   vector<CField*> CContext::findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn) 
     1213   TRY 
     1214   { 
     1215     vector<CField*> fields ; 
     1216     for (auto couplerIn :activeCouplerIn) 
     1217     { 
     1218        const vector<CField*>&& fieldList=couplerIn->getEnabledFields() ; 
     1219        for(auto field : fieldList) field->setCouplerIn(couplerIn) ; 
     1220        fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
     1221     } 
     1222     return fields ; 
     1223   } 
     1224   CATCH_DUMP_ATTR 
    14281225 
    14291226 /*! 
     
    14401237  } 
    14411238 
    1442   // ym obsolete now to be removed 
    1443    void CContext::closeDefinition_old(void) 
    1444    TRY 
    1445    { 
    1446      CTimer::get("Context : close definition").resume() ; 
    1447      
    1448     // 
    1449     postProcessingGlobalAttributes(); 
    1450  
    1451     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendPostProcessingGlobalAttributes(); 
    1452  
    1453     // There are some processings that should be done after all of above. For example: check mask or index 
    1454     this->buildFilterGraphOfEnabledFields(); 
    1455      
    1456      if (serviceType_==CServicesManager::CLIENT) 
    1457     { 
    1458       buildFilterGraphOfFieldsWithReadAccess(); 
    1459       postProcessFilterGraph(); // For coupling in, modify this later 
    1460     } 
    1461      
    1462     checkGridEnabledFields();    
    1463  
    1464     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendProcessingGridOfEnabledFields(); 
    1465     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendCloseDefinition(); 
    1466  
    1467     // Nettoyage de l'arborescence 
    1468     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) CleanTree(); // Only on client side?? 
    1469  
    1470     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendCreateFileHeader(); 
    1471     if (serviceType_==CServicesManager::CLIENT) startPrefetchingOfEnabledReadModeFiles(); 
    1472      
    1473     CTimer::get("Context : close definition").suspend() ; 
    1474    } 
    1475    CATCH_DUMP_ATTR 
    1476  
    1477    vector<CField*> CContext::findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
    1478    TRY 
    1479    { 
    1480      vector<CField*> fields ; 
    1481      for (unsigned int i = 0; i < activeFiles.size(); i++) 
    1482      { 
    1483         const vector<CField*>&& field=activeFiles[i]->getEnabledFields() ; 
    1484         fields.insert(fields.end(),field.begin(),field.end()); 
    1485      } 
    1486      return fields ; 
    1487    } 
    1488    CATCH_DUMP_ATTR 
    1489  
    1490    vector<CField*> CContext::findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles) 
    1491    TRY 
    1492    { 
    1493      vector<CField*> fields ; 
    1494      for(auto file : activeFiles) 
    1495      { 
    1496         const vector<CField*>&& fieldList=file->getEnabledFields() ; 
    1497         for(auto field : fieldList) field->setFileOut(file) ; 
    1498         fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
    1499      } 
    1500      return fields ; 
    1501    } 
    1502    CATCH_DUMP_ATTR 
    1503  
    1504    vector<CField*> CContext::findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles) 
    1505    TRY 
    1506    { 
    1507      vector<CField*> fields ; 
    1508      for(auto file : activeFiles) 
    1509      { 
    1510         const vector<CField*>&& fieldList=file->getEnabledFields() ; 
    1511         for(auto field : fieldList) field->setFileIn(file) ; 
    1512         fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
    1513      } 
    1514      return fields ; 
    1515    } 
    1516    CATCH_DUMP_ATTR 
    1517  
    1518    vector<CField*> CContext::findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut) 
    1519    TRY 
    1520    { 
    1521      vector<CField*> fields ; 
    1522      for (auto couplerOut :activeCouplerOut) 
    1523      { 
    1524         const vector<CField*>&& fieldList=couplerOut->getEnabledFields() ; 
    1525         for(auto field : fieldList) field->setCouplerOut(couplerOut) ; 
    1526         fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
    1527      } 
    1528      return fields ; 
    1529    } 
    1530    CATCH_DUMP_ATTR 
    1531  
    1532    vector<CField*> CContext::findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn) 
    1533    TRY 
    1534    { 
    1535      vector<CField*> fields ; 
    1536      for (auto couplerIn :activeCouplerIn) 
    1537      { 
    1538         const vector<CField*>&& fieldList=couplerIn->getEnabledFields() ; 
    1539         for(auto field : fieldList) field->setCouplerIn(couplerIn) ; 
    1540         fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
    1541      } 
    1542      return fields ; 
    1543    } 
    1544    CATCH_DUMP_ATTR 
    1545  
    1546  
    1547  
     1239  
    15481240   void CContext::readAttributesOfEnabledFieldsInReadModeFiles() 
    15491241   TRY 
     
    21101802             return true; 
    21111803             break; 
    2112            case EVENT_ID_POST_PROCESS: 
    2113              recvPostProcessing(event); 
    2114              return true; 
    21151804           case EVENT_ID_SEND_REGISTRY: 
    21161805             recvRegistry(event); 
    2117              return true; 
    2118              break; 
    2119            case EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES: 
    2120              recvPostProcessingGlobalAttributes(event); 
    2121              return true; 
    2122              break; 
    2123            case EVENT_ID_PROCESS_GRID_ENABLED_FIELDS: 
    2124              recvProcessingGridOfEnabledFields(event); 
    21251806             return true; 
    21261807             break; 
     
    22881969      if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::OUT_SERVER)  
    22891970        createFileHeader(); 
    2290    } 
    2291    CATCH_DUMP_ATTR 
    2292  
    2293    //! Client side: Send a message to do some post processing on server 
    2294    void CContext::sendProcessingGridOfEnabledFields() 
    2295    TRY 
    2296    { 
    2297      int nbSrvPools ; 
    2298      if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ; 
    2299      else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ; 
    2300      else nbSrvPools = 0 ; 
    2301      CContextClient* contextClientTmp ; 
    2302  
    2303      for (int i = 0; i < nbSrvPools; ++i) 
    2304      { 
    2305        if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ; 
    2306        else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ; 
    2307  
    2308        CEventClient event(getType(),EVENT_ID_PROCESS_GRID_ENABLED_FIELDS); 
    2309  
    2310        if (contextClientTmp->isServerLeader()) 
    2311        { 
    2312          CMessage msg; 
    2313          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    2314          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    2315            event.push(*itRank,1,msg); 
    2316          contextClientTmp->sendEvent(event); 
    2317        } 
    2318        else contextClientTmp->sendEvent(event); 
    2319      } 
    2320    } 
    2321    CATCH_DUMP_ATTR 
    2322  
    2323    //! Server side: Receive a message to do some post processing 
    2324    void CContext::recvProcessingGridOfEnabledFields(CEventServer& event) 
    2325    TRY 
    2326    { 
    2327       CBufferIn* buffer=event.subEvents.begin()->buffer; 
    2328       // nothing to do, no call ??!!     
    2329    } 
    2330    CATCH 
    2331  
    2332    //! Client side: Send a message to do some post processing on server 
    2333    void CContext::sendPostProcessing() 
    2334    TRY 
    2335    { 
    2336      int nbSrvPools ; 
    2337      if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ; 
    2338      else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ; 
    2339      else nbSrvPools = 0 ; 
    2340      CContextClient* contextClientTmp ; 
    2341  
    2342      for (int i = 0; i < nbSrvPools; ++i) 
    2343      { 
    2344        if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ; 
    2345        else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ; 
    2346        CEventClient event(getType(),EVENT_ID_POST_PROCESS); 
    2347        if (contextClientTmp->isServerLeader()) 
    2348        { 
    2349          CMessage msg; 
    2350          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    2351          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    2352          event.push(*itRank,1,msg); 
    2353          contextClientTmp->sendEvent(event); 
    2354        } 
    2355        else contextClientTmp->sendEvent(event); 
    2356      } 
    2357    } 
    2358    CATCH_DUMP_ATTR 
    2359  
    2360    //! Server side: Receive a message to do some post processing 
    2361    void CContext::recvPostProcessing(CEventServer& event) 
    2362    TRY 
    2363    { 
    2364       CBufferIn* buffer=event.subEvents.begin()->buffer; 
    2365       getCurrent()->recvPostProcessing(*buffer); 
    2366    } 
    2367    CATCH 
    2368  
    2369    //! Server side: Receive a message to do some post processing 
    2370    void CContext::recvPostProcessing(CBufferIn& buffer) 
    2371    TRY 
    2372    { 
    2373       CCalendarWrapper::get(CCalendarWrapper::GetDefName())->createCalendar(); 
    2374       postProcessing(); 
    2375    } 
    2376    CATCH_DUMP_ATTR 
    2377  
    2378   
    2379    /*! 
    2380    \brief Do some simple post processings after parsing xml file 
    2381       After the xml file (iodef.xml) is parsed, it is necessary to build all relations among 
    2382    created object, e.g: inhertance among fields, domain, axis. After that, all fiels as well as their parents (reference fields), 
    2383    which will be written out into netcdf files, are processed 
    2384    */ 
    2385    void CContext::postProcessing() 
    2386    TRY 
    2387    { 
    2388      if (isPostProcessed) return; 
    2389  
    2390       // Make sure the calendar was correctly created 
    2391       if (!calendar) 
    2392         ERROR("CContext::postProcessing()", << "A calendar must be defined for the context \"" << getId() << "!\"") 
    2393       else if (calendar->getTimeStep() == NoneDu) 
    2394         ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"") 
    2395       // Calendar first update to set the current date equals to the start date 
    2396       calendar->update(0); 
    2397  
    2398       // Find all inheritance in xml structure 
    2399       this->solveAllInheritance(); 
    2400  
    2401 //      ShowTree(info(10)); 
    2402  
    2403       // Check if some axis, domains or grids are eligible to for compressed indexed output. 
    2404       // Warning: This must be done after solving the inheritance and before the rest of post-processing 
    2405       //checkAxisDomainsGridsEligibilityForCompressedOutput();      // only for field written on IO_SERVER service ???? 
    2406  
    2407       // Check if some automatic time series should be generated 
    2408       // Warning: This must be done after solving the inheritance and before the rest of post-processing       
    2409       prepareTimeseries(); 
    2410  
    2411       //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers à sortir. 
    2412       findEnabledFiles(); 
    2413       findEnabledWriteModeFiles(); 
    2414       findEnabledReadModeFiles(); 
    2415       findEnabledCouplerIn(); 
    2416       findEnabledCouplerOut(); 
    2417       createCouplerInterCommunicator() ; 
    2418  
    2419       // Find all enabled fields of each file       
    2420       const vector<CField*>&& fileOutField = findAllEnabledFieldsInFiles(this->enabledWriteModeFiles); 
    2421       const vector<CField*>&& fileInField = findAllEnabledFieldsInFiles(this->enabledReadModeFiles); 
    2422       const vector<CField*>&& CouplerOutField = findAllEnabledFieldsCouplerOut(this->enabledCouplerOut); 
    2423       const vector<CField*>&& CouplerInField = findAllEnabledFieldsCouplerIn(this->enabledCouplerIn); 
    2424  
    2425  
    2426  
    2427       // For now, only read files with client and only one level server 
    2428       // if (hasClient && !hasServer) findEnabledReadModeFiles();       
    2429  
    2430  
    2431       // For now, only read files with client and only one level server 
    2432       // if (hasClient && !hasServer)  
    2433       //   findAllEnabledFieldsInFiles(this->enabledReadModeFiles);       
    2434  
    2435       if (serviceType_==CServicesManager::CLIENT) 
    2436       { 
    2437         initReadFiles(); 
    2438         // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis) 
    2439         this->readAttributesOfEnabledFieldsInReadModeFiles(); 
    2440       } 
    2441  
    2442       // Only search and rebuild all reference objects of enable fields, don't transform 
    2443       this->solveOnlyRefOfEnabledFields(); 
    2444  
    2445       // Search and rebuild all reference object of enabled fields, and transform 
    2446       this->solveAllRefOfEnabledFieldsAndTransform(); 
    2447  
    2448       // Find all fields with read access from the public API 
    2449       if (serviceType_==CServicesManager::CLIENT) findFieldsWithReadAccess(); 
    2450       // and solve the all reference for them 
    2451       if (serviceType_==CServicesManager::CLIENT) solveAllRefOfFieldsWithReadAccess(); 
    2452  
    2453       isPostProcessed = true; 
    24541971   } 
    24551972   CATCH_DUMP_ATTR 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp

    r1956 r1973  
    5353           EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR, 
    5454           EVENT_ID_CREATE_FILE_HEADER,EVENT_ID_CONTEXT_FINALIZE, 
    55            EVENT_ID_POST_PROCESS, EVENT_ID_SEND_REGISTRY, 
    56            EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES, 
    57            EVENT_ID_PROCESS_GRID_ENABLED_FIELDS, 
     55           EVENT_ID_SEND_REGISTRY, 
    5856           EVENT_ID_CONTEXT_FINALIZE_CLIENT, 
    5957           EVENT_ID_COUPLER_IN_READY, 
     
    117115 
    118116         void closeDefinition(void); 
    119          void closeDefinition_old(void); 
    120117 
    121118         // to be removed      
     
    140137         void createFileHeader(void); 
    141138         void initReadFiles(void); 
    142         void prepareTimeseries(void); 
     139         void prepareTimeseries(void); 
    143140         void solveOnlyRefOfEnabledFields(void);          
    144141         void buildFilterGraphOfEnabledFields(); 
     
    150147         void solveAllRefOfFieldsWithReadAccess(); 
    151148         void buildFilterGraphOfFieldsWithReadAccess(); 
    152          void postProcessing(); 
    153          void postProcessingGlobalAttributes();          
    154149         void triggerLateFields(void) ; 
    155150         void solveAllRefOfEnabledFieldsAndTransform(void); 
     
    183178         void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles); 
    184179         void sendRefGrid(const std::vector<CFile*>& activeFiles); 
    185          void sendPostProcessing(); 
    186          void sendPostProcessingGlobalAttributes(); 
    187          void sendProcessingGridOfEnabledFields(); 
    188180         //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers 
    189181         void sendRegistry(void) ; 
     
    206198         static void recvSolveInheritanceContext(CEventServer& event); 
    207199         void recvSolveInheritanceContext(CBufferIn& buffer); 
    208          static void recvPostProcessing(CEventServer& event); 
    209          void recvPostProcessing(CBufferIn& buffer); 
    210          static void recvProcessingGridOfEnabledFields(CEventServer& event); 
    211          static void recvPostProcessingGlobalAttributes(CEventServer& event); 
    212          void recvPostProcessingGlobalAttributes(CBufferIn& buffer); 
    213200         static void recvRegistry(CEventServer& event) ; 
    214201         void recvRegistry(CBufferIn& buffer) ; //!< registry is received by the servers 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp

    r1962 r1973  
    1515#include <set> 
    1616#include "garbage_collector.hpp" 
    17 #include "source_filter.hpp" 
    1817#include "pass_through_filter.hpp" 
    1918#include "filter_expr_node.hpp" 
     
    624623    } 
    625624 
    626     solveCheckMaskIndex(doSending2Server); 
    627625  } 
    628626  CATCH_DUMP_ATTR 
     
    865863  }  
    866864 
    867   /*! 
    868    * Compute grid index needed to send grid and data to server 
    869    */ 
    870   void CField::computeGridIndexToFileServer(void) 
    871   { 
    872     grid_->computeGridIndexToFileServer(client) ; 
    873   } 
    874  
     865  
    875866  /*! 
    876867   * Connect field to a source filter to receive data from model. 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp

    r1962 r1973  
    240240        void connectToServerToClient(CGarbageCollector& gc) ; 
    241241 
    242         void computeGridIndexToFileServer(void) ; 
    243  
    244242        void setContextClientDataBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize,  
    245243                                        map<CContextClient*,map<int,size_t>>& maxEventSize,  
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field_impl.hpp

    r1949 r1973  
    99#include "timer.hpp" 
    1010#include "array_new.hpp" 
    11 #include "source_filter.hpp" 
    1211 
    1312 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp

    r1960 r1973  
    3636      , vAxisGroup_(), axisList_(), isAxisListSet(false) 
    3737      , vScalarGroup_(), scalarList_(), isScalarListSet(false) 
    38       , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    39       , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
     38      , clientDistribution_(0), isIndexSent(false) 
    4039      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 
    4140            , isCompressible_(false) 
    4241      , transformations_(0), isTransformed_(false) 
    4342      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    44       , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
    45       , computedWrittenIndex_(false) 
     43      , gridSrc_(), hasTransform_(false), isGenerated_(false), order_() 
    4644      , clients() 
    4745   { 
     
    5755      , vAxisGroup_(), axisList_(), isAxisListSet(false) 
    5856      , vScalarGroup_(), scalarList_(), isScalarListSet(false) 
    59       , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    60       , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
     57      , clientDistribution_(0), isIndexSent(false) 
    6158      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 
    6259            , isCompressible_(false) 
    6360      , transformations_(0), isTransformed_(false) 
    6461      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    65       , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
    66       , computedWrittenIndex_(false) 
     62      , gridSrc_(), hasTransform_(false), isGenerated_(false), order_() 
    6763      , clients() 
    6864   { 
     
    7571   { 
    7672    if (0 != clientDistribution_) delete clientDistribution_; 
    77     if (0 != serverDistribution_) delete serverDistribution_; 
    78     if (0 != clientServerMap_) delete clientServerMap_; 
    7973    if (0 != transformations_) delete transformations_; 
    8074   } 
     
    859853     this->checkAttributesAfterTransformation(); 
    860854 
    861      // TODO: Transfer grid attributes 
    862      //if (!context->hasClient && context->hasServer) this->createMask(); 
    863      this->computeIndex(); 
    864  
    865855     if (!(this->hasTransform() && !this->isTransformed())) 
    866856      this->isChecked = true; 
     
    897887      return mask_ ; 
    898888   } 
    899    /* 
    900      Create mask of grid from mask of its components 
    901    */ 
    902    void CGrid::createMask(void) 
    903    TRY 
    904    { 
    905       using namespace std; 
    906       std::vector<CDomain*> domainP = this->getDomains(); 
    907       std::vector<CAxis*> axisP = this->getAxis(); 
    908       int dim = domainP.size() * 2 + axisP.size(); 
    909  
    910       std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 
    911       for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 
    912       std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 
    913       for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 
    914  
    915       switch (dim) { 
    916         case 1: 
    917           checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order, true); 
    918           break; 
    919         case 2: 
    920           checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order, true); 
    921           break; 
    922         case 3: 
    923           checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order, true); 
    924           break; 
    925         case 4: 
    926           checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order, true); 
    927           break; 
    928         case 5: 
    929           checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order, true); 
    930           break; 
    931         case 6: 
    932           checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order, true); 
    933           break; 
    934         case 7: 
    935           checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order, true); 
    936           break; 
    937         default: 
    938           break; 
    939       } 
    940    } 
    941    CATCH_DUMP_ATTR 
    942  
    943    /* 
    944      Check validity of grid's mask by using the masks of its components 
    945    */ 
    946    void CGrid::checkMask(void) 
    947    TRY 
    948    { 
    949       using namespace std; 
    950       std::vector<CDomain*> domainP = this->getDomains(); 
    951       std::vector<CAxis*> axisP = this->getAxis(); 
    952       int dim = domainP.size() * 2 + axisP.size(); 
    953  
    954       std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 
    955       for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 
    956       std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 
    957       for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 
    958  
    959       switch (dim) { 
    960         case 1: 
    961           checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order); 
    962           break; 
    963         case 2: 
    964           checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order); 
    965           break; 
    966         case 3: 
    967           checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order); 
    968           break; 
    969         case 4: 
    970           checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order); 
    971           break; 
    972         case 5: 
    973           checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order); 
    974           break; 
    975         case 6: 
    976           checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order); 
    977           break; 
    978         case 7: 
    979           checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order); 
    980           break; 
    981         default: 
    982           break; 
    983       } 
    984    } 
    985    CATCH_DUMP_ATTR 
    986  
    987    /* 
    988      Modify value of mask in a certain index 
    989      This function can be used to correct the mask of grid after being constructed with createMask 
    990      \param [in] indexToModify 
    991      \param [in] modifyValue 
    992    */ 
    993    void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue) 
    994    TRY 
    995    { 
    996       using namespace std; 
    997       std::vector<CDomain*> domainP = this->getDomains(); 
    998       std::vector<CAxis*> axisP = this->getAxis(); 
    999       int dim = domainP.size() * 2 + axisP.size(); 
    1000  
    1001       switch (dim) { 
    1002         case 0: 
    1003           modifyGridMask(mask_0d, indexToModify, modifyValue); 
    1004           break; 
    1005         case 1: 
    1006           modifyGridMask(mask_1d, indexToModify, modifyValue); 
    1007           break; 
    1008         case 2: 
    1009           modifyGridMask(mask_2d, indexToModify, modifyValue); 
    1010           break; 
    1011         case 3: 
    1012           modifyGridMask(mask_3d, indexToModify, modifyValue); 
    1013           break; 
    1014         case 4: 
    1015           modifyGridMask(mask_4d, indexToModify, modifyValue); 
    1016           break; 
    1017         case 5: 
    1018           modifyGridMask(mask_5d, indexToModify, modifyValue); 
    1019           break; 
    1020         case 6: 
    1021           modifyGridMask(mask_6d, indexToModify, modifyValue); 
    1022           break; 
    1023         case 7: 
    1024           modifyGridMask(mask_7d, indexToModify, modifyValue); 
    1025           break; 
    1026         default: 
    1027           break; 
    1028       } 
    1029    } 
    1030    CATCH_DUMP_ATTR 
    1031  
    1032    /* 
    1033      Change the mask size. This function is used on reconstructing mask in server side 
    1034      \param [in] newDimensionSize 
    1035      \param [in] newValue  
    1036    */ 
    1037    void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue) 
    1038    TRY 
    1039    {       
    1040       std::vector<CDomain*> domainP = this->getDomains(); 
    1041       std::vector<CAxis*> axisP = this->getAxis();             
    1042       int dim = domainP.size() * 2 + axisP.size(); 
    1043  
    1044       switch (dim) { 
    1045         case 0: 
    1046           modifyGridMaskSize(mask_0d, newDimensionSize, newValue); 
    1047           break; 
    1048         case 1: 
    1049           modifyGridMaskSize(mask_1d, newDimensionSize, newValue); 
    1050           break; 
    1051         case 2: 
    1052           modifyGridMaskSize(mask_2d, newDimensionSize, newValue); 
    1053           break; 
    1054         case 3: 
    1055           modifyGridMaskSize(mask_3d, newDimensionSize, newValue); 
    1056           break; 
    1057         case 4: 
    1058           modifyGridMaskSize(mask_4d, newDimensionSize, newValue); 
    1059           break; 
    1060         case 5: 
    1061           modifyGridMaskSize(mask_5d, newDimensionSize, newValue); 
    1062           break; 
    1063         case 6: 
    1064           modifyGridMaskSize(mask_6d, newDimensionSize, newValue); 
    1065           break; 
    1066         case 7: 
    1067           modifyGridMaskSize(mask_7d, newDimensionSize, newValue); 
    1068           break; 
    1069         default: 
    1070           break; 
    1071       } 
    1072    } 
    1073    CATCH_DUMP_ATTR 
    1074  
     889 
     890   
    1075891   //--------------------------------------------------------------- 
    1076892 
     
    1130946   CATCH_DUMP_ATTR 
    1131947 
    1132    /*! 
    1133       Compute the index to for write data into a file 
    1134    */ 
    1135    void CGrid::computeWrittenIndex() 
    1136    TRY 
    1137    {       
    1138       if (computedWrittenIndex_) return; 
    1139       computedWrittenIndex_ = true; 
    1140  
    1141       if (isScalarGrid()) 
    1142       { 
    1143         size_t nbWritten = 1; 
    1144         int writtenIndex = 0; 
    1145  
    1146         localIndexToWriteOnClient_.resize(nbWritten);   
    1147         localIndexToWriteOnServer_.resize(nbWritten); 
    1148         localIndexToWriteOnServer_(0) = writtenIndex; 
    1149         localIndexToWriteOnClient_(0) = writtenIndex; 
    1150          
    1151         return; 
    1152       } 
    1153  
    1154       size_t nbWritten = 0, indGlo; 
    1155       CDistributionClient::GlobalLocalDataMap& globalDataIndex = getClientDistribution()->getGlobalDataIndexOnClient(); 
    1156       CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(), 
    1157                                                               ite = globalDataIndex.end(), it;     
    1158       const CDistributionServer::GlobalLocalMap& globalLocalIndex = serverDistribution_->getGlobalLocalIndex();                                                               
    1159       CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(), 
    1160                                                           itSrve = globalLocalIndex.end(), itSrv; 
    1161       for (it = itb; it != ite; ++it) 
    1162       { 
    1163         indGlo = it->first; 
    1164         if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten;                 
    1165       } 
    1166  
    1167       localIndexToWriteOnClient_.resize(nbWritten);   
    1168       localIndexToWriteOnServer_.resize(nbWritten); 
    1169        
    1170       { 
    1171         numberWrittenIndexes_ = nbWritten; 
    1172         if (isDataDistributed()) 
    1173         { 
    1174           CContext* context = CContext::getCurrent();       
    1175           MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, context->intraComm_); 
    1176           MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, context->intraComm_); 
    1177           offsetWrittenIndexes_ -= numberWrittenIndexes_; 
    1178         } 
    1179         else 
    1180           totalNumberWrittenIndexes_ = numberWrittenIndexes_; 
    1181       } 
    1182  
    1183       nbWritten = 0;  
    1184       for (it = itb; it != ite; ++it) 
    1185       { 
    1186         indGlo = it->first; 
    1187         itSrv = globalLocalIndex.find(indGlo); 
    1188         if (itSrve != itSrv) 
    1189         { 
    1190           localIndexToWriteOnServer_(nbWritten) = itSrv->second; 
    1191           localIndexToWriteOnClient_(nbWritten) = it->second; 
    1192           ++nbWritten;                 
    1193         }  
    1194       } 
    1195    } 
    1196    CATCH_DUMP_ATTR 
    1197  
    1198     
    1199  
    1200    /*! 
    1201      Compute the global index of grid to send to server as well as the connected server of the current client. 
    1202      First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know 
    1203      their global index. We can have a map of global index of grid and local index that each client holds 
    1204      Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s) 
    1205      of the current client. 
    1206    */ 
    1207    void CGrid::computeGridIndexToFileServer(CContextClient* client) 
    1208    { 
    1209      if (isScalarGrid()) computeConnectedClientsScalarGrid(client); 
    1210      else computeConnectedClients(client); 
    1211      
    1212      // compute indices for client/server transfer for domain 
    1213      for (const auto& domainId : domList_) CDomain::get(domainId)->computeConnectedClients(client); 
    1214     
    1215     
    1216      // compute indices for client/server transfer for axis 
    1217      std::vector<CAxis*> axisList = this->getAxis(); 
    1218      for(int i=0 ; i<axisList.size(); i++) axisList[i] -> computeConnectedClients(client, getGlobalDimension(),getAxisPositionInGrid()[i]) ; 
    1219    } 
    1220    //--------------------------------------------------------------- 
    1221  
     948 
     949    //--------------------------------------------------------------- 
     950   CDistributionClient* CGrid::getClientDistribution() 
     951   TRY 
     952   { 
     953     if (!computeClientDistribution_done_) computeClientDistribution() ; 
     954     return clientDistribution_; 
     955   } 
     956   CATCH_DUMP_ATTR 
    1222957    
    1223958   void CGrid::computeClientDistribution(void) 
     
    1231966   } 
    1232967 
    1233    void CGrid::computeStoreIndex_client(void) 
    1234    { 
    1235      if (computeStoreIndex_client_done_) return ; 
    1236      else computeStoreIndex_client_done_ = true ; 
    1237      if (isScalarGrid()) 
    1238      { 
    1239        storeIndex_client_.resize(1); 
    1240        storeIndex_client_(0) = 0; 
    1241      } 
    1242      else 
    1243      { 
    1244        CDistributionClient* clientDistribution = getClientDistribution() ; 
    1245        const std::vector<int>& localDataIndex = clientDistribution->getLocalDataIndexOnClient() ; 
    1246        int nbStoreIndex = localDataIndex.size() ; 
    1247        storeIndex_client_.resize(nbStoreIndex); 
    1248        for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client_(idx) = localDataIndex[idx]; 
    1249      } 
    1250    } 
    1251  
    1252    void CGrid::computeStoreMask_client(void) 
    1253    { 
    1254      if (computeStoreMask_client_done_) return ; 
    1255      else computeStoreMask_client_done_ = true ; 
    1256      if (isScalarGrid()) 
    1257      { 
    1258        storeMask_client_.resize(1); 
    1259        storeMask_client_(0) = true; 
    1260      } 
    1261      else 
    1262      { 
    1263        CDistributionClient* clientDistribution = getClientDistribution() ; 
    1264        const std::vector<bool>& localMaskIndex = clientDistribution->getLocalMaskIndexOnClient() ; 
    1265        int nbMaskIndex = localMaskIndex.size() ; 
    1266        storeMask_client_.resize(nbMaskIndex); 
    1267        for (int idx = 0; idx < nbMaskIndex; ++idx) storeMask_client_(idx) = localMaskIndex[idx]; 
    1268      } 
    1269    } 
    1270  
    1271  
    1272   void CGrid::computeOutLocalIndexStoreOnClient(void) 
    1273   { 
    1274     if (computeOutLocalIndexStoreOnClient_done_) return ; 
    1275     else computeOutLocalIndexStoreOnClient_done_=true ; 
    1276  
    1277     if (isScalarGrid()) 
    1278     { 
    1279         auto& outGlobalIndexFromClient  = getOutGlobalIndexFromClient(); 
    1280         auto itb = outGlobalIndexFromClient.begin(), ite = outGlobalIndexFromClient.end() ; 
    1281         for (auto it = itb; it != ite; ++it) 
    1282         { 
    1283           int rank = it->first; 
    1284           CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
    1285           outLocalIndexStoreOnClient_.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
    1286           CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient_[rank]; 
    1287           if (1 != globalIndex.numElements()) 
    1288             ERROR("void CGrid::computeClientIndexScalarGrid()", 
    1289               << "Something wrong happened. " 
    1290               << "Number of received global index on scalar grid should equal to 1"  
    1291               << "Number of received global index " << globalIndex.numElements() << "."); 
    1292  
    1293           localIndex(0) = globalIndex(0); 
    1294         } 
    1295     } 
    1296     else 
    1297     { 
    1298       CDistributionClient::GlobalLocalDataMap& globalDataIndex = getClientDistribution()->getGlobalDataIndexOnClient(); 
    1299       CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 
    1300       auto& outGlobalIndexFromClient  = getOutGlobalIndexFromClient(); 
    1301       auto itb = outGlobalIndexFromClient.begin(), ite = outGlobalIndexFromClient.end() ; 
    1302      
    1303       for (auto it = itb; it != ite; ++it) 
    1304       { 
    1305          int rank = it->first; 
    1306          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
    1307          outLocalIndexStoreOnClient_.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
    1308          CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient_[rank]; 
    1309          size_t nbIndex = 0; 
    1310  
    1311         // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 
    1312         for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    1313           if (itGloe != globalDataIndex.find(globalIndex(idx))) ++nbIndex; 
    1314  
    1315         if (nbIndex != localIndex.numElements()) 
    1316              ERROR("void CGrid::computeClientIndex()", 
    1317                  << "Number of local index on client is different from number of received global index" 
    1318                  << "Rank of sent client " << rank <<"." 
    1319                  << "Number of local index " << nbIndex << ". " 
    1320                  << "Number of received global index " << localIndex.numElements() << "."); 
    1321  
    1322         nbIndex = 0; 
    1323         for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    1324           if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    1325             localIndex(idx) = globalDataIndex[globalIndex(idx)]; 
    1326       } 
    1327     } 
    1328   } 
    1329968 
    1330969  bool CGrid::isDataDistributed(void)  
     
    1333972  } 
    1334973 
    1335    /*! 
    1336      Compute connected receivers and indexes to be sent to these receivers. 
    1337    */ 
    1338    void CGrid::computeConnectedClients(CContextClient* client) 
    1339    TRY 
    1340    { 
    1341      if (computeConnectedClients_done_.count(client)!=0) return ; 
    1342      else  computeConnectedClients_done_.insert(client) ; 
    1343  
    1344      CContext* context = CContext::getCurrent(); 
    1345       
    1346      set<int> listReceiverSize ; 
    1347      int receiverSize = client->serverSize; 
    1348        
    1349      if (listReceiverSize.find(receiverSize)==listReceiverSize.end()) 
    1350      { 
    1351        listReceiverSize.insert(receiverSize) ; 
    1352        if (connectedServerRank_.find(receiverSize) != connectedServerRank_.end()) 
    1353        { 
    1354           // delete corresponding map in case of recompute, probably because a grid could has been modifiedd  
    1355           // by a transformation 
    1356           connectedServerRank_.erase(receiverSize); 
    1357           connectedDataSize_.erase(receiverSize); 
    1358           globalIndexOnServer_.erase(receiverSize); 
    1359           nbSenders_.erase(receiverSize); 
    1360        } 
    1361  
    1362        if (!doGridHaveDataDistributed(client)) 
    1363        { 
    1364           if (client->isServerLeader()) 
    1365           { 
    1366             size_t ssize = getClientDistribution()->getLocalDataIndexOnClient().size(); 
    1367             const std::list<int>& ranks = client->getRanksServerLeader(); 
    1368             for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1369             { 
    1370               connectedServerRank_[receiverSize].push_back(*itRank); 
    1371               connectedDataSize_[receiverSize][*itRank] = ssize; 
    1372             } 
    1373           } 
    1374           return; 
    1375        } 
    1376  
    1377        // Compute mapping between client and server 
    1378        std::vector<std::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
    1379        CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
    1380        std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
    1381                                                                                                     client->clientRank, 
    1382                                                                                                     client->clientSize, 
    1383                                                                                                     axis_domain_order, 
    1384                                                                                                     getDistributedDimension()); 
    1385  
    1386        // Even if servers have no index, they must received something from client 
    1387        // We only use several client to send "empty" message to these servers 
    1388        std::list<int> serverZeroIndexLeader; 
    1389        std::list<int> serverZeroIndexNotLeader; 
    1390        CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
    1391        for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    1392          *it = serverZeroIndex[*it]; 
    1393  
    1394        if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end()) 
    1395          computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]); 
    1396  
    1397        const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getClientDistribution()->getGlobalLocalDataSendToServer(); 
    1398        CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
    1399        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 
    1400        itbGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
    1401        iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
    1402  
    1403        for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    1404        { 
    1405          int serverRank = itGlobalMap->first; 
    1406          int indexSize = itGlobalMap->second.size(); 
    1407          const std::vector<size_t>& indexVec = itGlobalMap->second; 
    1408          for (int idx = 0; idx < indexSize; ++idx) 
    1409          { 
    1410             itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 
    1411             if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 
    1412             { 
    1413               if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank)) 
    1414                 connectedDataSize_[receiverSize][serverRank] = 1; 
    1415               else 
    1416                 ++connectedDataSize_[receiverSize][serverRank]; 
    1417             } 
    1418          } 
    1419        } 
    1420  
    1421        // Connected servers which really have index 
    1422        for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)  
    1423          connectedServerRank_[receiverSize].push_back(itGlobalMap->first); 
    1424       
    1425        // Connected servers which have no index at all 
    1426        for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    1427          connectedServerRank_[receiverSize].push_back(*it); 
    1428  
    1429        // Even if a client has no index, it must connect to at least one server and 
    1430        // send an "empty" data to this server 
    1431        if (connectedServerRank_[receiverSize].empty()) 
    1432          connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 
    1433   
    1434        // Now check if all servers have data to receive. If not, master client will send empty data. 
    1435        // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 
    1436        std::vector<int> counts (client->clientSize); 
    1437        std::vector<int> displs (client->clientSize); 
    1438        displs[0] = 0; 
    1439        int localCount = connectedServerRank_[receiverSize].size() ; 
    1440        MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 
    1441        for (int i = 0; i < client->clientSize-1; ++i) displs[i+1] = displs[i] + counts[i]; 
    1442        std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]); 
    1443        MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 
    1444  
    1445        if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0)) 
    1446        { 
    1447          std::vector<bool> isSrvConnected (receiverSize, false); 
    1448          for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 
    1449          for (int i = 0; i < receiverSize; ++i) if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i); 
    1450        } 
    1451  
    1452        nbSenders_[receiverSize] = CClientServerMapping::computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 
    1453      } 
    1454    } 
    1455    CATCH_DUMP_ATTR 
    1456  
     974   
    1457975   /*! 
    1458976     Compute the global index of grid to send to server as well as the connected server of the current client. 
     
    14871005     if (context->getServiceType()==CServicesManager::OUT_SERVER) 
    14881006     { 
    1489        computeWrittenIndex() ; 
    1490        if (serverDistribution_!=0) serverDistribution_->partialClear() ; 
    14911007       if (clientDistribution_!=0) clientDistribution_->partialClear() ; 
    1492        outGlobalIndexFromClient_.clear() ; 
    14931008     } 
    14941009   } 
    14951010   CATCH_DUMP_ATTR 
    14961011 
    1497    /*! 
    1498       Compute the global of (client) grid to send to server with the global index of each element of grid 
    1499       Each element of grid has its own global index associated to a groups of server. We only search for the global index of each element whose 
    1500       server is the same, then calculate the global index of grid. This way can reduce so much the time for executing DHT, which only needs to run 
    1501       on each element whose size is much smaller than one of whole grid. 
    1502       \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 
    1503       \param [in] client contextClient 
    1504       \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 
    1505    */ 
    1506    void CGrid::computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
    1507                                      const CContextClient* client, 
    1508                                      CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 
    1509    TRY 
    1510    { 
    1511      int serverSize = client->serverSize; 
    1512  
    1513      std::vector<CDomain*> domList = getDomains(); 
    1514      std::vector<CAxis*> axisList = getAxis(); 
    1515  
    1516      // Some pre-calculations of global index on each element of current grid. 
    1517      int nbElement = axis_domain_order.numElements(); 
    1518      std::vector<CArray<size_t,1> > globalIndexElement(nbElement); 
    1519      int domainIdx = 0, axisIdx = 0, scalarIdx = 0; 
    1520      std::vector<size_t> elementNGlobal(nbElement); 
    1521      elementNGlobal[0] = 1; 
    1522      size_t globalSize = 1; 
    1523      for (int idx = 0; idx < nbElement; ++idx) 
    1524      { 
    1525        elementNGlobal[idx] = globalSize; 
    1526        size_t elementSize; 
    1527        size_t elementGlobalSize = 1; 
    1528        if (2 == axis_domain_order(idx)) // This is domain 
    1529        { 
    1530          elementSize = domList[domainIdx]->i_index.numElements(); 
    1531          globalIndexElement[idx].resize(elementSize); 
    1532          for (int jdx = 0; jdx < elementSize; ++jdx) 
    1533          { 
    1534            globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx); 
    1535          } 
    1536          elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue(); 
    1537          ++domainIdx; 
    1538        } 
    1539        else if (1 == axis_domain_order(idx))  // This is axis 
    1540        { 
    1541          elementSize = axisList[axisIdx]->index.numElements(); 
    1542          globalIndexElement[idx].resize(elementSize); 
    1543          for (int jdx = 0; jdx < elementSize; ++jdx) 
    1544          { 
    1545            globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx); 
    1546          } 
    1547          elementGlobalSize = axisList[axisIdx]->n_glo.getValue(); 
    1548          ++axisIdx; 
    1549        } 
    1550        else  // Of course, this is scalar 
    1551        { 
    1552          globalIndexElement[idx].resize(1); 
    1553          globalIndexElement[idx](0) = 0; 
    1554          elementGlobalSize = 1; 
    1555        } 
    1556        globalSize *= elementGlobalSize; 
    1557      } 
    1558  
    1559      std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false)); 
    1560      std::vector<std::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement); 
    1561      CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server 
    1562      // Number of temporary distributed global index held by each client for each server 
    1563      // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank 
    1564      CArray<int,1> nbIndexOnServerTmp(serverSize); 
    1565      for (int idx = 0; idx < nbElement; ++idx) 
    1566      { 
    1567        nbIndexOnServer = 0; 
    1568        const std::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx]; 
    1569        const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx]; 
    1570        CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm); 
    1571        clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient); 
    1572        const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap(); 
    1573        CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(), 
    1574                                                                     ite = globalIndexElementOnServerMap.end(), it; 
    1575        for (it = itb; it != ite; ++it) 
    1576        { 
    1577          const std::vector<int>& tmp = it->second; 
    1578          nbIndexOnServerTmp = 0; 
    1579          for (int i = 0; i < tmp.size(); ++i) 
    1580          { 
    1581            if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]); 
    1582          } 
    1583          nbIndexOnServer += nbIndexOnServerTmp; 
    1584        } 
    1585  
    1586        for (int i = 0; i < serverSize; ++i) 
    1587        { 
    1588          if (0 != nbIndexOnServer(i)) 
    1589          { 
    1590            globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i)); 
    1591            elementOnServer[idx][i] = true; 
    1592          } 
    1593        } 
    1594  
    1595      nbIndexOnServer = 0; 
    1596      for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 
    1597      { 
    1598        it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 
    1599        if (it != ite) 
    1600        { 
    1601          const std::vector<int>& tmp = it->second; 
    1602          nbIndexOnServerTmp = 0; 
    1603          for (int i = 0; i < tmp.size(); ++i) 
    1604          { 
    1605            if (0 == nbIndexOnServerTmp(tmp[i])) 
    1606            { 
    1607              globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first; 
    1608              ++nbIndexOnServerTmp(tmp[i]); 
    1609            } 
    1610          } 
    1611          nbIndexOnServer += nbIndexOnServerTmp; 
    1612        } 
    1613      } 
    1614    } 
    1615  
    1616     // Determine server which contain global source index 
    1617     std::vector<bool> intersectedProc(serverSize, true); 
    1618     for (int idx = 0; idx < nbElement; ++idx) 
    1619     { 
    1620       std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(), 
    1621                      intersectedProc.begin(), intersectedProc.begin(), 
    1622                      std::logical_and<bool>()); 
    1623     } 
    1624  
    1625     std::vector<int> srcRank; 
    1626     for (int idx = 0; idx < serverSize; ++idx) 
    1627     { 
    1628       if (intersectedProc[idx]) srcRank.push_back(idx); 
    1629     } 
    1630  
    1631     // Compute the global index of grid from global index of each element. 
    1632     for (int i = 0; i < srcRank.size(); ++i) 
    1633     { 
    1634       size_t ssize = 1; 
    1635       int rankSrc = srcRank[i]; 
    1636       std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement); 
    1637       std::vector<size_t> currentIndex(nbElement,0); 
    1638       for (int idx = 0; idx < nbElement; ++idx) 
    1639       { 
    1640         ssize *= (globalElementIndexOnServer[idx][rankSrc]).size(); 
    1641         globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]); 
    1642       } 
    1643       globalIndexOnServer[rankSrc].resize(ssize); 
    1644  
    1645       std::vector<int> idxLoop(nbElement,0); 
    1646       int innnerLoopSize = (globalIndexOfElementTmp[0])->size(); 
    1647       size_t idx = 0; 
    1648       while (idx < ssize) 
    1649       { 
    1650         for (int ind = 0; ind < nbElement; ++ind) 
    1651         { 
    1652           if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size()) 
    1653           { 
    1654             idxLoop[ind] = 0; 
    1655             ++idxLoop[ind+1]; 
    1656           } 
    1657  
    1658           currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]]; 
    1659         } 
    1660  
    1661         for (int ind = 0; ind < innnerLoopSize; ++ind) 
    1662         { 
    1663           currentIndex[0] = (*globalIndexOfElementTmp[0])[ind]; 
    1664           size_t globalSrcIndex = 0; 
    1665           for (int idxElement = 0; idxElement < nbElement; ++idxElement) 
    1666           { 
    1667             globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement]; 
    1668           } 
    1669           globalIndexOnServer[rankSrc][idx] = globalSrcIndex; 
    1670           ++idx; 
    1671           ++idxLoop[0]; 
    1672         } 
    1673       } 
    1674     } 
    1675    } 
    1676    CATCH_DUMP_ATTR 
     1012    
    16771013//---------------------------------------------------------------- 
    16781014 
     
    17831119   //---------------------------------------------------------------- 
    17841120 
    1785    void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored)  
    1786    TRY 
    1787    { 
    1788       auto& storeIndex_client = getStoreIndex_client() ; 
    1789       const StdSize size = storeIndex_client.numElements(); 
    1790  
    1791       stored.resize(size); 
    1792       for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 
    1793    } 
    1794    CATCH 
    1795  
    1796    void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data)  
    1797    TRY 
    1798    { 
    1799       auto& storeIndex_client=getStoreIndex_client() ; 
    1800       const StdSize size = storeIndex_client.numElements(); 
    1801  
    1802       for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i); 
    1803    } 
    1804    CATCH 
    1805  
    1806    void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored)  
    1807    { 
    1808       auto& storeIndex_client=getStoreIndex_client() ; 
    1809       auto& storeMask_client=getStoreMask_client() ; 
    1810          
    1811       const StdSize size = storeIndex_client.numElements(); 
    1812       stored.resize(size); 
    1813       const double nanValue = std::numeric_limits<double>::quiet_NaN(); 
    1814  
    1815       if (storeMask_client.numElements() != 0) 
    1816         for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue; 
    1817       else 
    1818         for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 
    1819    } 
    1820  
    1821    void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out)  
    1822    TRY 
    1823    { 
    1824       const std::vector<int>& localMaskedDataIndex = getClientDistribution()->getLocalMaskedDataIndexOnClient(); 
    1825       const int size = localMaskedDataIndex.size(); 
    1826       for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i]; 
    1827    } 
    1828    CATCH 
    1829  
    1830    
    1831   void CGrid::computeConnectedClientsScalarGrid(CContextClient* client) 
    1832   TRY 
    1833   { 
    1834     if (computeConnectedClientsScalarGrid_done_.count(client)!=0) return ; 
    1835  
    1836     CContext* context = CContext::getCurrent(); 
    1837       
    1838     set<int> listReceiverSize ; 
    1839  
    1840     int receiverSize = client->serverSize; 
    1841        
    1842     if (listReceiverSize.find(receiverSize)==listReceiverSize.end()) 
    1843     { 
    1844       listReceiverSize.insert(receiverSize) ; 
    1845       if (connectedServerRank_.find(receiverSize) != connectedServerRank_.end()) 
    1846       { 
    1847          // delete corresponding map in case of recompute, probably because a grid could has been modifiedd  
    1848          // by a transformation 
    1849         connectedServerRank_.erase(receiverSize); 
    1850         connectedDataSize_.erase(receiverSize); 
    1851         globalIndexOnServer_.erase(receiverSize); 
    1852         nbSenders_.erase(receiverSize); 
    1853       } 
    1854  
    1855       if (client->isServerLeader()) 
    1856       { 
    1857         const std::list<int>& ranks = client->getRanksServerLeader(); 
    1858         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1859         { 
    1860           int rank = *itRank; 
    1861           int nb = 1; 
    1862           connectedServerRank_[receiverSize].push_back(rank); 
    1863           connectedDataSize_[receiverSize][rank] = nb; 
    1864           nbSenders_[receiverSize][rank] = nb; 
    1865         } 
    1866       } 
    1867       else 
    1868       { 
    1869         const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1870         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1871         { 
    1872           int rank = *itRank; 
    1873           int nb = 1; 
    1874           connectedServerRank_[receiverSize].push_back(rank); 
    1875           connectedDataSize_[receiverSize][rank] = nb; 
    1876           nbSenders_[receiverSize][rank] = nb; 
    1877         } 
    1878       } 
    1879     } 
    1880     
    1881     computeConnectedClientsScalarGrid_done_.insert(client) ; 
    1882   } 
    1883   CATCH_DUMP_ATTR 
    1884  
    1885   void CGrid::sendIndexScalarGrid(CContextClient* client, const string& gridId) 
    1886   TRY 
    1887   { 
    1888     if (sendIndexScalarGrid_done_.count(client)!=0) return ; 
    1889     else sendIndexScalarGrid_done_.insert(client) ; 
    1890  
    1891     CContext* context = CContext::getCurrent(); 
    18921121     
    1893     string serverGridId = gridId.empty() ? serverGridId=this->getId() : serverGridId=gridId ; 
    1894  
    1895     int receiverSize = client->serverSize; 
    1896  
    1897     CEventClient event(getType(), EVENT_ID_INDEX); 
    1898     list<CMessage> listMsg; 
    1899     list<CArray<size_t,1> > listOutIndex; 
    1900  
    1901     if (client->isServerLeader()) 
    1902     { 
    1903       const std::list<int>& ranks = client->getRanksServerLeader(); 
    1904       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1905       { 
    1906         int rank = *itRank; 
    1907         int nb = 1; 
    1908         storeIndex_toSrv_[client].insert(std::make_pair(rank, CArray<int,1>(nb))); 
    1909         listOutIndex.push_back(CArray<size_t,1>(nb)); 
    1910  
    1911         CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv_[client][rank]; 
    1912         CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
    1913  
    1914         for (int k = 0; k < nb; ++k) 
    1915         { 
    1916           outGlobalIndexOnServer(k) = 0; 
    1917           outLocalIndexToServer(k)  = 0; 
    1918         } 
    1919  
    1920         if (context->getServiceType()==CServicesManager::CLIENT)  // -> what about for coupling probably unusefull to be check 
    1921           storeIndex_fromSrv_.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1922  
    1923         listMsg.push_back(CMessage()); 
    1924         listMsg.back() << serverGridId << isCompressible_ << listOutIndex.back(); 
    1925  
    1926         event.push(rank, 1, listMsg.back()); 
    1927       } 
    1928       client->sendEvent(event); 
    1929     } 
    1930     else 
    1931     { 
    1932       const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1933       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1934       { 
    1935         int rank = *itRank; 
    1936         int nb = 1;           
    1937         CArray<int, 1> outLocalIndexToServer(nb); 
    1938         for (int k = 0; k < nb; ++k) 
    1939         { 
    1940           outLocalIndexToServer(k)  = 0; 
    1941         } 
    1942  
    1943         if (context->getServiceType()==CServicesManager::CLIENT) 
    1944           storeIndex_fromSrv_.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1945       } 
    1946       client->sendEvent(event); 
    1947     } 
    1948   } 
    1949   CATCH_DUMP_ATTR 
    1950  
    1951   void CGrid::sendIndex(CContextClient* client, const string& gridId) 
    1952   TRY 
    1953   { 
    1954     if (sendIndex_done_.count(client)!=0) return ; 
    1955     else sendIndex_done_.insert(client) ; 
    1956     CContext* context = CContext::getCurrent(); 
    1957     string serverGridId = gridId.empty() ? this->getId() : gridId ; 
    1958  
    1959  
    1960  
    1961     int receiverSize = client->serverSize; 
    1962  
    1963     CEventClient event(getType(), EVENT_ID_INDEX); 
    1964     int rank; 
    1965     list<CMessage> listMsg; 
    1966     list<CArray<size_t,1> > listOutIndex; 
    1967     const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getClientDistribution()->getGlobalLocalDataSendToServer(); 
    1968     CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex, 
    1969                                                             iteIndex = globalLocalIndexSendToServer.end(); 
    1970     itIndex = itbIndex;                                                               
    1971  
    1972     if (!doGridHaveDataDistributed(client)) 
    1973     { 
    1974       if (client->isServerLeader()) 
    1975       { 
    1976         int indexSize = globalLocalIndexSendToServer.size(); 
    1977         CArray<size_t,1> outGlobalIndexOnServer(indexSize); 
    1978         CArray<int,1> outLocalIndexToServer(indexSize); 
    1979         for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    1980         { 
    1981           outGlobalIndexOnServer(idx) = itIndex->first; 
    1982           outLocalIndexToServer(idx) = itIndex->second; 
    1983         } 
    1984  
    1985         const std::list<int>& ranks = client->getRanksServerLeader(); 
    1986         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1987         { 
    1988           storeIndex_toSrv_[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1989           if (context->getServiceType()==CServicesManager::CLIENT)  // -> what about for coupling probably unusefull to be check 
    1990             storeIndex_fromSrv_.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1991            
    1992           listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 
    1993  
    1994           listMsg.push_back(CMessage()); 
    1995           listMsg.back() << serverGridId << isCompressible_ << listOutIndex.back(); 
    1996  
    1997           event.push(*itRank, 1, listMsg.back()); 
    1998         } 
    1999         client->sendEvent(event); 
    2000       } 
    2001       else 
    2002       { 
    2003          int indexSize = globalLocalIndexSendToServer.size(); 
    2004          CArray<int,1> outLocalIndexToServer(indexSize); 
    2005          for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    2006          { 
    2007            outLocalIndexToServer(idx) = itIndex->second; 
    2008          } 
    2009  
    2010          const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    2011          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    2012          { 
    2013            storeIndex_fromSrv_.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    2014          } 
    2015          client->sendEvent(event); 
    2016        } 
    2017     } 
    2018     else 
    2019     { 
    2020       CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 
    2021       itGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
    2022       iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
    2023  
    2024       std::map<int,std::vector<int> >localIndexTmp; 
    2025       std::map<int,std::vector<size_t> > globalIndexTmp; 
    2026       for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    2027       { 
    2028         int serverRank = itGlobalMap->first; 
    2029         int indexSize = itGlobalMap->second.size(); 
    2030         const std::vector<size_t>& indexVec = itGlobalMap->second; 
    2031         for (int idx = 0; idx < indexSize; ++idx) 
    2032         { 
    2033           itIndex = globalLocalIndexSendToServer.find(indexVec[idx]); 
    2034           if (iteIndex != itIndex) 
    2035           { 
    2036             globalIndexTmp[serverRank].push_back(itIndex->first); 
    2037             localIndexTmp[serverRank].push_back(itIndex->second); 
    2038           } 
    2039         } 
    2040       } 
    2041  
    2042       for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns) 
    2043       { 
    2044         rank = connectedServerRank_[receiverSize][ns]; 
    2045         int nb = 0; 
    2046         if (globalIndexTmp.end() != globalIndexTmp.find(rank)) 
    2047           nb = globalIndexTmp[rank].size(); 
    2048  
    2049         storeIndex_toSrv_[client].insert(make_pair(rank, CArray<int,1>(nb))); 
    2050         listOutIndex.push_back(CArray<size_t,1>(nb)); 
    2051  
    2052         CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv_[client][rank]; 
    2053         CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
    2054  
    2055         for (int k = 0; k < nb; ++k) 
    2056         { 
    2057           outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k); 
    2058           outLocalIndexToServer(k)  = localIndexTmp[rank].at(k); 
    2059         } 
    2060  
    2061         storeIndex_fromSrv_.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    2062         listMsg.push_back(CMessage()); 
    2063         listMsg.back() << serverGridId  << isCompressible_ << listOutIndex.back(); 
    2064  
    2065         event.push(rank, nbSenders_[receiverSize][rank], listMsg.back()); 
    2066       } 
    2067       client->sendEvent(event); 
    2068     } 
    2069   } 
    2070   CATCH_DUMP_ATTR 
    2071  
    2072   void CGrid::recvIndex(CEventServer& event) 
    2073   TRY 
    2074   { 
    2075     string gridId; 
    2076     vector<int> ranks; 
    2077     vector<CBufferIn*> buffers; 
    2078  
    2079     list<CEventServer::SSubEvent>::iterator it; 
    2080     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    2081     { 
    2082       ranks.push_back(it->rank); 
    2083       CBufferIn* buffer = it->buffer; 
    2084       *buffer >> gridId; 
    2085       buffers.push_back(buffer); 
    2086     } 
    2087     get(gridId)->recvIndex(ranks, buffers, event.getContextServer()); 
    2088   } 
    2089   CATCH 
    2090  
    2091   void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server) 
    2092   TRY 
    2093   { 
    2094     CContextClient* client = server->getAssociatedClient(); 
    2095     connectedServerRankRead_ = ranks; 
    2096     for (int n = 0; n < ranks.size(); n++) 
    2097     { 
    2098       int rank = ranks[n]; 
    2099       CBufferIn& buffer = *buffers[n]; 
    2100       buffer >>  isCompressible_; // probably to be removed later 
    2101       CArray<size_t,1> outIndex; 
    2102       buffer >> outIndex; 
    2103       outGlobalIndexFromClient_.insert(std::make_pair(rank, outIndex)); 
    2104       connectedDataSizeRead_[rank] = outIndex.numElements(); 
    2105     } 
    2106     // ym : displaced to avoid collective call at message reception 
    2107 /*  
    2108     nbReadSenders_[client] = CClientServerMappingDistributed::computeConnectedClients(client->serverSize, client->clientSize, 
    2109                                                                                      client->intraComm, ranks); 
    2110 */ 
    2111   } 
    2112   CATCH_DUMP_ATTR 
    21131122   
    21141123   
    2115   /*! 
    2116    * Compute the number of connected client for a given contextClient and insert it in the nbReadSenders map. 
    2117    * /param[in] client : the given contextClient 
    2118    */ 
    2119   void CGrid::computeNbReadSenders(CContextClient* client)  
    2120   TRY 
    2121    
    2122   {  
    2123     nbReadSenders_[client] = CClientServerMappingDistributed::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRankRead_); 
    2124   } 
    2125   CATCH_DUMP_ATTR 
    2126    
    2127   void CGrid::computeServerDistribution(void) 
    2128   TRY 
    2129   { 
    2130     if (computeServerDistribution_done_) return ; 
    2131     else computeServerDistribution_done_=true ; 
    2132  
    2133     CContext* context = CContext::getCurrent(); 
    2134        
    2135     int idx = 0, numElement = axis_domain_order.numElements(); 
    2136     int ssize = numElement; 
    2137     std::vector<int> indexMap(numElement); 
    2138     for (int i = 0; i < numElement; ++i) 
    2139     { 
    2140       indexMap[i] = idx; 
    2141       if (2 == axis_domain_order(i)) 
    2142       { 
    2143         ++ssize; 
    2144         idx += 2; 
    2145       } 
    2146       else 
    2147         ++idx; 
    2148     } 
    2149  
    2150     for (int n = 0; n < connectedServerRankRead_.size(); n++) 
    2151     { 
    2152       int rank = connectedServerRankRead_[n]; 
    2153       size_t dataSize = 0; 
    2154  
    2155       if (0 == serverDistribution_) 
    2156       { 
    2157         int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
    2158         std::vector<CDomain*> domainList = getDomains(); 
    2159         std::vector<CAxis*> axisList = getAxis(); 
    2160         std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize), nGlobElement(numElement); 
    2161         std::vector<CArray<int,1> > globalIndex(numElement); 
    2162         for (int i = 0; i < numElement; ++i) 
    2163         { 
    2164           nGlobElement[i] = globalSize; 
    2165           if (2 == axis_domain_order(i)) //domain 
    2166           { 
    2167             nBegin[indexMap[i]] = domainList[domainId]->ibegin; 
    2168             nSize[indexMap[i]]  = domainList[domainId]->ni; 
    2169             nBeginGlobal[indexMap[i]] = 0; 
    2170             nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
    2171  
    2172             nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 
    2173             nSize[indexMap[i] + 1] = domainList[domainId]->nj; 
    2174             nBeginGlobal[indexMap[i] + 1] = 0; 
    2175             nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
    2176  
    2177             { 
    2178               int count = 0; 
    2179               globalIndex[i].resize(nSize[indexMap[i]]*nSize[indexMap[i]+1]); 
    2180               for (int jdx = 0; jdx < nSize[indexMap[i]+1]; ++jdx) 
    2181                 for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 
    2182                 { 
    2183                   globalIndex[i](count) = (nBegin[indexMap[i]] + idx) + (nBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]]; 
    2184                   ++count; 
    2185                 } 
    2186             } 
    2187  
    2188             ++domainId; 
    2189           } 
    2190           else if (1 == axis_domain_order(i)) // axis 
    2191           { 
    2192             nBegin[indexMap[i]] = axisList[axisId]->begin; 
    2193             nSize[indexMap[i]]  = axisList[axisId]->n; 
    2194             nBeginGlobal[indexMap[i]] = 0; 
    2195             nGlob[indexMap[i]] = axisList[axisId]->n_glo;      
    2196             globalIndex[i].resize(nSize[indexMap[i]]); 
    2197             for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 
    2198               globalIndex[i](idx) = nBegin[indexMap[i]] + idx; 
    2199  
    2200             ++axisId; 
    2201           } 
    2202           else // scalar 
    2203           {  
    2204             nBegin[indexMap[i]] = 0; 
    2205             nSize[indexMap[i]]  = 1; 
    2206             nBeginGlobal[indexMap[i]] = 0; 
    2207             nGlob[indexMap[i]] = 1; 
    2208             globalIndex[i].resize(1); 
    2209             globalIndex[i](0) = 0; 
    2210             ++scalarId; 
    2211           } 
    2212         } 
    2213         dataSize = 1; 
    2214  
    2215         for (int i = 0; i < nSize.size(); ++i) 
    2216         dataSize *= nSize[i]; 
    2217         serverDistribution_ = new CDistributionServer(context->intraCommRank_,  
    2218                                                       globalIndex, axis_domain_order, 
    2219                                                       nBegin, nSize, nBeginGlobal, nGlob); 
    2220       } 
    2221     } 
    2222   } 
    2223   CATCH_DUMP_ATTR 
    2224  
    2225  
    2226  
    2227  
    2228  
    2229  
    2230 /* old interface => transform into compute receivedIndex 
    2231   void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server) 
    2232   TRY 
    2233   { 
    2234     CContext* context = CContext::getCurrent(); 
    2235     connectedServerRankRead_ = ranks; 
    2236  
    2237     nbReadSenders_.clear(); 
    2238     CContextClient* client = server->getAssociatedClient();    
    2239        
    2240     int idx = 0, numElement = axis_domain_order.numElements(); 
    2241     int ssize = numElement; 
    2242     std::vector<int> indexMap(numElement); 
    2243     for (int i = 0; i < numElement; ++i) 
    2244     { 
    2245       indexMap[i] = idx; 
    2246       if (2 == axis_domain_order(i)) 
    2247       { 
    2248         ++ssize; 
    2249         idx += 2; 
    2250       } 
    2251       else 
    2252         ++idx; 
    2253     } 
    2254  
    2255     for (int n = 0; n < ranks.size(); n++) 
    2256     { 
    2257       int rank = ranks[n]; 
    2258       CBufferIn& buffer = *buffers[n]; 
    2259  
    2260       buffer >>  isCompressible_; 
    2261       size_t dataSize = 0; 
    2262  
    2263       if (0 == serverDistribution_) 
    2264       { 
    2265         int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
    2266         std::vector<CDomain*> domainList = getDomains(); 
    2267         std::vector<CAxis*> axisList = getAxis(); 
    2268         std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize), nGlobElement(numElement); 
    2269         std::vector<CArray<int,1> > globalIndex(numElement); 
    2270         for (int i = 0; i < numElement; ++i) 
    2271         { 
    2272           nGlobElement[i] = globalSize; 
    2273           if (2 == axis_domain_order(i)) //domain 
    2274           { 
    2275             nBegin[indexMap[i]] = domainList[domainId]->ibegin; 
    2276             nSize[indexMap[i]]  = domainList[domainId]->ni; 
    2277             nBeginGlobal[indexMap[i]] = 0; 
    2278             nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
    2279  
    2280             nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 
    2281             nSize[indexMap[i] + 1] = domainList[domainId]->nj; 
    2282             nBeginGlobal[indexMap[i] + 1] = 0; 
    2283             nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
    2284  
    2285             { 
    2286               int count = 0; 
    2287               globalIndex[i].resize(nSize[indexMap[i]]*nSize[indexMap[i]+1]); 
    2288               for (int jdx = 0; jdx < nSize[indexMap[i]+1]; ++jdx) 
    2289                 for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 
    2290                 { 
    2291                   globalIndex[i](count) = (nBegin[indexMap[i]] + idx) + (nBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]]; 
    2292                   ++count; 
    2293                 } 
    2294             } 
    2295  
    2296             ++domainId; 
    2297           } 
    2298           else if (1 == axis_domain_order(i)) // axis 
    2299           { 
    2300             nBegin[indexMap[i]] = axisList[axisId]->begin; 
    2301             nSize[indexMap[i]]  = axisList[axisId]->n; 
    2302             nBeginGlobal[indexMap[i]] = 0; 
    2303             nGlob[indexMap[i]] = axisList[axisId]->n_glo;      
    2304             globalIndex[i].resize(nSize[indexMap[i]]); 
    2305             for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 
    2306               globalIndex[i](idx) = nBegin[indexMap[i]] + idx; 
    2307  
    2308             ++axisId; 
    2309           } 
    2310           else // scalar 
    2311           {  
    2312             nBegin[indexMap[i]] = 0; 
    2313             nSize[indexMap[i]]  = 1; 
    2314             nBeginGlobal[indexMap[i]] = 0; 
    2315             nGlob[indexMap[i]] = 1; 
    2316             globalIndex[i].resize(1); 
    2317             globalIndex[i](0) = 0; 
    2318             ++scalarId; 
    2319           } 
    2320         } 
    2321         dataSize = 1; 
    2322  
    2323         for (int i = 0; i < nSize.size(); ++i) 
    2324         dataSize *= nSize[i]; 
    2325         serverDistribution_ = new CDistributionServer(context->intraCommRank_,  
    2326                                                       globalIndex, axis_domain_order, 
    2327                                                       nBegin, nSize, nBeginGlobal, nGlob); 
    2328       } 
    2329  
    2330       CArray<size_t,1> outIndex; 
    2331       buffer >> outIndex; 
    2332       outGlobalIndexFromClient_.insert(std::make_pair(rank, outIndex)); 
    2333       connectedDataSizeRead_[rank] = outIndex.numElements(); 
    2334  
    2335       if (doGridHaveDataDistributed(client)) 
    2336       {} 
    2337       else 
    2338       { 
    2339         // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER 
    2340         // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar) 
    2341         dataSize = serverDistribution_->getGridSize(); 
    2342       } 
    2343       writtenDataSize_ += dataSize; 
    2344     } 
    2345  
    2346  
    2347     // Compute mask of the current grid 
    2348     { 
    2349       int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
    2350       std::vector<CDomain*> domainList = getDomains(); 
    2351       std::vector<CAxis*> axisList = getAxis(); 
    2352       int dimSize = 2 * domainList.size() + axisList.size(); 
    2353       std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize);         
    2354       for (int i = 0; i < numElement; ++i) 
    2355       {           
    2356         if (2 == axis_domain_order(i)) //domain 
    2357         { 
    2358           nBegin[indexMap[i]] = domainList[domainId]->ibegin; 
    2359           nSize[indexMap[i]]  = domainList[domainId]->ni; 
    2360           nBeginGlobal[indexMap[i]] = 0;               
    2361           nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
    2362  
    2363           nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 
    2364           nSize[indexMap[i] + 1] = domainList[domainId]->nj; 
    2365           nBeginGlobal[indexMap[i] + 1] = 0;               
    2366           nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
    2367           ++domainId; 
    2368         } 
    2369         else if (1 == axis_domain_order(i)) // axis 
    2370         { 
    2371           nBegin[indexMap[i]] = axisList[axisId]->begin; 
    2372           nSize[indexMap[i]]  = axisList[axisId]->n; 
    2373           nBeginGlobal[indexMap[i]] = 0;               
    2374           nGlob[indexMap[i]] = axisList[axisId]->n_glo;               
    2375           ++axisId; 
    2376         } 
    2377         else // scalar 
    2378         {   
    2379         } 
    2380       } 
    2381       
    2382       if (nSize.empty()) // Scalar grid 
    2383       { 
    2384         nBegin.push_back(0); 
    2385         nSize.push_back(1); 
    2386         nBeginGlobal.push_back(0);               
    2387         nGlob.push_back(1);   
    2388       } 
    2389     } 
    2390  
    2391     if (isScalarGrid()) return; 
    2392  
    2393     nbReadSenders_[client] = CClientServerMappingDistributed::computeConnectedClients(client->serverSize, client->clientSize, 
    2394                                                                                       client->intraComm, ranks); 
    2395  
    2396   } 
    2397   CATCH_DUMP_ATTR 
    2398 */ 
    2399  
    2400  
    24011124  /* 
    24021125     Compute on the fly the global dimension of a grid with its elements 
     
    24951218  CATCH_DUMP_ATTR 
    24961219 
    2497   /*! 
    2498     Return size of data which is written on each server 
    2499     Whatever dimension of a grid, data which are written on server must be presented as 
    2500     an one dimension array. 
    2501     \return size of data written on server 
    2502   */ 
    2503   size_t CGrid::getWrittenDataSize()  
    2504   TRY 
    2505   { 
    2506     return getGridLocalElements()->getView(CElementView::FULL)->getSize() ; 
    2507   } 
    2508   CATCH 
    2509  
    2510   /*! 
    2511     Returns the number of indexes written by each server. 
    2512     \return the number of indexes written by each server 
    2513   */ 
    2514   int CGrid::getNumberWrittenIndexes() const 
    2515   TRY 
    2516   { 
    2517     return numberWrittenIndexes_; 
    2518   } 
    2519   CATCH 
    2520  
    2521   /*! 
    2522     Returns the total number of indexes written by the servers. 
    2523     \return the total number of indexes written by the servers 
    2524   */ 
    2525   int CGrid::getTotalNumberWrittenIndexes() const 
    2526   TRY 
    2527   { 
    2528     return totalNumberWrittenIndexes_; 
    2529   } 
    2530   CATCH 
    2531  
    2532   /*! 
    2533     Returns the offset of indexes written by each server. 
    2534     \return the offset of indexes written by each server 
    2535   */ 
    2536   int CGrid::getOffsetWrittenIndexes() const 
    2537   TRY 
    2538   { 
    2539     return offsetWrittenIndexes_; 
    2540   } 
    2541   CATCH 
    2542  
    2543    
    2544   CDistributionClient* CGrid::getClientDistribution() 
    2545   TRY 
    2546   { 
    2547     if (!computeClientDistribution_done_) computeClientDistribution() ; 
    2548     return clientDistribution_; 
    2549   } 
    2550   CATCH_DUMP_ATTR 
    2551  
     1220  
    25521221  bool CGrid::doGridHaveDataDistributed(CContextClient* client) 
    25531222  TRY 
     
    25821251      switch(event.type) 
    25831252      { 
    2584         case EVENT_ID_INDEX : 
    2585           recvIndex(event); 
    2586           return true; 
    2587           break; 
    2588  
    25891253         case EVENT_ID_ADD_DOMAIN : 
    25901254           recvAddDomain(event); 
     
    26261290    gridPtr->sendCreateChild(this->getId(),client); 
    26271291    this->sendAllAttributesToServer(client); 
    2628     //if (isScalarGrid())  sendIndexScalarGrid(client); 
    2629     //else  sendIndex(client); 
    2630     //this->sendAllDomains(client); 
    2631     //this->sendAllAxis(client); 
    2632     //this->sendAllScalars(client); 
    2633  
    26341292    distributeGridToFileServer(client) ; 
    26351293  } 
     
    32091867    if (0 < transformations_->getNbAlgo()) hasTransform_ = true; 
    32101868 
    3211     // Ok, now need to compute index of grid source 
    3212     transformGridSrc->checkMaskIndex(false); 
    3213   } 
     1869 } 
    32141870  CATCH_DUMP_ATTR 
    32151871 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp

    r1943 r1973  
    7575         enum EEventId 
    7676         { 
    77            EVENT_ID_INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR, 
     77           EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR, 
    7878           EVENT_ID_SEND_MASK, 
    7979 
     
    117117         StdSize  getLocalDataSize(void) ; 
    118118 
    119          /// Entrees-sorties de champs 
    120          template <int n> 
    121          void inputField(const CArray<double,n>& field, CArray<double,1>& stored) ; 
    122          template <int n> 
    123          void maskField(const CArray<double,n>& field, CArray<double,1>& stored) ; 
    124          template <int n> 
    125          void outputField(const CArray<double,1>& stored, CArray<double,n>& field) ;   
    126          template <int n> 
    127          void uncompressField(const CArray<double,n>& data, CArray<double,1>& outData) ;  
    128  
     119  
    129120         virtual void parse(xml::CXMLNode& node); 
    130121 
     
    155146 
    156147      public:             
    157          void computeIndexServer(void); 
    158148         void computeIndex(void); 
    159149         void computeIndexScalarGrid(); 
    160          void computeWrittenIndex(); 
    161150         void solveDomainAxisRef(bool areAttributesChecked); 
    162151         void checkElementsAttributes(void) ; 
     
    202191 
    203192         static bool dispatchEvent(CEventServer& event); 
    204          static void recvIndex(CEventServer& event); 
    205          void recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server); 
    206         
    207        public:   
    208          void sendIndex(CContextClient* client, const string& gridId=""); 
    209        private: 
    210           set<CContextClient*> sendIndex_done_ ; 
    211193        
    212194       public: 
    213          void sendIndexScalarGrid(CContextClient* client, const string& gridId=""); 
    214        private: 
    215           set<CContextClient*> sendIndexScalarGrid_done_ ; 
    216        
    217        public: 
    218195         void setContextClient(CContextClient* contextClient); 
    219196 
    220          void computeDomConServer(); 
    221          std::map<int, int> getDomConServerSide(); 
    222197         std::map<int, StdSize> getAttributesBufferSize(CContextClient* client, bool bufferForWriting = false); 
    223198         std::map<int, StdSize> getDataBufferSize(CContextClient* client, const std::string& id = "", bool bufferForWriting = false); 
     
    237212         bool doGridHaveDataToWrite(); 
    238213         bool doGridHaveDataDistributed(CContextClient* client = 0); 
    239          size_t getWrittenDataSize() ; 
    240          int getNumberWrittenIndexes() const; 
    241          int getTotalNumberWrittenIndexes() const; 
    242          int getOffsetWrittenIndexes() const; 
    243214 
    244215         CGridTransformation* getTransformations(); 
     
    255226 
    256227         void completeGrid(CGrid* transformGridSrc = 0); 
    257          void doAutoDistribution(CGrid* transformGridSrc); 
    258228         bool isTransformed(); 
    259229         void setTransformed(); 
     
    271241 
    272242         bool hasMask(void) const; 
    273          void checkMask(void); 
    274          void createMask(void); 
    275          void modifyMask(const CArray<int,1>& indexToModify, bool valueToModify = false); 
    276          void modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue = false); 
    277          
    278243        /** get mask pointer stored in mask_1d, or mask_2d, or..., or mask_7d */ 
    279244         CArray<bool,1> mask_ ; 
    280245         CArray<bool,1>& getMask(void) ; 
    281246 
    282          void computeGridGlobalDimension(const std::vector<CDomain*>& domains, 
    283                                          const std::vector<CAxis*>& axis, 
    284                                          const std::vector<CScalar*>& scalars, 
    285                                          const CArray<int,1>& axisDomainOrder); 
    286  
    287          void computeGridIndexToFileServer(CContextClient* client) ; 
    288   
    289      private: 
     247      private: 
    290248        /** Client-like distribution calculated based on the knowledge of the entire grid */ 
    291249       CDistributionClient* clientDistribution_; 
     
    298256 
    299257     private:    
    300        /** Server-like distribution calculated upon receiving indexes */ 
    301        CDistributionServer* serverDistribution_; 
    302        void computeServerDistribution(void) ; 
    303        bool computeServerDistribution_done_=false ; 
    304      public:  
    305        CDistributionServer* getServerDistribution(void) { if (!computeServerDistribution_done_) computeServerDistribution() ; return serverDistribution_ ;} 
    306  
    307  
    308      private: 
    309        template<int N> 
    310        void checkGridMask(CArray<bool,N>& gridMask, 
    311                           const std::vector<CArray<bool,1>* >& domainMasks, 
    312                           const std::vector<CArray<bool,1>* >& axisMasks, 
    313                           const CArray<int,1>& axisDomainOrder, 
    314                           bool createMask = false); 
    315  
    316         template<int N> 
    317         void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify); 
    318  
    319         template<int N> 
    320         void modifyGridMaskSize(CArray<bool,N>& gridMask, const std::vector<int>& eachDimSize, bool newValue); 
    321  
    322         void storeField_arr(const double* const data, CArray<double, 1>& stored) ; 
    323         void restoreField_arr(const CArray<double, 1>& stored, double* const data) ; 
    324         void uncompressField_arr(const double* const data, CArray<double, 1>& outData) ; 
    325         void maskField_arr(const double* const data, CArray<double, 1>& stored) ; 
    326  
    327258        void setVirtualDomainGroup(CDomainGroup* newVDomainGroup); 
    328259        void setVirtualAxisGroup(CAxisGroup* newVAxisGroup); 
     
    339270        void checkAttributesAfterTransformation(); 
    340271        void setTransformationAlgorithms(); 
    341         void computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
    342                                    const CContextClient* client, 
    343                                    CClientServerMapping::GlobalIndexMap& globalIndexOnServer); 
    344272        int computeGridGlobalDimension(std::vector<int>& globalDim, 
    345273                                       const std::vector<CDomain*> domains, 
     
    348276                                       const CArray<int,1>& axisDomainOrder); 
    349277        int getDistributedDimension(); 
    350  
    351         void computeConnectedClients(CContextClient* client); 
    352         set<CContextClient*> computeConnectedClients_done_ ; 
    353  
    354         void computeConnectedClientsScalarGrid(CContextClient* client);  
    355         set<CContextClient*> computeConnectedClientsScalarGrid_done_ ; 
    356  
    357       public: 
    358 /** Array containing the local index of the grid 
    359  *  storeIndex_client[local_workflow_grid_index] -> local_model_grid_index.  
    360  *  Used to store field from model into the worklow, or to return field into models.   
    361  *  The size of the array is the number of local index of the workflow grid */         
    362         CArray<int, 1> storeIndex_client_; 
    363         void computeStoreIndex_client(void) ; 
    364         bool computeStoreIndex_client_done_ = false ; 
    365         CArray<int, 1>& getStoreIndex_client(void) { if (!computeStoreIndex_client_done_) computeStoreIndex_client() ; return storeIndex_client_ ;} 
    366  
    367 /** Array containing the grid mask masked defined by the mask_nd grid attribute.         
    368   * The corresponding masked field value provided by the model will be replaced by a NaN value 
    369   * in the workflow.  */ 
    370         CArray<bool, 1> storeMask_client_; 
    371         void computeStoreMask_client(void) ; 
    372         bool computeStoreMask_client_done_ = false ; 
    373         CArray<bool, 1>& getStoreMask_client(void) { if (!computeStoreMask_client_done_) computeStoreMask_client() ; return storeMask_client_ ;} 
    374  
    375 /** Map containing the indexes on client side that will be sent to each connected server. 
    376   * storeIndex_toSrv[&contextClient] -> map concerning the contextClient for which the data will be sent (client side) 
    377   * storeIndex_toSrv[&contextClient][rank] -> array of indexes that will be sent to each "rank" of the connected servers  
    378   * storeIndex_toSrv[&contextClient][rank](index_of_buffer_sent_to_server) -> local index of the field of the workflow  
    379   * grid that will be sent to server */ 
    380          std::map<CContextClient*, map<int, CArray<int, 1> > > storeIndex_toSrv_; 
    381  
    382  
    383 /** Map containing the indexes on client side that will be received from each connected server. 
    384   * This map is used to agreggate field data received from server (for reading) into a single array, which will be an entry 
    385   * point of the worklow on client side. 
    386   * storeIndex_toSrv[rank] -> array of indexes that will be received from each "rank" of the connected servers  
    387   * storeIndex_toSrv[rank](index_of_buffer_received_from_server) -> local index of the field in the "workflow grid" 
    388   * that has been received from server */ 
    389          std::map<int, CArray<int, 1> > storeIndex_fromSrv_; // Support, for now, reading with level-1 server 
    390  
    391  
    392 /** Maps storing the number of participating clients for data sent a specific server for a given contextClient, identified 
    393   * by the servers communicator size. In future must be direcly identified by context. 
    394   * nbSender_[context_server_size] -> map the number of client sender by connected rank of servers 
    395   * nbSender_[context_server_size] [rank_server] -> the number of client participating to a send message for a server of rank "rank_server"  
    396   * Usefull to indicate in a message the number of participant needed by the transfer protocol */ 
    397          std::map<int, std::map<int,int> > nbSenders_; 
    398  
    399       private: 
    400 /** Maps storing the number of participating servers for data sent a specific client for a given contextClient. 
    401   * Symetric of nbSenders_, but for server side which want to send data to client. 
    402   * nbReadSender_[context_client_size] -> map the number of server sender by connected rank of clients 
    403   * nbReadSender_[context_client_size] [rank_client] -> the number of server participating to a send message for a client of rank "rank_client"  
    404   * Usefull to indicate in a message the number of participant needed by the transfer protocol */ 
    405          std::map<CContextClient*, std::map<int,int> > nbReadSenders_; 
    406       public: 
    407          std::map<int,int>& getNbReadSenders(CContextClient* client)  
    408          { if (nbReadSenders_.count(client)==0) computeNbReadSenders(client) ; return nbReadSenders_[client] ;} 
    409       private: 
    410          void computeNbReadSenders(CContextClient* client) ; 
    411       
    412  
    413 // Manh Ha's comment: " A client receives global index from other clients (via recvIndex) 
    414 // then does mapping these index into local index of STORE_CLIENTINDEX 
    415 // In this way, store_clientIndex can be used as an input of a source filter 
    416 // Maybe we need a flag to determine whether a client wants to write. TODO " 
    417  
    418       private: 
    419        /** Map storing received data on server side. This map is the equivalent to the storeIndex_client, but for data received from client 
    420         * instead that from model. This map is used to concatenate data received from several clients into a single array on server side 
    421         * which match the local workflow grid. 
    422         * outLocalIndexStoreOnClient_[client_rank] -> Array of index from client of rank "client_rank" 
    423         * outLocalIndexStoreOnClient_[client_rank](index of buffer from client) -> local index of the workflow grid 
    424         * The map is created in CGrid::computeClientIndex and filled upon receiving data in CField::recvUpdateData(). 
    425         * Symetrically it is also used to send data from a server to several client for reading case. */ 
    426         map<int, CArray<size_t, 1>> outLocalIndexStoreOnClient_;  
    427       public: 
    428          void computeOutLocalIndexStoreOnClient(void) ; 
    429       private: 
    430          bool computeOutLocalIndexStoreOnClient_done_ = false ;   
    431       public:    
    432          map<int, CArray<size_t, 1>>& getOutLocalIndexStoreOnClient(void)  
    433          { if (!computeOutLocalIndexStoreOnClient_done_) computeOutLocalIndexStoreOnClient(); return outLocalIndexStoreOnClient_ ; } 
    434  
    435       public: 
    436 /** Indexes calculated based on server-like distribution. 
    437  *  They are used for writing/reading data and only calculated for server level that does the writing/reading. 
    438  *  Along with localIndexToWriteOnClient, these indexes are used to correctly place incoming data.  
    439  *  size of the array : numberWrittenIndexes_ : number of index written in a compressed way 
    440  *  localIndexToWriteOnServer_(compressed_written_index) : -> local uncompressed index that will be written in the file */ 
    441          CArray<size_t,1> localIndexToWriteOnServer_; 
    442  
    443 /** Indexes calculated based on client-like distribution. 
    444   * They are used for writing/reading data and only calculated for server level that does the writing/reading. 
    445   * Along with localIndexToWriteOnServer, these indexes are used to correctly place incoming data.  
    446   * size of the array : numberWrittenIndexes_ 
    447   * localIndexToWriteOnClient_(compressed_written_index) -> local index of the workflow grid*/ 
    448          CArray<size_t,1> localIndexToWriteOnClient_; 
    449  
    450       public:  
     278      public: 
     279 
    451280        bool isDataDistributed(void) ;  
    452281      private: 
     
    455284        std::list<CContextClient*> clients; 
    456285        std::set<CContextClient*> clientsSet; 
    457  
    458       private:   
    459         /** Map storing received indexes on server side sent by clients. Key = sender rank, value = global index array.  
    460             Later, the global indexes received will be mapped onto local index computed with the local distribution. 
    461             outGlobalIndexFromClient_[rank] -> array of global index send by client of rank "rank" 
    462             outGlobalIndexFromClient_[rank](n) -> global index of datav n sent by client 
    463         */       
    464         map<int, CArray<size_t, 1> > outGlobalIndexFromClient_; 
    465       public:   
    466         map<int, CArray<size_t, 1> >& getOutGlobalIndexFromClient() { return outGlobalIndexFromClient_ ;} 
    467286 
    468287      private: 
     
    476295        std::vector<std::string> axisList_, domList_, scalarList_; 
    477296        bool isAxisListSet, isDomListSet, isScalarListSet; 
    478  
    479         CClientServerMapping* clientServerMap_; 
    480         int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_; 
    481297 
    482298/** Map storing local ranks of connected receivers. Key = size of receiver's intracomm. 
     
    499315 
    500316        bool isTransformed_, isGenerated_; 
    501         bool computedWrittenIndex_; 
    502317         
    503318        std::vector<int> axisPositionInGrid_; 
     
    511326        bool hasTransform_; 
    512327 
    513 /** Map storing global indexes of server-like (band-wise) distribution for sending to receivers (client side). 
    514   * Key = size of receiver's intracomm (i.e. number of servers) 
    515   * ~ map<int, umap<int, std::vector<size_t> >> globalIndexOnServer_ 
    516   * globalIndexOnServer_[servers_size] -> map for a distribution of size "servers_size" (number of servers) 
    517   * globalIndexOnServer_[servers_size][server_rank] -> array of global index managed by server of rank "server_rank" 
    518   * globalIndexOnServer_[servers_size][server_rank][n] -> global index of data to be send to the server by client based on sub element of the grid. 
    519   * -> grid masking is not included. 
    520   */ 
    521 //        std::map<CContextClient*, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_; 
    522       std::map<int, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_; 
    523       
    524  
    525328     ////////////////////////////////////////////////////////////////////////////////////// 
    526329     //  this part is related to distribution, element definition, views and connectors  // 
     
    602405   }; // class CGrid 
    603406 
    604    ///-------------------------------------------------------------- 
    605  
    606    template <int n> 
    607    void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) 
    608    TRY 
    609    { 
    610 //#ifdef __XIOS_DEBUG 
    611       if (this->getDataSize() != field.numElements()) 
    612          ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const", 
    613                 << "[ Awaiting data of size = " << this->getDataSize() << ", " 
    614                 << "Received data size = "      << field.numElements() << " ] " 
    615                 << "The data array does not have the right size! " 
    616                 << "Grid = " << this->getId()) 
    617 //#endif 
    618       this->storeField_arr(field.dataFirst(), stored); 
    619    } 
    620    CATCH 
    621  
    622 /* obsolete 
    623    template <int n> 
    624    void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored) 
    625    { 
    626 //#ifdef __XIOS_DEBUG 
    627       if (this->getDataSize() != field.numElements()) 
    628          ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const", 
    629                 << "[ Awaiting data of size = " << this->getDataSize() << ", " 
    630                 << "Received data size = "      << field.numElements() << " ] " 
    631                 << "The data array does not have the right size! " 
    632                 << "Grid = " << this->getId()) 
    633 //#endif 
    634       this->maskField_arr(field.dataFirst(), stored); 
    635    } 
    636 */ 
    637    template <int n> 
    638    void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored) 
    639    { 
    640       auto connector = getModelToWorkflowConnector() ; 
    641  
    642       if (connector->getSrcSize() != field.numElements()) 
    643          ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const", 
    644                 << "[ Awaiting data of size = " << this->getDataSize() << ", " 
    645                 << "Received data size = "      << field.numElements() << " ] " 
    646                 << "The data array does not have the right size! " 
    647                 << "Grid = " << this->getId()) 
    648       const double nanValue = std::numeric_limits<double>::quiet_NaN(); 
    649       connector->transfer(field, stored, nanValue) ; 
    650    } 
    651  
    652  
    653  
    654    template <int n> 
    655    void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) 
    656    TRY 
    657    { 
    658 //#ifdef __XIOS_DEBUG 
    659       if (this->getDataSize() != field.numElements()) 
    660          ERROR("void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const", 
    661                 << "[ Size of the data = " << this->getDataSize() << ", " 
    662                 << "Output data size = "   << field.numElements() << " ] " 
    663                 << "The ouput array does not have the right size! " 
    664                 << "Grid = " << this->getId()) 
    665 //#endif 
    666       this->restoreField_arr(stored, field.dataFirst()); 
    667    } 
    668    CATCH 
    669  
    670    /*! 
    671      This function removes the effect of mask on received data on the server. 
    672      This function only serve for the checking purpose. TODO: Something must be done to seperate mask and data_index from each other in received data 
    673      \data data received data with masking effect on the server 
    674      \outData data without masking effect 
    675    */ 
    676    template <int N> 
    677    void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData) 
    678    TRY 
    679    {       
    680      uncompressField_arr(data.dataFirst(), outData); 
    681    } 
    682    CATCH 
    683  
    684    template<int N> 
    685    void CGrid::checkGridMask(CArray<bool,N>& gridMask, 
    686                              const std::vector<CArray<bool,1>* >& domainMasks, 
    687                              const std::vector<CArray<bool,1>* >& axisMasks, 
    688                              const CArray<int,1>& axisDomainOrder, 
    689                              bool createMask) 
    690    TRY 
    691    { 
    692      int idx = 0; 
    693      int numElement = axisDomainOrder.numElements(); 
    694      int dim = domainMasks.size() * 2 + axisMasks.size(); 
    695      std::vector<CDomain*> domainP = this->getDomains(); 
    696      std::vector<CAxis*> axisP = this->getAxis(); 
    697  
    698      std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim); 
    699      std::vector<int> currentIndex(dim); 
    700      int idxDomain = 0, idxAxis = 0; 
    701     for (int i = 0; i < numElement; ++i) 
    702     { 
    703       indexMap[i] = idx; 
    704       if (2 == axisDomainOrder(i)) { 
    705           eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni; 
    706           eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj; 
    707           idx += 2; ++idxDomain; 
    708       } 
    709       else if (1 == axisDomainOrder(i)) { 
    710 //        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements(); 
    711         eachDimSize[indexMap[i]] = axisP[idxAxis]->n; 
    712         ++idx; ++idxAxis; 
    713       } 
    714       else {}; 
    715     } 
    716  
    717     if (!gridMask.isEmpty() && !createMask) 
    718     { 
    719       for (int i = 0; i < dim; ++i) 
    720       { 
    721         if (gridMask.extent(i) != eachDimSize[i]) 
    722           ERROR("CGrid::checkMask(void)", 
    723                 << "The mask has one dimension whose size is different from the one of the local grid." << std::endl 
    724                 << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl 
    725                 << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl 
    726                 << "Grid = " << this->getId()) 
    727       } 
    728     } 
    729     else { 
    730         CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 
    731         gridMask = true; 
    732     } 
    733  
    734     int ssize = gridMask.numElements(); 
    735     idx = 0; 
    736     while (idx < ssize) 
    737     { 
    738       for (int i = 0; i < dim-1; ++i) 
    739       { 
    740         if (idxLoop[i] == eachDimSize[i]) 
    741         { 
    742           idxLoop[i] = 0; 
    743           ++idxLoop[i+1]; 
    744         } 
    745       } 
    746  
    747       // Find out outer index 
    748       idxDomain = idxAxis = 0; 
    749       bool maskValue = true; 
    750       for (int i = 0; i < numElement; ++i) 
    751       { 
    752         if (2 == axisDomainOrder(i)) 
    753         { 
    754           int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]; 
    755           if (idxTmp < (*domainMasks[idxDomain]).numElements()) 
    756             maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp); 
    757           else 
    758             maskValue = false; 
    759           ++idxDomain; 
    760         } 
    761         else if (1 == axisDomainOrder(i)) 
    762         { 
    763           int idxTmp = idxLoop[indexMap[i]]; 
    764           if (idxTmp < (*axisMasks[idxAxis]).numElements()) 
    765             maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp); 
    766           else 
    767             maskValue = false; 
    768  
    769           ++idxAxis; 
    770         } 
    771       } 
    772  
    773       int maskIndex = idxLoop[0]; 
    774       int mulDim = 1; 
    775       for (int k = 1; k < dim; ++k) 
    776       { 
    777         mulDim *= eachDimSize[k-1]; 
    778         maskIndex += idxLoop[k]*mulDim; 
    779       } 
    780       *(gridMask.dataFirst()+maskIndex) &= maskValue; 
    781  
    782       ++idxLoop[0]; 
    783       ++idx; 
    784     } 
    785    } 
    786    CATCH_DUMP_ATTR 
    787  
    788    template<int N> 
    789    void CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask, 
    790                                   const std::vector<int>& eachDimSize, 
    791                                   bool newValue) 
    792    TRY 
    793    { 
    794       if (N != eachDimSize.size()) 
    795       { 
    796         // ERROR("CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask, 
    797         //                                  const std::vector<int>& eachDimSize, 
    798         //                                  bool newValue)", 
    799         //       << "Dimension size of the mask is different from input dimension size." << std::endl 
    800         //       << "Mask dimension is " << N << "." << std::endl 
    801         //       << "Input dimension is " << eachDimSize.size() << "." << std::endl 
    802         //       << "Grid = " << this->getId()) 
    803       } 
    804       CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 
    805       gridMask = newValue; 
    806    } 
    807    CATCH_DUMP_ATTR 
    808                                   
    809  
    810    /*! 
    811      Modify the current mask of grid, the local index to be modified will take value false 
    812      \param [in/out] gridMask current mask of grid 
    813      \param [in] indexToModify local index to modify 
    814    */ 
    815    template<int N> 
    816    void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify) 
    817    TRY 
    818    {      
    819      int num = indexToModify.numElements(); 
    820      for (int idx = 0; idx < num; ++idx) 
    821      { 
    822        *(gridMask.dataFirst()+indexToModify(idx)) = valueToModify; 
    823      } 
    824    } 
    825    CATCH_DUMP_ATTR 
    826  
    827    ///-------------------------------------------------------------- 
    828  
    829  
    830  
    831407   // Declare/Define CGridGroup and CGridDefinition 
    832408   DECLARE_GROUP(CGrid); 
Note: See TracChangeset for help on using the changeset viewer.