使用Mpi4py时OrderedDict失去其顺序

时间:2018-08-09 11:28:49

标签: python ordereddictionary mpi4py

我正在尝试使用Mpi4py打印字典:

from mpi4py import MPI

comm = MPI.COMM_WORLD
rank = comm.rank

if rank == 0:
    data = {'a':1,'b':2,'c':3}
else:
    data = None

data = comm.bcast(data, root=0)
print 'rank',rank,data

我立即使用以下命令为更多处理器运行它:

mpiexec -n 10 python code.py

结果与其他处理器结果混合在一起,如下所示:

rank 0 {'arank 2 {'a': 1, 'c': 3, 'b': 2}
rank' 3 {'a': 1, 'c': 3, 'b': 2}
: 1, 'c': 3, 'b': 2}
rank 8 {'a': 1, 'c': 3, 'b': 2}rank
 1 {'a': 1, 'c': 3, 'b': 2}
rank 4 {'a': 1, 'c': 3, 'b': 2}
rank 5 {'a': 1, 'c': 3, 'b': 2}
rank 9 {'a': 1, 'c': 3, 'b': 2}
rankrank  7 {'a': 1, 'c': 3, 'b': 2}
6 {'a': 1, 'c': 3, 'b': 2}

我认为发生这种情况是因为处理器在完成任务时会打印结果,从而导致混合匹配。我尝试使用OrderedDict,但那还是行不通。该代码为

from mpi4py import MPI
import collections 

comm = MPI.COMM_WORLD
rank = comm.rank

if rank == 0:
    data = collections.OrderedDict({'a':1,'b':2,'c':3})
else:
    data = None

data = comm.bcast(data, root=0)
print 'rank',rank,data

是否有一种方法可以使结果保持一致,并且不会与其他处理器的结果混淆?

2 个答案:

答案 0 :(得分:3)

我不确定它是否能解决混合输出的问题,但请声明

collections.OrderedDict({'a':1,'b':2,'c':3})

有2件事发生:

  1. 创建dict文字{'a':1,'b':2,'c':3}
  2. 将其传递到collections.OrderedDict,从而产生从原始dict文字继承而来的顺序的副本。

如果要保持插入顺序-传递键值对的有序迭代(如list)。

所以我们可以这样写

collections.OrderedDict([('a', 1), ('b', 2), ('c', 3)])

测试

>>> data = collections.OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> list(data.keys()) == ['a', 'b', 'c']
True

答案 1 :(得分:2)

请勿写入终端:多个进程的输出可能重叠。

相反,写入文件,为每个进程独立命名每个输出文件。

另外,考虑使用日志记录模块:它的目的正是为了记录信息。

类似的东西可以工作:

from mpi4py import MPI
import logging

comm = MPI.COMM_WORLD
rank = comm.rank

filename = 'output{}.log'.format(rank)
logger = logging.getLogger()
handler = logging.FileHandler(filename)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

if rank == 0:
    data = {'a':1,'b':2,'c':3}
else:
    data = None

data = comm.bcast(data, root=0)
logger.debug('rank = %d, %s', rank, data)

然后检查“ output0.log”,“ output1.log”等文件。

NB:使用dictOrderedDict与重叠输出无关。 dict将以随机(键)顺序打印输出,而按照您创建有序字典的方式,它将以随机顺序创建(请参阅Azat的回答和我在评论中提供的链接)。 br /> 它与写入同一输出源的多个进程有关,就像多个人都在同一个房间里说相同的话,只是彼此之间稍微不同步。


注意:如果使用C或C ++进行重叠没有问题,则可能是1 /运气,2 /底层代码执行输出,或3 / MPI / mpiexec执行某些标准输出。尝试为每个单独的进程使用更多的进程或更长的输出线,以查看它是否仍然有效。