繁体   English   中英

Python中的多处理意外返回None

[英]Multiprocessing in Python returns None unexpectedly

我正在尝试在python 3.6(Anaconda发行版)中启动多处理。 我已经对我的内部函数(数值积分)进行了大量测试,因此我确信它有效。 目前给我带来麻烦的是传递适当的范围,因为我得到一些“无”回报。

import multiprocessing
from multiprocessing import Pool

def chunkwise(t, size=2):
    it = iter(t)
    return zip(*[it]*size)

def sint(tupl):
    print('arg = ',tupl)
    #lower = float(tupl[0])
    #upper = float(tupl[1])
    exit()
    #ans = scipy.integrate.quad(int2,lower,upper) 
    #return ans

n_CPUs = 6 

smin = float(10000)
smax = float(np.inf)
smax_spacing = float(2.5*10**12)
srange = np.linspace(smin,smax_spacing,n_CPUs)

srange = np.append(srange,np.inf)
print('length srange = ',len(srange))
filler=[]

for i in range(len(srange)):
    if i == 0:
        filler.append(float(srange[i]))
    elif srange[i] == srange[-1]:
        filler.append(float(srange[i]))
    else:
        filler.append(float(srange[i]))
        filler.append(float(srange[i]))
srange = np.array(filler)
srange = list(chunkwise(srange))

def main():
    pool = Pool(processes=n_CPUs)
    res1 = pool.map(sint,[(smin,float(smin*2)),  (float(smin*2),float(smin*3))])#srange)
    res = sum(res1)
    pool.close()
    pool.join()
    return res

if __name__ =="__main__":
    result = main()

我的一些调试过程可以在这里包含的代码中看到。 目前,我只想查看传递给我的sint()函数的参数。 当我打印结果时,我得到了结果

arg = (number,bigger number)
None
arg = (number2, bigger number2)
None

为什么这些“无”出现? 目前,它们的存在导致溢出/ NaN在代码的非并行化版本中不存在。 有没有办法让“无”出现? 我试图在tupl,lower和upper中检查是否存在“None”,但Python似乎不想识别这些(不会打印我写的“未检测到”消息)。

任何帮助将非常感谢! 如果需要更多信息,请与我们联系。

一个问题是多处理为您编写的所有内容启动一个单独的进程,它完全创建一个单独的Python实例,因此您的代码实际上运行了多次放入全局范围的所有内容。 运行代码将返回

>>> length srange =  7
>>> length srange =  7

多次为我。 您需要将其他代码移动到单独的函数中或者只是在def main()调用它。 然而,修复此问题仍会导致nones,这似乎是由于您实际上没有在映射函数中返回任何内容,即pool.map smin 通常你的结果将是None对象(并且sum也不能对无对象求和),但这里还有另一个问题。 您的流程实际上并未关闭。

这可能是因为你调用exit,没有返回或任何东西,甚至None

您不要调用exit来结束映射功能,请查看多处理以查看那里的示例。 只需使用普通函数作为映射器,无需使用系统调用。

即使这不是您想要的,这是一个简单的示例,用您的示例显示实际运行的多处理代码:

编辑:我没有意识到你发布的大部分内容都不是必需的,我鼓励你在发布问题时做出最小的可验证的例子,我已经缩小并改变了我发布的实际集成,我也鼓励你使用当你提出问题,并编写自己的代码正确的命名规则, sinttupl不exceptable描述性名称。 我在这里完成的工作向您展示了如何使用您提供的相同scipy集成实用程序在并行中正确执行集成。 您可以将integrated_function替换为您自己的函数的代码,它应该工作相同

from multiprocessing import Pool
from scipy import integrate


def integrated_function(x):
    return x ** 2


def integration_process(integration_range):
    print("thread launched, tuple = ", integration_range)
    lower = float(integration_range[0])
    upper = float(integration_range[1])
    y, err = integrate.quad(integrated_function, lower, upper)
    return y


def main():
    # notice how we put this inside this main function
    n_CPUs = 6
    total_integration_range = 60000
    integration_chunks = 6
    integration_step = total_integration_range / integration_chunks
    integration_ranges = [(i * integration_step, (i + 1) * integration_step) for i in range(integration_chunks)]
    pool = Pool(processes=n_CPUs)
    res1 = pool.map(integration_process, integration_ranges)  # srange)
    res = sum(res1)
    print(res)
    pool.close()
    pool.join()
    return res


if __name__ == "__main__":
    result = main()
    # thread launched, tuple = (0, 10000)
    # thread launched, tuple = (10000, 20000)
    # thread launched, tuple = (20000, 30000)
    # thread launched, tuple = (30000, 40000)
    # thread launched, tuple = (40000, 50000)
    # thread launched, tuple = (50000, 60000)
    # 72000000000000.0

如果你的功能足够复杂并且集成足够大,那么多处理的开销应该足够低以使其更快,请注意在线程中打印导致你不想要的减速,所以在调试之外我会鼓励你不打印。

编辑:由于他们想要进行无限集成,我还会在这里发布我对代码的想法和附录,而不是在评论中留下它。

从技术上讲,即使在无限积分范围内,你实际上并没有无限积分,无限积分近似积分的具体数值方法超出了这个问题的范围,但是因为scipy.ntegrate.quad是使用高斯积分来进行积分(因此名称' quad '),它修复了这个问题,可以将np.inf作为绑定。 不幸的是,我不知道如何保证与此绑定的连续性能,可能需要比其他所有集成更长的时间来完成,或者可能需要更少的时间,这意味着将工作分成相等的块变得更难。 但是,您只需要更改积分范围的最后一个边界,以包括该范围内的无穷大。

这种变化看起来像这样:

integration_ranges = [(i * integration_step, (i + 1) * integration_step) for i in range(integration_chunks)]
# we take the last element of the array, and all but the last element of the tuple, 
# and make a new tuple with np.inf as the last element
integration_ranges[-1] = integration_ranges[-1][:-1] + (np.inf,)

这样做之后,你的最后一个界限应该被无穷大限制,所以你的总积分范围实际上是0 - > inf,即使total_integration_range不是无穷大

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM