我有一个 Python 脚本,最初由来自 Intel OneAPI 的 python3.7 执行。
此脚本使用“
multiprocessing
”库。
我已经从Intel的python3.7升级到Intel的python3.9。
代码无法正常执行,由于python3.7和python3.9之间的转换而出现错误。
我可以通过在顶部添加
mp.set_start_method("fork")
来找到 python3.9 的解决方法:
import multiprocessing as mp
mp.set_start_method("fork")
但是python3.7和python3.9之间的代码结果存在显着差异(数值差异约为20%):正常吗?
有没有办法在两个版本之间获得相同的结果?
我认为问题来自“
multiprocessing
”,但我不知道如何用python3.9处理它。
这是使用 python3.7 的
multiprocessing
包的代码片段部分示例:
#Modules import.
import sys
import numpy as np
import scipy.integrate as pyint
import os
from os import path
import glob
from scipy.interpolate import CubicSpline
import multiprocessing as mp
mp.set_start_method("fork")
from multiprocessing import Pool
def integ(I1):
#The Pobs(k,mu) is duplicated and rolled on the right, lower and right-lower directions to sum each elements
function_A = aux_fun_LU(way, ecs, I1[0], I1[1])*delta_x*delta_y
function_A_10 = np.roll(function_A, -1, axis = 1)
function_A_01 = np.roll(function_A, -1, axis = 0)
function_A_11 = np.roll(function_A_01, -1, axis = 1)
function_A = function_A[0:-1, 0:-1]
function_A_10 = function_A_10[0:-1, 0:-1]
function_A_01 = function_A_01[0:-1, 0:-1]
function_A_11 = function_A_11[0:-1, 0:-1]
#Integral computation.
integrale_A = np.sum(function_A + function_A_10 + function_A_01 + function_A_11)/4
#The integral is saved into the temporar files.
file=open('tmp_F/LU_table_NL.txt','a')
file.write(str(I1[0]%N_notRD_params) + ' ' + str(I1[1]%N_notRD_params) + ' ' + str("%.12e" % integrale_A))
file.write(str('\n'))
return integrale_A
#Function that yields over two index (equivalent to double for loop) for parallel computing.
def g():
for j in range(N_notRD_params*i, N_notRD_params*i+N_notRD_params):
for l in range(j, N_notRD_params*i+N_notRD_params):
yield j, l
#Pool map function for parallel computing.
if __name__ == '__main__':
pool = mp.Pool(12)
pool.map(integ, g())
pool.terminate()
这就是为什么我必须添加 python3.9 的导入头:
import multiprocessing as mp
mp.set_start_method("fork")
from multiprocessing import Pool
但是这个版本的 python3.9 结果非常糟糕。我得到的最终结果数值有 20% 的差异。
有没有办法获得与 python3.7 相同的结果?
这更像是一条评论,而不是一个答案,但它太长了,不适合作为评论。
#1) 在函数
integ
中,我注意到您使用了 way
、ecs
、delta_x
和 delta_y
而没有对它们进行初始化。这些在哪里初始化?你能验证它们两次的值是否相同吗?
#2)这不是你的问题,但你写入文件的方式非常糟糕,并且可能会导致竞争条件。让每个线程都尝试写入一个公共文件是一个坏主意。更好的选择是删除
integ
中的写入,只保留它 return integrale_A, I1
然后你可以写:
with open('......', 'w') as file:
pool = mp.Pool(12)
for integral_A, I1 in pool.map(.....):
file.write(......);
pool.terminate()