【问题标题】:Fix arithmetic error in distributed version修复分布式版本中的算术错误
【发布时间】:2015-11-11 12:31:32
【问题描述】:

我在分布式环境中通过 Cholesky 分解来反转矩阵,正如 here 所讨论的那样。我的代码工作正常,但为了测试我的分布式项目是否产生正确的结果,我不得不将它与串行版本进行比较。结果不完全一样!

例如,结果矩阵的最后五个单元格是:

serial gives:
-250207683.634793 -1353198687.861288 2816966067.598196 -144344843844.616425 323890119928.788757
distributed gives:
-250207683.634692 -1353198687.861386 2816966067.598891 -144344843844.617096 323890119928.788757

我曾在Intel forum 中发布过关于该问题的帖子,但我得到的答案是关于在我将使用分布式版本进行的所有执行中获得相同的结果,这是我已经拥有的东西。他们似乎(在另一个线程中)无法对此做出回应:

如何在串行执行和分布式执行之间获得相同的结果?这可能吗?这将导致修正算术错误。

我尝试设置:mkl_cbwr_set(MKL_CBWR_AVX); 并使用mkl_malloc(),以对齐内存,但没有任何改变。我会得到相同的结果,只是在我将为分布式版本生成一个进程的情况下(这将使其几乎是串行的)!

我正在调用的分布式例程:pdpotrf()pdpotri()

我正在调用的串行例程:dpotrf()dpotri()

【问题讨论】:

  • 每次运行串行版本时是否得到相同的结果,或者串行运行之间的结果是否存在微小差异?
  • 抱歉添加了多个连续的cmets;我做了一些更多的研究,这是 HPC 和分布式计算中的一个常见问题,许多大问题和基准测试都包括验证所获得的有效性的步骤。即使是用于对世界上最快的计算机进行基准测试的High Performance Linpack (HPL) 测试也有一个步骤来验证解决问题时计算出的答案。有几种不同的技术可以验证答案,如果这是您想要追求的路线,我可以发布答案。
  • @Matt 感谢您的评论,是的,每次运行串行/分布式版本时,结果都是可重现的。问题是两个版本解决了相同的问题,使用相同的算法,但输出的结果有点不同,因为分布式执行的性质,这导致操作的顺序不同,从而产生细微的差异。问题是(如果可能的话)我如何使分布式版本给出与串行版本相同的结果。您能否详细说明您的第二条评论?
  • 验证答案的一个例子是计算分布结果和实际结果之间的百分比误差。然后为有效答案设置一个阈值,例如两个结果之间的百分比误差小于 0.0001% 是否被视为有效答案?
  • 是的@Matt 我就是这么想的,但我想确定一下。所以,您是说我无法在串行执行和分布式执行之间获得相同的结果,但我可以使用阈值来验证分布式答案,对吧?

标签: c++ mpi distributed-computing intel-mkl scalapack


【解决方案1】:

您的差异似乎出现在大约 12 s.f.由于浮点算术不是真正的关联(即 fp 算术不能保证a+(b+c) == (a+b)+c),并且由于并行执行通常不会给出操作应用的确定顺序,所以这些小的差异是并行化的典型与它们的串行等效项相比,数字代码。实际上,当在不同数量的处理器上运行时,您可能会观察到相同的差异顺序,例如 4 对 8。

不幸的是,获得确定性结果的简单方法是坚持串行执行。要从并行执行中获得确定性的结果,需要付出很大的努力来非常具体地确定操作的执行顺序,直到最后一个 +* 这几乎可以肯定地排除了大多数数字库的使用并导致您费力大型数值例程的手动编码。

在大多数情况下,我遇到的输入数据的准确性(通常来自传感器)并不需要担心 12 号或更晚的 s.f.我不知道你的数字代表什么,但对于许多科学家和工程师来说,4 或 5 sf 的平等对于所有实际目的来说已经足够了。这对数学家来说是另一回事......

【讨论】:

  • 所以,马克,我基本上对 MKL 无能为力,我只能接受我会得到那么小的差异,对吧?
  • 是的,但不要怪MKL,这是易于并行数值计算的一个特点。消除差异很困难,很难以致于通常不值得付出努力。
  • 我看到马克了。所以我应该研究我得到的数字错误?你能就这个方向给点建议吗?
  • 并行计算产生的数值误差分析是一个极其复杂的领域。要么深入研究,可以在 SO 答案中解释的更深入,要么做大多数人所做的事情并忽略这个问题。直到你的钻头到达泥线以下 1000m 并且你碰到灰尘......
【解决方案2】:

