用于在 MacOS 上复制随机数的 Python 3.8 多处理

Posted

技术标签:

【中文标题】用于在 MacOS 上复制随机数的 Python 3.8 多处理【英文标题】:Python 3.8 multiprocessing for copying the random on MacOS 【发布时间】:2021-06-13 05:55:36 【问题描述】:
from multiprocessing import Pool, cpu_count
import numpy as np
from numpy.random import multivariate_normal

F = multivariate_normal(np.zeros(3), np.eye(3), (3, 5))

def test(k):
    print(k)
    res = np.zeros((5, 3))
    for i in range(3):
        res[:, i] = F[k, :, i]
        #print(res[:, i])
    return res


if __name__ == '__main__':
    with Pool(cpu_count()) as pool:
        result = pool.map(test, range(3))
    pool.close()
    pool.join()
    result = np.array(results)

在python3.6中,结果等于随机矩阵F。但是在python 3.8中它们的两个矩阵是不同的。这只是一个例子。在实际代码中,我想在每个时间步中取出F的每一列,并对其进行一些操作。

【问题讨论】:

【参考方案1】:

心理调试:您在 Windows(任何 Python 版本)或 macOS(Python 3.8 或更高版本)上运行,两者都默认使用 'spawn' 创建工作进程的方法,而不是 'fork'。当这种情况发生时,__main__ 模块会在子进程中导入(使用不同的名称,因此它不会再次尝试运行主代码)以模拟fork

这主要是可行的,但在自播 PRNG 的情况下会失败,因为它们在子进程中重新播种,并且全局是从新的 PRNG 重新生成的,而不是让子进程继承它们生成的值。

简而言之,完成这项工作的方法是:

    使用'fork' 作为multiprocessing 启动方法运行它(在Windows 上不可能,在macOS 上技术上允许,但可能会中断,这就是他们将默认设置更改为'spawn' 的原因)。我在 Linux 上测试了你的代码(默认是 forks),除了修正错字(你在一个应该是 result 的地方输入了 results)之外,resultF 是那里也一样。当我在创建 Pool 之前添加 multiprocessing.set_start_method('spawn') 时,它们不匹配。 将初始化函数和参数显式传递给 Pool,以便每个工作人员将 F 重置为在父项中看到的值 在生成 F 之前使用显式种子,因此无论过程如何,它都是一致的(缺点:每次运行都会相同,或者至少,非常可预测,具体取决于您尝试的聪明程度得到)

请注意,#2 和#3 可以结合使用以最小化数据流。在父节点中生成一个“真正的”随机种子(例如使用os.urandom)并编写一个简单的函数来接受种子并使用它来播种PRNG并生成F(使用global F让它改变全局价值)。在父函数中调用该函数,并将其作为带有种子参数的初始化程序传递给每个子函数。现在,不用传递F(可能很大)的生成值,只需要传递种子,子进程就可以在本地重现F,而无需序列化整个事情。缺点:所有进程共享相同的随机种子;它不像硬编码的种子那样可预测,但父母和孩子会从一组相同的随机数中抽取。

【讨论】:

另一方面,在每个工作进程中使用相同的 RNG 种子通常是个好主意。在每个过程中使用相同的 RNG 种子会导致虚假的相关性,从而破坏您的数据。 (我认为继承RNG种子的工人是multiprocessing的一大设计缺陷。) @user2357112supportsMonica:是的,理想情况下,每个进程的种子都不同,但F 是相同的(因为它在逻辑上是相同的值)。选项 #2 会得到这个结果。 这也适用于 3.6,因为“spawn”仅在 3.8 及更高版本的 MacOS 上更改为默认值。 3.6 默认使用“fork” @Aaron:是的,当我回答时,OP 没有提到测试版本 3.6 或有问题的操作系统。本来可以使答案变得不那么通灵,要么被指定。 :-)

以上是关于用于在 MacOS 上复制随机数的 Python 3.8 多处理的主要内容,如果未能解决你的问题,请参考以下文章

如何在MacOS的VScode上安装Python3

MacOS 上的 Python 3.6 和 MySQL 8.0.21:如何给表 camelCase 列名? [复制]

Ujson 适用于 MacOS,但不适用于 Ubuntu

mac数据迁移python库还在吗

我应该如何在 macOS 上设置 JAVA_HOME 环境变量? [复制]

在 MacOS Mojave 上为 QGIS 安装 Python 3.6