python3.7 和 python3.9 之间的 python 代码结果存在显着差异

问题描述 投票:0回答:1

我有一个 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 相同的结果?

python python-3.x fork python-multiprocessing python-multithreading
1个回答
0
投票

这更像是一条评论,而不是一个答案,但它太长了,不适合作为评论。

#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()
© www.soinside.com 2019 - 2024. All rights reserved.