Ignore:
Timestamp:
08/04/16 16:24:20 (8 years ago)
Author:
rlacroix
Message:

Fix the client/server communication protocol.

In the some extreme cases a deadlock could occur. To fix this, the number of buffered events must be properly limited.

If you noticed decreased performance due to this commit, please let us know about it.

Fixes ticket #91.

File:
1 edited

Legend:

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

    r884 r917  
    2121    */ 
    2222    CContextClient::CContextClient(CContext* parent, MPI_Comm intraComm_, MPI_Comm interComm_, CContext* cxtSer) 
    23      : mapBufferSize_(), parentServer(cxtSer) 
     23     : mapBufferSize_(), parentServer(cxtSer), maxBufferedEvents(4) 
    2424    { 
    2525      context = parent; 
     
    7070 
    7171      timeLine = 0; 
    72  
    7372    } 
    7473 
     
    179178        mapBufferSize_[rank] = CXios::minBufferSize; 
    180179      } 
    181       CClientBuffer* buffer = buffers[rank] = new CClientBuffer(interComm, rank, mapBufferSize_[rank]); 
     180      CClientBuffer* buffer = buffers[rank] = new CClientBuffer(interComm, rank, mapBufferSize_[rank], maxBufferedEvents); 
    182181      // Notify the server 
    183182      CBufferOut* bufOut = buffer->getBuffer(sizeof(StdSize)); 
     
    219218 
    220219   /*! 
    221    Set buffer size for each connection 
    222    \param [in] mapSize mapping rank of connected server to size of allocated buffer 
    223    */ 
    224    void CContextClient::setBufferSize(const std::map<int,StdSize>& mapSize) 
     220    * Set the buffer size for each connection. Warning: This function is collective. 
     221    * 
     222    * \param [in] mapSize maps the rank of the connected servers to the size of the correspoinding buffer 
     223    * \param [in] maxEventSize maps the rank of the connected servers to the size of the biggest event 
     224   */ 
     225   void CContextClient::setBufferSize(const std::map<int,StdSize>& mapSize, const std::map<int,StdSize>& maxEventSize) 
    225226   { 
    226227     mapBufferSize_ = mapSize; 
     228 
     229     // Compute the maximum number of events that can be safely buffered. 
     230     double minBufferSizeEventSizeRatio = std::numeric_limits<double>::max(); 
     231     for (std::map<int,StdSize>::const_iterator it = mapSize.begin(), ite = mapSize.end(); it != ite; ++it) 
     232     { 
     233       double ratio = double(it->second) / maxEventSize.at(it->first); 
     234       if (ratio < minBufferSizeEventSizeRatio) minBufferSizeEventSizeRatio = ratio; 
     235     } 
     236     MPI_Allreduce(MPI_IN_PLACE, &minBufferSizeEventSizeRatio, 1, MPI_DOUBLE, MPI_MIN, intraComm); 
     237 
     238     if (minBufferSizeEventSizeRatio < 1.0) 
     239       ERROR("void CContextClient::setBufferSize(const std::map<int,StdSize>& mapSize, const std::map<int,StdSize>& maxEventSize)", 
     240             << "The buffer sizes and the maximum events sizes are incoherent."); 
     241 
     242     maxBufferedEvents = size_t(2 * minBufferSizeEventSizeRatio) // there is room for two local buffers on the server 
     243                          + size_t(minBufferSizeEventSizeRatio)  // one local buffer can always be fully used 
     244                          + 1;                                   // the other local buffer might contain only one event 
    227245   } 
    228246 
Note: See TracChangeset for help on using the changeset viewer.