通过发送功能进行Bradcasting并通过recv接收来自不同来源的消息

时间:2016-01-19 17:43:57

标签: python python-3.x mpi mpi4py

我尝试编写主/从程序,其中root comp将数据发送到包含自身的3个comp,并在从此comps接收计算数据之后。它发送但无法接收数据。

if rank==0:
    for i in range(minf.astype(int), ped.max_frame.astype(int), step):
        # remove code which is not significant
        while True:
            # remove code which is not significant        
            pop = pool
            # remove code which is not significant
            logger.info('broadcasting gen%s:' % current_gen)

            n_to_send = len(pop)//3
            req = comm.irecv(source=0)
            for i in range(2):
                out = []
                j =0
                while j < n_to_send and pop:
                    out.append(pop.pop(0))
                    j+=1 
                logger.info('out%s: %s' % (i, len(out)))
                comm.send(out, dest=i)

            logger.info('out%s: %s' % (2, len(pop)))
            comm.send(pop, dest=2) 

            part = req.wait()
            obj(part)                
            logger.info("len part1: ", len(part))
            # comm.Barrier()
            #req1 = comm.irecv(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG)
            #part1 = req1.wait()
            part1 = comm.recv(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG)

            logger.info("len part2: ", len(part1))
            # req2 = comm.irecv(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG)
            # part2 = req2.wait()
            part2 = comm.recv(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG)
            logger.info("len part3: ", len(part2))

            # MPI.Request.Waitall([req1, req2])

            pop = part + part1 + part2                
            # logger.info('population len%s: %s' % (len(pop), '\n'.join(pop)))                
            logger.info('population len %s: ' % len(pop))
            message = '{0}'.format([ind.objectives for ind in pop])
            logger.info(message)
else:        
    part = comm.recv(source=0)
    obj(part)
    comm.send(part, dest=0, tag=rank+1)
    # req = comm.isend(part, dest=0, tag=666)
    # req.wait()

我在非root comps中尝试isend。我不知道root为什么不接收消息。

1 个答案:

答案 0 :(得分:2)

我解决了这个问题。我只是忘了在slave进程中添加一个循环。我在下面附上了一个同步主从程序的例子。我希望它有所帮助。

import os
import sys
from mpi4py import MPI
import logging
import random

def getScriptPath():
    return os.path.dirname(os.path.realpath(sys.argv[0]))

if __name__ == '__main__':
    comm = MPI.COMM_WORLD
    rank = MPI.COMM_WORLD.Get_rank()
    size = MPI.COMM_WORLD.Get_size()
    name = MPI.Get_processor_name()
    logging.basicConfig(filename=getScriptPath() + "\\log_filename.log", level=logging.DEBUG,
                            format='%(asctime)s - %(levelname)s - %(message)s')
    logger = logging.getLogger()
    work = True
    if rank == 0:
        for i in range(3):
            for j in range(1, size):
                req = comm.isend(work, dest=j, tag=j+1)
                req.wait()

            data = [random.random() for i in range(100)]
            ndata = len(data)//size

            logger.info("Loop i=%s" % i)
            req = comm.irecv(source=0)
            for j in range(size-1):
                to_send = []
                t = 0
                while t < ndata:
                    to_send.append(data.pop(0))
                    t += 1
                comm.isend(to_send, dest=j, tag=j+1)

            comm.issend(data, dest=size-1)

            # recieve block
            d = req.wait()
            logger.info("i=%s, j=%s: %s" % (i, rank, d))
            requests = []
            for j in range(1, size):
                # d = comm.recv(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG, status=None)
                req = comm.irecv(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG)
                d = req.wait()
                logger.info("i=%s, j=%s: %s" % (i, j, d))

        work = False
        for j in range(1, size):
            req = comm.isend(work, dest=j, tag=j+1)
            req.wait()

        MPI.Finalize()

    else:
        while True:
            have_job = comm.recv(source=0)
            if have_job == False:
                break

            data = comm.recv(source=0)

            for i in range(len(data)):
                data[i] = rank
            comm.isend(data, dest=0, tag=rank+1)
            print("Data was sent from %s" % rank)
            logger.info("Data was sent from %s: /n %s" % (rank, data))