OrderedDict在使用Mpi4py时会丢失其序列

2024-05-16 20:52:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用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

有没有办法让结果保持一致,而不是和其他处理器的结果混在一起?你知道吗


Tags: fromimportnoneworlddataifmpi4pyroot
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”等文件。你知道吗

注意:使用dictOrderedDict与重叠输出无关。dict将以随机(键)顺序打印其输出,而按照您创建有序词典的方式,它将以随机顺序创建(请参阅Azat的答案和我在注释中提供的链接)。
这与多个进程向同一输出源写入数据有关,就像多个人在同一个房间里说同一件事,只是彼此稍微不同步。你知道吗


注意:如果你没有重叠的问题,使用C或C++,这可能是1 /运气,2 /不同的代码下的引擎盖做输出,或3 /MPI/MPIExcel做一些花哨的STDUT处理。尝试为每个进程使用更多的进程或(更长)的输出行,看看它是否仍然有效。你知道吗

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

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

有两种情况发生:

  1. 创建dict文字{'a':1,'b':2,'c':3}。你知道吗
  2. 将其传递给collections.OrderedDict,结果是以继承自原始dict文本的顺序生成副本。你知道吗

如果要保持插入顺序,请传递键-值对的iterable(如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

相关问题 更多 >