Non-blocking Accept()

97 views
Skip to first unread message

Allan Ma

unread,
Feb 25, 2016, 2:47:17 AM2/25/16
to mpi4py
Hi,

I was trying to make a toy example of the master process and came across an issue.

See the following line in mpi4py's server example.


I wonder if there's a way that the server won't block on this line:

"icomm = COMM.Accept(port, info, root=0)" and proceed to do other things.

The ideal behaviour of the asynchronous server should be:

Loop:
{
1. accept connections from a new client if there's any.
2. respond to a request from a client for merging parameter update if there's any.

I wonder if there's a way that to realize this without blocking on Accept.

Thanks,

Allan

Lisandro Dalcin

unread,
Feb 25, 2016, 2:55:53 AM2/25/16
to mpi4py
No, MPI does not provide such feature. Maybe you can emulate it
executing the Accept() call in a new thread (mpi4py releases the GIL
while the process blocks). Another option to explore would be to use
sockets and MPI.Comm.Join(), take a look in test/test_dynproc.py


--
Lisandro Dalcin
============
Research Scientist
Computer, Electrical and Mathematical Sciences & Engineering (CEMSE)
Extreme Computing Research Center (ECRC)
King Abdullah University of Science and Technology (KAUST)
http://ecrc.kaust.edu.sa/

4700 King Abdullah University of Science and Technology
al-Khawarizmi Bldg (Bldg 1), Office # 4332
Thuwal 23955-6900, Kingdom of Saudi Arabia
http://www.kaust.edu.sa

Office Phone: +966 12 808-0459

Allan

unread,
Feb 25, 2016, 2:23:13 PM2/25/16
to mpi4py
Thank you very much. That helps. I'm thinking the second way.  just to use socket to setup a REQ-REP connection  first and then use this connection to prepare for further MPI communication setup.

Allan

Allan

unread,
Mar 1, 2016, 3:15:57 PM3/1/16
to mpi4py
Hi Lisandro,

I just tried out the socket and MPI.Comm.Join() method. The MPI.Comm.Join() function works when the server and client run on the same node. However, the MPI.Comm.Join() keeps waiting when server and client run on two separate nodes. 

            fd = client.fileno()
            
            intercomm = MPI.Comm.Join(fd)    <- blocked here on both the server and client side

I can setup the socket connection though when I got the ip address of the server with socket.gethostbyname(socket.gethostname()) and plug it in the socket.connect("tcp://address:port) on the client. I doubt this is the same problem with firewall when I tried Accept() and Connect() method:

------------------------------------------------------------
A process or daemon was unable to complete a TCP connection
to another process:
  Local host:    cop7
  Remote host:   cop7
This is usually caused by a firewall on the remote host. Please
check that any firewall (e.g., iptables) has been disabled and
try again.
------------------------------------------------------------

By the way, I can always start the server and client processes with one mpirun call and setting the -host attribute for connecting two processes on different nodes. But the ideal behaviour is asynchronously starting them. I wonder if you have any idea. Thanks in advance.

Allan

On Thursday, February 25, 2016 at 2:55:53 AM UTC-5, Lisandro Dalcin wrote:

Lisandro Dalcin

unread,
Mar 4, 2016, 4:19:55 AM3/4/16
to mpi4py
On 1 March 2016 at 23:15, Allan <mahe...@gmail.com> wrote:
> I just tried out the socket and MPI.Comm.Join() method. The MPI.Comm.Join()
> function works when the server and client run on the same node. However, the
> MPI.Comm.Join() keeps waiting when server and client run on two separate
> nodes.
>
> fd = client.fileno()
>
> intercomm = MPI.Comm.Join(fd) <- blocked here on both the
> server and client side

At this point, I'm not sure what you are actually trying to do. You
simply cannot create a new communicator with accept/connect/join in a
non-blocking way, and unfortunatelly MPI does not have any polling
mechanism to check about requests for connection.

My suggestion about using sockets (or other mechanisms, you could use
POSIX FIFO , that could be made to work) is that now you have an
option to implement your OWN non-blocking logic. Look at this example
from the Python docs:

https://docs.python.org/2/library/socket.html#example

That way that code works is almost the same as an MPI version using
Accept()/Connect(). They are blocking, both the client and the server
block at the accept/connect call. HOWEVER, you can add more logic, e.g
making the accept() call in a separate thread and block for a
connection, while your main code is free to do other work (BTW, while
connect() blocks, Python will release the GIL, so you are fine, your
main thread will not be harmed).

At this point, it would be better if you provide us with some more
details about your actual application.
Reply all
Reply to author
Forward
0 new messages