**kwargs 在 mpi4py MPIPoolExecutor 中不起作用
**kwargs not working in mpi4py MPIPoolExecutor
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 中注释掉的部分时,代码会按预期运行。
我认为 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
视为可调用的 kwargs。
正如我在评论中指出的那样,对于这个特定示例,您可以将参数作为非关键字参数提供,但也可以作为位置参数提供:
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
是实现可迭代协议的列表。
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 中注释掉的部分时,代码会按预期运行。
我认为 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
视为可调用的 kwargs。
正如我在评论中指出的那样,对于这个特定示例,您可以将参数作为非关键字参数提供,但也可以作为位置参数提供:
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
是实现可迭代协议的列表。