【问题标题】:gfortran how do I increment random_seed by 2^128gfortran 如何将 random_seed 增加 2^128
【发布时间】:2021-01-11 14:49:27
【问题描述】:

gfortran page on random_seed 表示当使用 OMP 线程时,每个线程将其种子增加 2^128。我想知道如何手动将种子增加 2^128。我写了一个小测试程序将主种子设置为0,然后看看种子是什么,但我不明白我看到的是什么。我想知道的是例如我在子程序increment_by_2_tothe_128中放入的内容@

program main
  implicit none

  character(len=32)    :: arg
  integer              :: n
  integer              :: i
  integer              :: nthreads
  integer, allocatable :: seed(:, :)
  integer, allocatable :: master_seed(:)
  real,    allocatable :: rn(:)

  call get_command_argument(1, arg)
  read(arg, *) nthreads

  call random_seed(size=n)
  allocate(seed(n, nthreads))
  allocate(master_seed(n))
  allocate(rn(nthreads))
  master_seed = 0
  seed = 0
  call random_seed(put=master_seed)

  ! call increment_by_2_tothe_128(n)

  call omp_set_num_threads(nthreads)

  !$OMP PARALLEL DO
  do i=1,nthreads
     call random_number(rn(i))
     call random_seed(get=seed(:,i))
  end do

  do i=1,nthreads
     print *, i
     print *, rn(i)
     print *, seed(:,i)
  end do

end program main


subroutine increment_by_2_tothe_128(n)
  implicit none
  integer, intent(in) :: n
  integer             :: current_seed(n)
  integer             :: increment_seed(n)
  call random_seed(get=current_seed)
  ! what goes here:
  ! incrememt_seed = current_seed + 2**128
  call random_seed(put=increment_seed)
end subroutine increment_by_2_tothe_128

【问题讨论】:

  • 增量不是“将 2^128 添加到种子”而是“表现得好像已经生成了 2^128 个偏差”。那是你缺少的部分吗? (无论如何,这不是答案,因为“调用 random_number 2*128 次”并不合适。)

标签: fortran gfortran random-seed


【解决方案1】:

您无法手动执行此操作。您需要访问随机数生成器才能做到这一点,但内部不会暴露给 Fortran 程序员。而且你显然不能调用生成器 2^128 次。

如果您需要进行移位,则需要使用一些伪随机数生成器,该生成器确实会暴露内部结构并且同时允许这种移位。例如,可以是 gfortran 内部使用的xoroshiro PRNG family。这些生成器针对这种转变具有专门的功能:

所有基于线性递归的生成器都提供跳转 使模拟任意数量的调用成为可能的函数 常数时间内的下一个状态函数,一次合适的跳跃多项式 已计算。我们为一个号码提供现成的跳转功能 调用次数等于周期的平方根,以使其更容易 为并行计算生成非重叠序列,以及 等于周期的第四根的立方,使其 可以在不同的并行上生成独立的序列 处理器。

这些生成器最常在 C 中实现,但 Fortran 实现 also existsubroutine rng_jump 是跳转函数,免责声明:链接指向我的存储库,不保证质量)。

【讨论】:

  • 另外,这里是 Mersenne Twister 的一个版本,它(大部分)在 Fortran 中实现,并为程序员提供了跳转随机数以提供多个流的能力:theo.phys.sci.hiroshima-u.ac.jp/~ishikawa/PRNG/…。跨度>
  • 非常感谢。与此同时,我不好的解决方案是记录我在 OMP 并行 DO 循环中获得的种子并将它们保存到一个文件中,然后稍后读取它们并根据我正在处理的块的索引来引用它们。我不是特别喜欢这个想法,但它现在属于作品类别,无需更改我不熟悉的代码
猜你喜欢
  • 2015-10-30
  • 2010-11-06
  • 2014-12-10
  • 1970-01-01
  • 2021-07-16
  • 2019-11-15
  • 1970-01-01
  • 2011-10-22
  • 2023-03-23
相关资源
最近更新 更多