<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>All,</div><div><br></div><div>I'm running an MPI_Comm_accept in a separate thread whose purpose is to allow connections from other (hitherto unknown) MPI universes. A well-known issue of such configurations is that MPI_Comm_accept being blocking, in order for the application to exit, a connection MUST be made even if no actual other universes attempted to connect. In this situation (see Gropp, et al. "Using Advanced MPI", section 6.5) it seems the 'customary' solution is to have the local universe connect to itself and then shut down.</div><div> </div><div>However, I'm getting the following error on exit:</div><div><br></div><div>Fatal error in PMPI_Comm_accept: Message truncated, error stack:<br>PMPI_Comm_accept(129).............: MPI_Comm_accept(port="tag#0$description#<a href="http://aesop.cl.cam.ac.uk">aesop.cl.cam.ac.uk</a>$port#43337$ifname#128.232.98.176$", MPI_INFO_NULL, root=6, MPI_COMM_WORLD, newcomm=0x1473f24) failed<br>MPID_Comm_accept(153).............: <br>MPIDI_Comm_accept(1005)...........: <br>MPIR_Bcast_intra(1249)............: <br>MPIR_SMP_Bcast(1088)..............: <br>MPIR_Bcast_binomial(239)..........: <br>MPIDI_CH3U_Receive_data_found(131): Message from rank 0 and tag 2 truncated; 260 bytes received but buffer size is 12</div><div><br></div><div>You typically get several of these messages, the number seems to vary from trial to trial, I'm guessing it comes from different MPI processes (although there is no fixed relationship between number of processes started and number of error messages)</div><div><br></div><div>Does anyone have any suggestions on what types of problems might cause this error? (I'm not expecting you to identify and debug the problem specifically, unless, perhaps, this error is indicative of some particular mistake, just would like any hints on where to look)</div><div><br></div><div>If it helps, here are the 3 main relevant functions involved - there is, of course, a lot more going on in the application besides these, but the error is occurring at shutdown and by this point the rest of the application is quiescent. Also note that the Connect routine is NOT called at shutdown; it's invoked when a 'real' universe wants to connect. <br></div><div><br></div><div>//------------------------------------------------------------------------------<br><br>void* CommonBase::Accept(void* par)<br>/* Blocking routine to connect to another MPI universe by publishing a port.<br>   This operates in a separate thread to avoid blocking the whole process.<br>*/<br>{<br>CommonBase* parent=static_cast<CommonBase*>(par);</div><div><br></div><div>while (parent->AcceptConns.load(std::memory_order_relaxed))<br>{<br>// run the blocking accept itself.<br>if (MPI_Comm_accept(parent->MPIPort.load(std::memory_order_seq_cst),MPI_INFO_NULL,parent->Lrank.load(std::memory_order_relaxed),MPI_COMM_WORLD,parent->Tcomm.load(std::memory_order_seq_cst)))<br>{<br>   printf("Error: attempt to connect to another MPI universe failed\n");<br>   parent->AcceptConns.store(false,std::memory_order_relaxed);<br>   break;<br>}<br>// Now trigger the Connect process in the main thread to complete the setup<br>PMsg_p Creq;<br>string N("");              // zero-length string indicates a server-side connection<br>Creq.Put(0,&N);<br>Creq.Key(Q::SYST,Q::CONN);<br>Creq.Src(0);<br>Creq.comm = MPI_COMM_SELF;<br>Creq.Send(0);<br>while (*(parent->Tcomm.load(std::memory_order_seq_cst)) != MPI_COMM_NULL); // block until connect has succeeded<br>}<br>pthread_exit(par);<br>return par;<br>}</div><div><br></div><div>//------------------------------------------------------------------------------<br><br>unsigned CommonBase::Connect(string svc)<br>// connects this process' MPI universe to a remote universe that has published<br>// a name to access it by.<br>{<br>int error = MPI_SUCCESS;<br>// a server has its port already so can just open a comm<br>if (svc=="") Comms.push_back(*Tcomm.load(std::memory_order_seq_cst));<br>else // clients need to look up the service name<br>{<br>   MPI_Comm newcomm;<br>   char port[MPI_MAX_PORT_NAME];<br>   // Get the published port for the service name asked for.<br>   // Exit if we don't get a port, probably because the remote universe isn't<br>   // initialised yet (we can always retry).<br>   if (error = MPI_Lookup_name(svc.c_str(),MPI_INFO_NULL,port)) return error;<br>   // now try to establish the connection itself. Again, we can always retry.<br>   if (error = MPI_Comm_connect(port,MPI_INFO_NULL,0,MPI_COMM_WORLD,&newcomm)) return error;<br>   Comms.push_back(newcomm); // as long as we succeeded, add to the list of comms<br>}<br>int rUsize;<br>MPI_Comm_remote_size(Comms.back(), &rUsize);<br>Usize.push_back(rUsize);       // record the size of the remote universe<br>FnMapx.push_back(new FnMap_t); // give the new comm some function tables to use<br>pPmap.push_back(new ProcMap(this));  // and a new processor map for the remote group<br>PMsg_p prMsg;<br>SendPMap(Comms.back(), &prMsg);        // Send our process data to the remote group<br>int fIdx=FnMapx.size()-1;<br>// populate the new function table with the global functions<br>(*FnMapx[fIdx])[Msg_p::KEY(Q::EXIT                )] = &CommonBase::OnExit;<br>(*FnMapx[fIdx])[Msg_p::KEY(Q::PMAP                )] = &CommonBase::OnPmap;<br>(*FnMapx[fIdx])[Msg_p::KEY(Q::SYST,Q::PING,Q::ACK )] = &CommonBase::OnSystPingAck;<br>(*FnMapx[fIdx])[Msg_p::KEY(Q::SYST,Q::PING,Q::REQ )] = &CommonBase::OnSystPingReq;<br>(*FnMapx[fIdx])[Msg_p::KEY(Q::TEST,Q::FLOO        )] = &CommonBase::OnTestFloo;<br>if (svc=="") *Tcomm.load(std::memory_order_seq_cst) = MPI_COMM_NULL;  // release any Accept comm.<br>return error;<br>}</div><div><br></div><div>//------------------------------------------------------------------------------<br><br>unsigned CommonBase::OnExit(PMsg_p * Z,unsigned cIdx)<br>// Do not post anything further here - the LogServer may have already gone<br>{<br>AcceptConns.store(false,std::memory_order_relaxed); // stop accepting connections<br>if (acpt_running)<br>{<br>   printf("(%s)::CommonBase::OnExit closing down Accept MPI request\n",Sderived.c_str());<br>   fflush(stdout);<br>   // have to close the Accept thread via a matching MPI_Comm_connect<br>   // because the MPI interface has made no provision for a nonblocking accept, thus<br>   // otherwise the Accept thread will block forever waiting for a message that will<br>   // never come because we are shutting down. See Gropp, et al. "Using Advanced MPI"<br>   MPI_Comm dcomm;<br>    MPI_Comm_connect(MPIPort.load(std::memory_order_seq_cst),MPI_INFO_NULL,Lrank.load(std::memory_order_relaxed),MPI_COMM_WORLD,&dcomm);<br>   pthread_join(MPI_accept,NULL);<br>   acpt_running = false;<br>}<br>if (Urank == Lrank.load(std::memory_order_relaxed))<br>{<br>   MPI_Unpublish_name(MPISvc,MPI_INFO_NULL,MPIPort.load(std::memory_order_seq_cst));<br>   MPI_Close_port(MPIPort.load(std::memory_order_seq_cst));<br>}<br>return 1;<br>}<br><br></div></div></div></div></div></div>