正如另一个答案提到的那样,不能保证在串行和分布式之间获得完全相同的结果。 HPC/分布式工作负载的一种常见技术是验证解决方案。从计算百分比误差到更复杂的验证方案,有许多技术,比如used by the HPL。这是一个计算百分比误差的简单 C++ 函数。正如@HighPerformanceMark 在他的帖子中指出的那样,对这种数值错误的分析非常复杂;这是一种非常简单的方法,网上有很多关于该主题的信息。

#include <iostream>
#include <cmath>

double calc_error(double a,double x)
{
  return std::abs(x-a)/std::abs(a);
}
int main(void)
{
  double sans[]={-250207683.634793,-1353198687.861288,2816966067.598196,-144344843844.616425, 323890119928.788757};
  double pans[]={-250207683.634692, -1353198687.861386, 2816966067.598891, -144344843844.617096, 323890119928.788757};
  double err[5];
  std::cout<<"Serial Answer,Distributed Answer, Error"<<std::endl;
  for (int it=0; it<5; it++) {
    err[it]=calc_error(sans[it], pans[it]);
    std::cout<<sans[it]<<","<<pans[it]<<","<<err[it]<<"\n";
  }
return 0;
}

产生这个输出:

Serial Answer,Distributed Answer, Error
-2.50208e+08,-2.50208e+08,4.03665e-13
-1.3532e+09,-1.3532e+09,7.24136e-14
2.81697e+09,2.81697e+09,2.46631e-13
-1.44345e+11,-1.44345e+11,4.65127e-15
3.2389e+11,3.2389e+11,0

正如您所见,每种情况下的误差数量级都在 10^-13 或更少,在一种情况下不存在。根据您尝试解决的问题,这个数量级的错误可能被认为是可以接受的。希望这有助于说明一种验证分布式解决方案与串行解决方案的方法,或者至少提供一种方法来显示并行算法和串行算法之间的差距。

在验证大问题和并行算法的答案时,执行多次并行算法运行也很有价值,可以保存每次运行的结果。然后,您可以查看结果和/或错误是否随并行算法运行而变化,或者它是否随着时间的推移而稳定。

表明并行算法在 1000 次以上的运行中会产生可接受的阈值内的错误(只是一个示例,此类事情的数据越多越好)是评估结果有效性的一种方法。

在过去,当我执行基准测试时,我注意到在服务器“预热”之前的前几次运行的行为差异很大。当时我从不费心去检查结果中的错误是否会像性能一样随着时间的推移而稳定,但看看会很有趣。

【讨论】:

  • 该死的马特,这么好的答案,现在我不知道该接受哪一个。另一个答案完全关于我的帖子,而你的建议下一步,应该是这样。我的意思是,手术真的让我想起了我们在大学里教过的东西。所以,我可以按照您的示例进行操作,将err 数组的每个条目相加并将其除以 5,产生平均误差会不会很好?
  • 这似乎会给出平均误差,但在这种情况下,有一些可视化工具可能有助于显示两个值的接近程度。 CERN 开发了一个数据处理和可视化工具包,它非常适合庞大的数据集,并且有很多比这个例子更高级的错误计算。它被称为ROOT,它是开源的和基于 C++ 的。在查看性能数据时,我已经广泛使用它,虽然在这种情况下它可能有点矫枉过正,但它是一个非常强大的工具,可用于分析您的数据
  • 我承认另一个答案更适用于您发布@gsamaras 的问题,我的示例只是在两种算法之间查找错误的一种方式。有很多方法可以使用这种错误检测,除了平均错误,您可以查看超出您确定的阈值的错误值,以及各种其他更复杂的异常值检测技术。如果您愿意,我可以在答案中添加更多内容或将其迁移到其他问题。最终,马克发布了一个更直接的答案,可能比这个更容易接受
  • 嗨,马特,抱歉我的沉默,我正在研究大学的相关书籍。您的示例使用绝对相对误差,这是我一定会使用的! ROOT 看起来不错,但正如你所说,它太多了!是的,是的,我想看看这个方向。您希望我发布一个新问题,您可以将答案完全移到那里并扩展它吗?
  • 新帖子可能有用,如果您可以发布更大的数据,我可以做出更具体的答案并使用您熟悉的数据。我将 ROOT 用于很多事情,因此我将包含一些可视化和不同的异常值检测技术。我也可以尝试使用类似的类似环境来获得一些集群时间来重现数据,但这可能需要更长的时间。今天晚些时候我有一些事情要处理,但我今晚晚些时候或明天早上可能会有时间发布更全面的答案
猜你喜欢
  • 2011-02-27
  • 2020-04-23
  • 1970-01-01
  • 2018-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多