【问题标题】:OrderedDict loses its sequence while using Mpi4pyOrderedDict 在使用 Mpi4py 时丢失了它的序列
【发布时间】:2019-01-16 20:20:13
【问题描述】:

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

有没有办法让结果保持一致而不与其他处理器的结果混在一起?

【问题讨论】:

  • 我想我在帖子中明确提到过,“结果与其他处理器结果混合在一起,如下所示”
  • 您分享的 stackoverflow 链接对我的问题没有帮助。在上面的代码中,当我使用 pyhton MPI 库运行时。它在多个处理器中运行相同的代码,如果 N 个处理器正在运行,那么它会打印 N 次结果。所以当我展示结果时,你可以很清楚地看到,0 级词典与 1 级词典混合在一起,等等。这是我唯一的问题。我希望 0 级字典不与 1 级字典混合。谢谢!
  • 在后面的代码中,我正在处理器之间交换字典数据,我想看看我正在编写的 MPI 代码在逻辑上是否正确。为此,我希望打印结果。我想指出,在使用 C/C++ 编程语言进行 MPI 时我没有遇到这样的问题。因此,对于 python,我试图找到一种方法来避免在打印时散布数据。非常感谢!

标签: python ordereddictionary mpi4py


【解决方案1】:

不要写入终端:多个进程的输出可能会重叠。

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

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

这样的东西可以工作:

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/mpiexec 执行一些花哨的标准输出处理。尝试为每个单独的进程添加更多进程或(更多)更长的输出行,看看它是否仍然有效。

【讨论】:

    【解决方案2】:

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

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

    发生了两件事:

    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
    

    【讨论】:

    • 抱歉,没用。因此,您可以从代码中看到我试图在多个处理器中运行它。并从多个处理器打印相同的结果。结果(数据字典)正在重叠。我正在寻找一种不重叠的方法。如果有什么可以帮助我按顺序从处理器获取结果,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多