Changeset 1587


Ignore:
Timestamp:
10/15/18 16:42:33 (2 years ago)
Author:
ymipsl
Message:

XIOS - OASIS interaction : due to many problem occurring in the oasis/XIOS initialization phase due to a bad order of intialization call from both, you have now the possibily to explicitly inform xios that the servers must call oasis_enddef().
New rules : On model side, before calling oasis_enddef, you must add a call to "xios_oasis_enddef()"
Old rules : oasis_enddef must be call before any call to "xios_context_initialize" otherwise it may lead to a deadlock.
You can use the old rules if the variable <call_oasis_enddef> is set to false (default value is true), and by this way no need to modify the source code of the models

YM

Location:
XIOS/trunk/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/client.cpp

    r1542 r1587  
    1111#include "timer.hpp" 
    1212#include "buffer_client.hpp" 
     13#include "string_tools.hpp" 
    1314 
    1415namespace xios 
     
    2324    StdOFStream CClient::m_infoStream; 
    2425    StdOFStream CClient::m_errorStream; 
    25  
    2626    MPI_Comm& CClient::getInterComm(void)   { return (interComm); } 
    27  
     27      
    2828///--------------------------------------------------------------- 
    2929/*! 
     
    230230      } 
    231231    } 
     232 
     233/*! 
     234 * \fn void CClient::callOasisEnddef(void) 
     235 * \brief Send the order to the servers to call "oasis_enddef". It must be done by each compound of models before calling oasis_enddef on client side 
     236 * Function is only called by client. 
     237 */ 
     238    void CClient::callOasisEnddef(void) 
     239    { 
     240      bool oasisEnddef=CXios::getin<bool>("call_oasis_enddef",true) ; 
     241      if (!oasisEnddef) ERROR("void CClient::callOasisEnddef(void)", <<"Function xios_oasis_enddef called but variable <call_oasis_enddef> is set to false."<<endl 
     242                                                                     <<"Variable <call_oasis_enddef> must be set to true"<<endl) ; 
     243      if (CXios::isServer) 
     244      // Attached mode 
     245      { 
     246        // nothing to do    
     247      } 
     248      else 
     249      { 
     250        int rank ; 
     251        int msg=0 ; 
     252 
     253        MPI_Comm_rank(intraComm,&rank) ; 
     254        if (rank==0)  
     255        { 
     256          MPI_Send(&msg,1,MPI_INT,0,5,interComm) ; // tags oasis_endded = 5 
     257        } 
     258 
     259      } 
     260    } 
     261 
    232262 
    233263    void CClient::finalize(void) 
  • XIOS/trunk/src/client.hpp

    r1243 r1587  
    1313        static void finalize(void); 
    1414        static void registerContext(const string& id, MPI_Comm contextComm); 
     15        static void callOasisEnddef(void) ; 
    1516 
    1617        static MPI_Comm intraComm; 
  • XIOS/trunk/src/interface/c/icdata.cpp

    r1542 r1587  
    8181     CClient::registerContext(str, comm); 
    8282     CTimer::get("XIOS init context").suspend(); 
     83     CTimer::get("XIOS").suspend(); 
     84   } 
     85 
     86   void cxios_oasis_enddef() 
     87   { 
     88     CTimer::get("XIOS").resume(); 
     89     CClient::callOasisEnddef(); 
    8390     CTimer::get("XIOS").suspend(); 
    8491   } 
  • XIOS/trunk/src/interface/fortran/idata.F90

    r1158 r1587  
    4242      END SUBROUTINE cxios_context_finalize 
    4343 
    44  
     44      SUBROUTINE  cxios_oasis_enddef() BIND(C) 
     45         USE ISO_C_BINDING 
     46      END SUBROUTINE cxios_oasis_enddef 
     47       
    4548      SUBROUTINE  cxios_finalize() BIND(C) 
    4649      END SUBROUTINE cxios_finalize 
     
    507510    END SUBROUTINE  xios(finalize) 
    508511 
     512   SUBROUTINE  xios(oasis_enddef) 
     513   IMPLICIT NONE 
     514 
     515      CALL cxios_oasis_enddef 
     516 
     517    END SUBROUTINE  xios(oasis_enddef) 
    509518 
    510519   SUBROUTINE xios(close_context_definition)() 
  • XIOS/trunk/src/interface/fortran/ixios.F90

    r981 r1587  
    1313 
    1414USE idata, ONLY : xios(initialize), xios(init_server), xios(finalize), xios(context_initialize), xios(context_is_initialized), & 
    15                   xios(close_context_definition), xios(context_finalize), xios(solve_inheritance) 
     15                  xios(close_context_definition), xios(context_finalize), xios(solve_inheritance), xios(oasis_enddef) 
    1616 
    1717USE idomain, ONLY : txios(domain), txios(domaingroup), xios(is_valid_domain), xios(is_valid_domaingroup) 
  • XIOS/trunk/src/server.cpp

    r1542 r1587  
    1414#include "timer.hpp" 
    1515#include "event_scheduler.hpp" 
     16#include "string_tools.hpp" 
    1617 
    1718namespace xios 
     
    343344 
    344345        string codesId=CXios::getin<string>("oasis_codes_id") ; 
    345         vector<string> splitted ; 
    346         boost::split( splitted, codesId, boost::is_any_of(","), boost::token_compress_on ) ; 
     346        vector<string> oasisCodeId=splitRegex(codesId,"\\s*,\\s*") ; 
     347  
    347348        vector<string>::iterator it ; 
    348349 
     
    352353 
    353354//      (2) Create interComms with models 
    354         for(it=splitted.begin();it!=splitted.end();it++) 
     355        for(it=oasisCodeId.begin();it!=oasisCodeId.end();it++) 
    355356        { 
    356357          oasis_get_intercomm(newComm,*it) ; 
     
    386387        } 
    387388        if (CXios::usingServer2) delete [] srvGlobalRanks ; 
    388         oasis_enddef() ; 
     389 
     390        bool oasisEnddef=CXios::getin<bool>("call_oasis_enddef",true) ; 
     391        if (!oasisEnddef) oasis_enddef() ; 
    389392      } 
    390393 
     
    442445           listenContext(); 
    443446           listenRootContext(); 
     447           listenOasisEnddef() ; 
     448           listenRootOasisEnddef() ; 
    444449           if (!finished) listenFinalize() ; 
    445450         } 
     
    447452         { 
    448453           listenRootContext(); 
     454           listenRootOasisEnddef() ; 
    449455           if (!finished) listenRootFinalize() ; 
    450456         } 
     
    516522        } 
    517523      } 
     524 
     525 
     526   /*! 
     527    * Root process is listening for an order sent by client to call "oasis_enddef". 
     528    * The root client of a compound send the order (tag 5). It is probed and received. 
     529    * When the order has been received from each coumpound, the server root process ping the order to the root processes of the secondary levels of servers (if any). 
     530    * After, it also inform (asynchronous call) other processes of the communicator that the oasis_enddef call must be done 
     531    */ 
     532     
     533     void CServer::listenOasisEnddef(void) 
     534     { 
     535        int flag ; 
     536        MPI_Status status ; 
     537        list<MPI_Comm>::iterator it; 
     538        int msg ; 
     539        static int nbCompound=0 ; 
     540        int size ; 
     541        static bool sent=false ; 
     542        static MPI_Request* allRequests ; 
     543        static MPI_Status* allStatus ; 
     544 
     545 
     546        if (sent) 
     547        { 
     548          MPI_Comm_size(intraComm,&size) ; 
     549          MPI_Testall(size,allRequests, &flag, allStatus) ; 
     550          if (flag==true) 
     551          { 
     552            delete [] allRequests ; 
     553            delete [] allStatus ; 
     554            sent=false ; 
     555          } 
     556        } 
     557         
     558 
     559        for(it=interCommLeft.begin();it!=interCommLeft.end();it++) 
     560        { 
     561           MPI_Status status ; 
     562           traceOff() ; 
     563           MPI_Iprobe(0,5,*it,&flag,&status) ;  // tags oasis_endded = 5 
     564           traceOn() ; 
     565           if (flag==true) 
     566           { 
     567              MPI_Recv(&msg,1,MPI_INT,0,5,*it,&status) ; // tags oasis_endded = 5 
     568              nbCompound++ ; 
     569              if (nbCompound==interCommLeft.size()) 
     570              { 
     571                for (std::list<MPI_Comm>::iterator it = interCommRight.begin(); it != interCommRight.end(); it++) 
     572                { 
     573                   MPI_Send(&msg,1,MPI_INT,0,5,*it) ; // tags oasis_endded = 5 
     574                } 
     575                MPI_Comm_size(intraComm,&size) ; 
     576                allRequests= new MPI_Request[size] ; 
     577                allStatus= new MPI_Status[size] ; 
     578                for(int i=0;i<size;i++) MPI_Isend(&msg,1,MPI_INT,i,5,intraComm,&allRequests[i]) ; // tags oasis_endded = 5 
     579                sent=true ; 
     580              } 
     581           } 
     582        } 
     583     } 
     584      
     585   /*! 
     586    * Processes probes message from root process if oasis_enddef call must be done. 
     587    * When the order is received it is scheduled to be treated in a synchronized way by all server processes of the communicator 
     588    */ 
     589     void CServer::listenRootOasisEnddef(void) 
     590     { 
     591       int flag ; 
     592       MPI_Status status ; 
     593       const int root=0 ; 
     594       int msg ; 
     595       static bool eventSent=false ; 
     596 
     597       if (eventSent) 
     598       { 
     599         boost::hash<string> hashString; 
     600         size_t hashId = hashString("oasis_enddef"); 
     601         if (eventScheduler->queryEvent(0,hashId)) 
     602         { 
     603           oasis_enddef() ; 
     604           eventSent=false ; 
     605         } 
     606       } 
     607          
     608       traceOff() ; 
     609       MPI_Iprobe(root,5,intraComm, &flag, &status) ; 
     610       traceOn() ; 
     611       if (flag==true) 
     612       { 
     613         MPI_Recv(&msg,1,MPI_INT,root,5,intraComm,&status) ; // tags oasis_endded = 5 
     614         boost::hash<string> hashString; 
     615         size_t hashId = hashString("oasis_enddef"); 
     616         eventScheduler->registerEvent(0,hashId); 
     617         eventSent=true ; 
     618       } 
     619     } 
     620 
     621 
     622 
     623      
    518624 
    519625     void CServer::listenContext(void) 
  • XIOS/trunk/src/server.hpp

    r1378 r1587  
    2222        static void listenRootContext(void); 
    2323        static void listenRootFinalize(void); 
     24        static void listenRootOasisEnddef(void); 
     25        static void listenOasisEnddef(void); 
    2426        static void registerContext(void* buff,int count, int leaderRank=0); 
    2527 
     
    7274        static StdOFStream m_infoStream; 
    7375        static StdOFStream m_errorStream; 
    74  
    7576        static void openStream(const StdString& fileName, const StdString& ext, std::filebuf* fb); 
    7677    }; 
Note: See TracChangeset for help on using the changeset viewer.