从分子动力学代码中去除非确定性

计算科学 并行计算 模拟 高性能计算 分子动力学
2021-12-24 13:15:06

我一直在寻找其他答案,但我还没有找到一个好的答案。我将描述我正在运行的模拟,然后是问题。该程序模拟经历布朗动态运动(热运动)与随机过程(动力学蒙特卡罗)交替的粒子。当我转向 OpenMP 代码时,我(最终)获得了性能,但我失去了系统中的确定性。因此,我有两个问题。

  1. 我只能使用单线程版本重复相同的“实验”两次。否则,线程对粒子的操作顺序会破坏任何确定性。
  2. 分析 OpenMP 代码作为线程函数或与串行版本的运行速度相比,需要在每个点运行 10 倍模拟程序,因为我测试了特定的结束配置,并且程序的速度对配置非常敏感粒子。基本上,粒子越接近,运行所需的时间就越长,因此不同的结束配置可能需要截然不同的时间。

我知道这是在 MD 中发现的一个正常问题,但我正在查看是否有任何解决方法,而不是运行单线程版本。如果是这样的话,那就这样吧,我只是希望有其他的东西,以便我可以优化 OpenMP 代码和环境变量。

4个回答

DE Shaw Research 的标准集群和定制超级计算机 (Anton) 版本的分子动力学都是确定性和并行不变的。也就是说,在单个内核上运行的测试生成与大规模并行运行相同的位。这些技术包括

  1. 整数求和:虽然每个力项都是以浮点数计算的,但每个原子上的总力是以定点数求和的。因此,这些和是可交换的和关联的,因此在不失去确定性的情况下并行化是微不足道的。所有状态(位置和动量)也保持在固定点。

  2. 使用计数器模式技术生成任何所需的随机数,如http://www.thesalmons.org/john/random123/papers/random123sc11.pdf中所述。计数器模式生成器相当于加密整数序列 0、1、2、使用足够强大的密码。有关详细信息,请参阅论文。

我相信在随机 MD 模拟中几乎不可能获得二元再现性(或“确定性”)。这样的模拟基本上是混乱的——即使在两次模拟运行中任何变量(例如任何粒子位置)的最低有效位不同时,轨迹也会在一段时间后发散。

这种错误的一个典型来源是主 MD 循环中力的总和顺序:当您以不同的顺序对力求和时,这可能已经导致总和的最低有效位的差异。要获得完整的确定性,您必须确保始终以相同的顺序汇总力量。

不幸的是,几乎不可能确保求和的顺序。当编译器优化代码时,它做的第一件事就是改变顺序。这意味着当您使用不同的编译器(甚至可能是同一编译器的不同版本,或不同的优化级别)编译相同的代码时,您不能期望结果在二进制级别上是相同的。此外,一些现代架构甚至在硬件级别上进行指令重新排序,或者它们提供更快的指令,其中最低有效位未确定。因此,即使您在同一台机器上执行相同的二进制文件,也不一定保证两次运行都会产生相同的结果。当您以任何有效的方式并行化代码时,甚至会增强此问题,因为这肯定会修改求和顺序。

请注意,这意味着即使您设法编写了一个在您的机器上创建二进制可重现结果的程序,您也不能指望其他人能够重现您的结果,除非他拥有与您的编译器相同的版本,与您的相同版本的编译器。操作系统和相同的硬件。

因此,我不得不说,对于 MD,我们根本无法获得二元再现性。另一方面,MD的结果通常是统计平均值。因此,我们在进行 MD 模拟时应该瞄准的是统计再现性,而不是二元再现性。

你知道不确定性究竟来自哪里吗?我不做MD,但我可以想到两种情况:

  • 粒子更新(时间步进)使用最新可用的粒子数据,因此另一个 OpenMP 线程可能已经更新了串行版本中未更新的粒子。解决这个问题需要所有线程仅根据前一个时间步的值进行更新。(我认为无论如何都需要这样做以保持时间准确性。)

  • 您提到了“随机过程”。你如何播种这里使用的随机数生成器?如果您强制所有线程使用相同的种子,则应该从 RNG 中删除任何非确定性。

您需要确保每次粒子更新都使用相同的随机数,无论您是在多个线程之一上运行。作为一种极端情况,假设您有一个与每个粒子相关联的 RNG。然后,当你做n粒子的第一次更新m, 你会得到n来自 RNG 的随机数m,无论您在哪个线程上执行此更新。

这可能有点极端,但您可以有一个 RNG,例如 1000 个粒子,并且每个线程一次只能使用关联的 RNG 更新 1000 个粒子的块。同样,这种方式没有区别哪个线程进行更新,因为它确定性地绘制随机数。