Reputation: 21
The error I'm getting is:
Traceback (most recent call last): File "client2.py", line 14, in port = MPI.Lookup_name(service, info) File "Comm.pyx", line 1676, in mpi4py.MPI.Lookup_name (src/mpi4py.MPI.c:64562) mpi4py.MPI.Exception: MPI_ERR_NAME: invalid name argument
I am trying implement client/server model using mpi4py. Server can Publish_name and waits for clients. However, client can not use the necessary method described in the api as shown below:
#! /usr/bin/env python
from mpi4py import MPI
rank = MPI.COMM_WORLD.Get_rank()
def log(msg, *args):
if rank == 0:
print msg % args
info = MPI.INFO_NULL
service = 'pyeval'
log("looking-up service '%s'", service)
port = MPI.Lookup_name(service, info) // PROBLEM HERE !
log("service located at port '%s'", port)
root = 0
log('waiting for server connection...')
comm = MPI.COMM_WORLD.Connect(port, info, root)
log('server connected...')
while True:
done = False
if rank == root:
try:
message = raw_input('pyeval>>> ')
if message == 'quit':
message = None
done = True
except EOFError:
message = None
done = True
comm.Send(message, dest=0, tag=0)
else:
message = None
done = MPI.COMM_WORLD.Bcast(done, root)
if done:
break
log('disconnecting server...')
comm.Disconnect()
I am also posting the server side code, as it might help:
#! /usr/bin/env python
from mpi4py import MPI
rank = MPI.COMM_WORLD.Get_rank()
def log(msg, *args):
if rank == 0:
print msg % args
log('')
info = MPI.INFO_NULL
port = MPI.Open_port(info)
log("opened port: '%s'", port)
service = 'pyeval'
MPI.Publish_name(service, info, port)
log("published service: '%s'", service)
root = 0
log('waiting for client connection...')
comm = MPI.COMM_WORLD.Accept(port, info, root)
log('client connected...')
while True:
done = False
if rank == root:
message = comm.Recv(source=0, tag=0)
if message is None:
done = True
else:
try:
print 'eval(%r) -> %r' % (message, eval(message))
except StandardError:
print "invalid expression: %s" % message
done = MPI.COMM_WORLD.Bcast(done, root)
if done:
break
log('disconnecting client...')
comm.Disconnect()
log('upublishing service...')
MPI.Unpublish_name(service, info, port)
log('closing port...')
MPI.Close_port(port)
Upvotes: 1
Views: 3235
Reputation: 21
I needed to use ompi-server for name publishing and name look ups. Following steps for executing server and client worked for me:
ompi-server
rm -f /tmp/ompi-server.txt
killall ompi-server
ompi-server -r /tmp/ompi-server.txt
server
mpiexec --ompi-server file:/tmp/ompi-server.txt -n 1 python server.py
client
mpiexec --ompi-server file:/tmp/ompi-server.txt -n 1 python client.py
Upvotes: 1
Reputation: 50937
You want the server to spawn the clients so that they can communicate. Also, your Send/Recv/Bcasts should be send/recv/bcast ; mpi4py supports both Send and send, Recv and recv, etc, but the upper case versions take "regular" C/C++/Fortran arguments, and the lowercase ones are more pythonic.
So the following succesfully runs for me - client.py:
#! /usr/bin/env python
from mpi4py import MPI
rank = MPI.COMM_WORLD.Get_rank()
def log(msg, *args):
if rank == 0:
print msg % args
info = MPI.INFO_NULL
service = "pyeval"
log("looking-up service '%s'", service)
port = MPI.Lookup_name(service)
log("service located at port '%s'", port)
root = 0
log('waiting for server connection...')
comm = MPI.COMM_WORLD.Connect(port, info, root)
log('server connected...')
while True:
done = False
if rank == root:
try:
message = raw_input('pyeval>>> ')
if message == 'quit':
message = None
done = True
except EOFError:
message = None
done = True
comm.send(message, dest=0, tag=0)
else:
message = None
done = MPI.COMM_WORLD.bcast(done, root)
if done:
break
log('disconnecting server...')
comm.Disconnect()
and server.py:
#! /usr/bin/env python
from mpi4py import MPI
rank = MPI.COMM_WORLD.Get_rank()
def log(msg, *args):
if rank == 0:
print msg % args
log('')
info = MPI.INFO_NULL
port = MPI.Open_port(info)
log("opened port: '%s'", port)
service = 'pyeval'
MPI.Publish_name(service, info, port)
log("published service: '%s'", service)
MPI.COMM_WORLD.Spawn("./client.py", maxprocs=1)
root = 0
log('waiting for client connection...')
comm = MPI.COMM_WORLD.Accept(port, info, root)
log('client connected...')
while True:
done = False
if rank == root:
message = comm.recv(source=0, tag=0)
if message is None:
done = True
else:
try:
print 'eval(%r) -> %r' % (message, eval(message))
except StandardError:
print "invalid expression: %s" % message
done = MPI.COMM_WORLD.bcast(done, root)
if done:
break
log('disconnecting client...')
comm.Disconnect()
log('upublishing service...')
MPI.Unpublish_name(service, info, port)
log('closing port...')
MPI.Close_port(port)
But here you'll also have to deal with the fact that most MPI implementations will only give stdin to rank 0, so the clients don't have a nice way to get input from a terminal (in general, how would that work if there were multiple clients?)
Upvotes: 2