我必须使用具有数值积分(scipy.integrate.quad)的函数来评估矩阵的每个元素。矩阵的元素是5202x3465灰度图像的像素。
我可以使用GPU,并且希望并行评估尽可能多的元素,因为现在,使用线性编程,整个计算需要24个小时以上。
这是示例代码:
for i in range(0, rows):
for j in range(0, columns):
img[i, j] = myFun(constant_args, i, j)
def myFunc(constant_args, i, j):
new_pixel = quad(integrand, constant_args, i, j)
... other calculations ...
return new_pixel
我试图像这样使用多重处理(如mp):
arows = list(range(0, rows))
acolumns = list(range(0, columns))
with mp.Pool() as pool:
img = pool.map(myFunc, (constant_args, arows, acolumns))
或带有img = pool.map(myFunc(constant_args),(箭头,列))
却给了我
TypeError:myFunc()缺少2个必需的位置参数:“ j”和“ i”
我不理解其他示例中的工作原理,也不知道文档中使用的术语。
如果有人建议采用其他方法,我只想将嵌套循环划分为子线程。
ps。我尝试使用numba,但在与某些Scipy库进行交互时却给出了错误
提前感谢您的帮助!
答案 0 :(得分:0)
首先,错误在于您对public TR MeasureExecutionTime<T1, T2, T3, T4, T5, T6, TR>(this Func<T1, T2, T3, T4, T5, T6, TR> func, out long executionTime)
{
Stopwatch stopwatch = Stopwatch.StartNew();
TR tr = func();
stopwatch.Stop();
executionTime = stopwatch.ElapsedMilliseconds;
return tr;
}
...
var result = MeasureExecutionTime(() => obj.Process(p1, p2, p3, p4, p5, p6), out long executionTime);
-操作的调用。必须是:
map
但是,这可能不会导致您要查找的内容,因为它仅通过3个参数(必须为列表)运行。它不是通过它们的组合来运行的,尤其是arows = list(range(0, rows))
acolumns = list(range(0, columns))
with mp.Pool() as pool:
img = pool.map(myFunc, constant_args, arows, acolumns)
和arows
。例如,如果acolumns
具有3个元素,则constant_args
将在3次迭代后停止,而不会遍历较长的列表Pool.map
或arows
。
首先,您应该对行索引和列索引进行所有组合
acolumns
这会导致类似(所有可能的组合)
from itertools import product, repeat
comb = list(product(arows, acolumns))
接下来,我将这些组合与您的[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
constant_args
它产生一个元组列表,每个元组包含两个元素。第一个是您的像素位置,第二个是您的constant_args = [10, 11]
arguments = list(zip(comb , repeat(constant_args)))
constant_args
现在,我们必须对您的[((1, 1), [10, 11]),
((1, 2), [10, 11]),
((1, 3), [10, 11]),
((2, 1), [10, 11]),
((2, 2), [10, 11]),
((2, 3), [10, 11]),
((3, 1), [10, 11]),
((3, 2), [10, 11]),
((3, 3), [10, 11])]
进行一些修改:
myFunc
最后,我们使用Pool.starmap发挥作用(参见此处:starmap usage):
def myFunc(pix_id, constant_args):
new_pixel = quad(integrand, constant_args, pix_id[0], pix_id[1])
... other calculations ...
return new_pixel
发生的情况是,with mp.Pool() as pool:
img = pool.starmap(myFunc, arguments )
接受一个元组列表,并将其提供为函数的输入。但是,starmap
会自动将元组列表解压缩为单个参数以供您使用。第一个参数是由两个元素组成的starmap
,第二个参数是pix_id
。
答案 1 :(得分:0)
您可以使用quadpy(我的项目之一)。它会执行 vectorized 计算,因此运行速度非常快。 输出形状为2x2的示例:
import quadpy
def f(x):
return [[x ** 2, x**3], [x**4, x**5]]
scheme = quadpy.line_segment.gauss_legendre(5)
val = scheme.integrate(f, [0, 1])
print(val)
[[0.33333333 0.25 ]
[0.2 0.16666667]]
f
的输出必须为(..., x.shape)
形状,并且...
可以是任何元组,例如(5202, 3465)
。