zaz*_*oma 6 numpy python-3.x concurrent.futures
我正在尝试使用多处理来填充大型numpy数组。我已经阅读了文档中的并发期货示例,但是对修改用法的理解还不够。
这是我想做的事情的简化版本:
import numpy
import concurrent.futures
squares = numpy.empty((20, 2))
def make_square(i, squares):
print('iteration', i)
squares[i, 0], squares[i, 1] = i, i ** 2
with concurrent.futures.ProcessPoolExecutor(2) as executor:
for i in range(20):
executor.submit(make_square, i, squares)
Run Code Online (Sandbox Code Playgroud)
输出运行类似:
iteration 1
iteration 0
iteration 2
iteration 3
iteration 5
iteration 4
iteration 6
iteration 7
iteration 8
iteration 9
iteration 10
iteration 11
iteration 12
iteration 13
iteration 15
iteration 14
iteration 16
iteration 17
iteration 18
iteration 19
Run Code Online (Sandbox Code Playgroud)
很好地证明了该功能正在同时运行。但是squares数组仍然为空。
填充squares数组的正确语法是什么?
其次,使用.map会更好吗?
提前致谢!
17年8月2日哇。因此,我进入了Reddit领域,因为我没有任何人接受这个问题。很高兴回到这里在stackoverflow。感谢@ilia w495 nikitin和@donkopotamus。这是我在reddit中发布的内容,它更详细地说明了此问题的背景。
The posted code is an analogy of what I'm trying to do, which is populating
a numpy array with a relatively simple calculation (dot product) involving
two other arrays. The algorithm depends on a value N which can be anything
from 1 on up, though we won't likely use a value larger than 24.
I'm currently running the algorithm on a distributed computing system and
the N = 20 versions take longer than 10 days to complete. I'm using dozens
of cores to obtain the required memory, but gaining none of the benefits of
multiple CPUs. I've rewritten the code using numba which makes lower N
variants superfast on my own laptop which can't handle the memory
requirements for larger Ns, but alas, our distributed computing environment
is not currently able to install numba. So I'm attempting concurrent.futures
to take advantage of the multiple CPUs in our computing environment in the
hopes of speeding things up.
Run Code Online (Sandbox Code Playgroud)
因此,计算不是时间密集型,而是1600万次以上的迭代。初始化后的数组为N x 2 ** N,即上述代码中的range(16777216)。
可能根本不可能通过多处理来填充数组。
这里的问题是 a将在单独的ProcessPoolExecutor进程中执行一个函数。
由于这些是单独的进程,具有单独的内存空间,因此您不能指望它们对数组 ( squares) 所做的任何更改都会反映在父进程中。因此你的原始数组没有改变(正如你所发现的)。
您需要执行以下任一操作:
ThreadPoolExecutor,但要注意,在一般情况下,您仍然不应该尝试在多个线程内修改全局变量;后者看起来像这样:
squares = numpy.zeros((20, 2))
def make_square(i):
print('iteration', i)
# compute expensive data here ...
# return row number and the computed data
return i, ([i, i**2])
with concurrent.futures.ProcessPoolExecutor(2) as executor:
for row, result in executor.map(make_square, range(20)):
squares[row] = result
Run Code Online (Sandbox Code Playgroud)
这将产生您期望的结果:
[[ 0. 0.]
[ 1. 1.]
[ 2. 4.]
...
[ 18. 324.]
[ 19. 361.]]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1448 次 |
| 最近记录: |