проблема с питоном MPI (mpi4py), клиент не может подключиться - PullRequest
0 голосов
/ 30 мая 2011

Я получаю ошибку:

Traceback (последний вызов был последним): Файл "client2.py", строка 14, в port = MPI.Lookup_name (сервис, информация) Файл "Comm.pyx", строка 1676, в mpi4py.MPI.Lookup_name (src / mpi4py.MPI.c: 64562) mpi4py.MPI.Exception: MPI_ERR_NAME: неверный аргумент имени

Я пытаюсь реализовать модель клиент / сервер, используя mpi4py. Сервер может Publish_name и ждет клиентов. Однако клиент не может использовать необходимый метод, описанный в API, как показано ниже:

#! /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()

Я также публикую код сервера, так как это может помочь:

#! /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)

Ответы [ 2 ]

1 голос
/ 31 мая 2011

Мне нужно было использовать ompi-сервер для публикации имен и поиска имен. Следующие шаги для выполнения сервера и клиента работали для меня:

OMPI-сервер

rm -f /tmp/ompi-server.txt
killall ompi-server
ompi-server -r /tmp/ompi-server.txt

Сервер

mpiexec --ompi-server file:/tmp/ompi-server.txt -n 1 python server.py

клиент

mpiexec --ompi-server file:/tmp/ompi-server.txt -n 1 python client.py
1 голос
/ 30 мая 2011

Вы хотите, чтобы сервер порождал клиентов, чтобы они могли общаться.Кроме того, ваши Send / Recv / Bcasts должны быть send / recv / bcast;mpi4py поддерживает и Send, и Send, Recv и recv и т. д., но версии в верхнем регистре принимают «обычные» аргументы C / C ++ / Fortran, а строчные - более питонические.

Так что следующее успешно выполняется для меня- 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()

и 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)

Но здесь вам также придется иметь дело с тем фактом, что большинство реализаций MPI дают только stdin для ранга0, поэтому у клиентов нет хорошего способа получить информацию от терминала (в общем, как бы это работало, если бы было несколько клиентов?)

...