【问题标题】:Using fortran RANDOM_SEED in parallel MPI在并行 MPI 中使用 fortran RANDOM_SEED
【发布时间】:2017-01-16 13:41:59
【问题描述】:

我正在尝试在 MPI 代码中使用 fortran 内部 PRNG。

我从link 了解到,GFortran 使用 xorshift1024* 实现 PRNG,周期为 2^1024 - 1。它还说:

请注意,在多线程程序中(例如,使用 OpenMP 指令), 每个线程都有自己的随机数状态。

然后看了this我发现:

当一个新线程使用 RANDOM_NUMBER第一次,种子从master复制 种子,并转发 N * 2^512 步以保证随机 stream 不会为系统中的任何其他流添加别名,其中 N 是 到目前为止使用过 RANDOM_NUMBER 的线程数 程序执行

如果这是 GFortran 的自动功能,它只适用于 OpenMP?如果我想使用 MPI 进行并行 PRNG 怎么办?如何确保代码对其他编译器的可移植性?

换句话说:有什么方法可以使用 fortran 内在指令以可移植的方式执行 GFortran 所说的操作(即保证真正的并行 PRNG)?

注意:我在 MPI 中使用数字食谱的 PRNG。几年来效果很好,但现在我在整数模型的一些假设中遇到了一些错误,Numerical Recipes 所说的超出了 fortran ......所以我不知道如何解决这个问题,这就是我想要使用的方式如果可能的话,内在的 PRNG。

【问题讨论】:

  • 如果您关心跨编译器(甚至是编译器版本)的可移植性/一致性,那么random_number(和random_seed)将会出现很多问题。
  • 有没有什么方法可以按照 GFortran 所说的那样做……使用 fortran 内部指令以可移植的方式? 不,这 -- stackoverflow.com/questions/8920411/… -- 可能有用。
  • 感谢您的 cmets。如果内在函数不可移植并且数字食谱似乎也不可移植(根据我的经验)。您还建议哪些其他库、子例程或方法?

标签: random fortran mpi gfortran


【解决方案1】:

请注意,使用 xorshoft1024* 是 GFortran 中的一个非常新功能,它仅在开发主干版本中可用,在撰写本文时还没有发布版本。它将作为 GCC 7 的一部分发布,可能在 2017 年春季。

因此,当您使用 MPI 时,每个 MPI 等级都是一个单独的进程,每个进程中的随机数生成器是完全独立的,不同进程中的 PRNG 之间没有通信(当然,除非您自己使用 MPI 处理) .转发 PRNG 流 2^512 步的事情只有在同一进程中的多个线程使用 PRNG 时才会发生。

话虽如此,xorshift1024* 有一个相当长的周期 (2^1024-1),并且第一次在进程中使用 PRNG 时(再次考虑 MPI 等级),它使用来自操作系统的随机数据进行初始化 ( /dev/urandom 在 POSIX 系统上),除非它已经用 RANDOM_SEED 显式初始化。所以在实践中我认为你会没事的,不同 MPI 等级的 PRNG 流极不可能出现别名。

不,上面描述了 GFortran 版本 7 中的 PRNG。如果你想要一些可移植的东西,你不能依赖任何超出标准保证的东西。除了并行方面,对于可移植的高质量随机数,您可能最好使用已知良好的 PRNG,而不是依赖编译器提供的 PRNG(我有至少一个编译器产生劣质随机数的个人经验) RANDOM_NUMBER 内在的,但我会避免命名供应商,因为它是多年前的事情,他们可能已经修复了它,如果他们甚至不再营业,我不知道)。

(如果您发现新的 xorshift1024* 实现的语义很困难,请怪罪 a)我,因为我设计并实现了它 b)Fortran 标准使得不可能拥有具有简单语义的并行 PRNG)

【讨论】:

  • 非常感谢@janneb。你能推荐一个已知的好且可移植的 fortran PRNG 吗?
  • 嗯,我认为 xorshift1024* 是一个相当不错的选择。不过,参考实现是用 C 语言编写的,并且使用了在 Fortran 中难以模拟的无符号 64 位算法。我建议通过 ISO_C_BINDING 使用 C 实现。
【解决方案2】:

如果您想为 Fortran 程序提供多流随机数生成器的可移植版本,可以使用 Mersenne Twister 的多流 Fortran 版本。见http://theo.phys.sci.hiroshima-u.ac.jp/~ishikawa/PRNG/mt_stream_en.html。它使用了通过大量步骤为不同线程推进 PRNG 的概念。它是通过子程序调用设置和配置的,因此您应该能够在各种多线程环境中使用它。

【讨论】:

    猜你喜欢
    • 2018-05-05
    • 2020-04-17
    • 2013-09-11
    • 2015-04-14
    • 1970-01-01
    • 2016-12-06
    • 2016-12-30
    • 2018-11-05
    • 2014-12-31
    相关资源
    最近更新 更多