【问题标题】:**kwargs not working in mpi4py MPIPoolExecutor**kwargs 在 mpi4py MPIPoolExecutor 中不起作用
【发布时间】:2018-08-13 21:47:45
【问题描述】:

mpi4py 文档声称您可以通过 MPIPoolExecutor 传递 **kwargs,但我无法让它工作。我执行以下代码:

import time
import socket
import numpy as np
from mpi4py.futures import MPIPoolExecutor
from mpi4py import MPI


def print_val(x, kwargsstr):
    time.sleep(1)
    msg = "x value: " + str(x) + \
        ", socket: " + str(socket.gethostname()) + \
        ", rank: " + str(MPI.COMM_WORLD.Get_rank()) + \
        ", time: " + str(np.round(time.time(), 1)) + \
        ", kwargs string: " + kwargsstr
    print(msg)

    return x


def main():

    kwarg = 'test'
    kwargs = {'kwargsstr':kwarg}

    with MPIPoolExecutor() as executor:
        x_v = []
        # for res in executor.map(print_val,
        #                         range(9), 9*[kwarg]):
        for res in executor.map(print_val,
                                range(9), **kwargs):
            x_v += [res]
        print(x_v)


if __name__ == '__main__':

    """
    run on command line with 1 scheduler and 2 workers:
    $ mpiexec -n 1 -usize 3 -machinefile hostfile.txt python mpi4py_kwargs.py
    """

    main()

通过这个命令:

$ mpiexec -n 1 -usize 3 -machinefile hostfile.txt python mpi4py_kwargs.py

并收到此错误消息:

TypeError: print_val() missing 1 required positional argument: 'kwargsstr'

请注意,当 main 中的注释掉部分切换时,代码会按预期运行。

【问题讨论】:

  • kwargs = {'kwargstr':kwarg} 是不是应该写成 kwargs = {'kwargsstr':kwarg} 的错字?
  • 你是对的,这是一个错字。我纠正了这个但得到了同样的错误。我将编辑问题。
  • 看源码,觉得不支持kwargs。但是你无论如何都不会在print_val 中处理 kwargs。那么zip(range(9), [kwarg] * 9) 作为第二个参数,executor.map 没有 **kwargs 怎么样?
  • 啊,真令人失望。不幸的是,我实际应用程序中的函数还有很多参数。 executor.map(print_val, range(9), 9*[kwarg]) 在这个例子中完成了这项工作。

标签: python-3.x keyword-argument mpi4py


【解决方案1】:

我不认为 map 支持 kwargs。一起来看看source code

map 确实在其签名中使用了kwargs

def map(self, fn, *iterables, **kwargs):

这是关于 kwargs 参数的文档所说的:

Keyword Args:
  unordered: If ``True``, yield results out-of-order, as completed.

关键字参数(不包括unordered)是否会传递给可调用对象并不明显。我们继续。实现是使用:

iterable = getattr(itertools, 'izip', zip)(*iterables)
return self.starmap(fn, iterable, **kwargs)

因此,kwargs 被转发到starmap

def starmap(self, fn, iterable, timeout=None, chunksize=1, **kwargs):

使用相同的文档

Keyword Args:
  unordered: If ``True``, yield results out-of-order, as completed.

实现如下:

unordered = kwargs.pop('unordered', False)
if chunksize < 1:
    raise ValueError("chunksize must be >= 1.")
if chunksize == 1:
    return _starmap_helper(self.submit, fn, iterable,
                           timeout, unordered)
else:
    return _starmap_chunks(self.submit, fn, iterable,
                           timeout, unordered, chunksize)

显然,一旦unordered 被检索到,kwargs 将不再被使用。因此,map 不会将 kwargs 视为可调用的 kwarg。

正如我在评论中指出的那样,对于这个特定示例,您可以将参数提供为非关键字参数,但也可以提供位置参数:

for res in executor.map(print_val, range(9), [kwarg] * 9):

map 的第二个参数记录为:

iterables: Iterables yielding positional arguments to be passed to
           the callable.

对于 Python 新手:

>>> kwarg = 'test'
>>> [kwarg] * 9
['test', 'test', 'test', 'test', 'test', 'test', 'test', 'test', 'test']

其中[kwarg] * 9 是一个实现可迭代协议的列表。

【讨论】:

    猜你喜欢
    • 2018-10-02
    • 2023-03-13
    • 1970-01-01
    • 2016-07-26
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多