可能的编译器错误:在两台机器之间使用带有英特尔编译器的 boost bessel 函数的奇怪结果?

Posted

技术标签:

【中文标题】可能的编译器错误:在两台机器之间使用带有英特尔编译器的 boost bessel 函数的奇怪结果?【英文标题】:Possible compiler bug: Weird results using boost bessel functions with Intel compiler between two machines? 【发布时间】:2014-03-04 17:06:08 【问题描述】:

我正在尝试在项目中使用 boost 的贝塞尔函数 (cyl_bessel_j)。但是,我发现该函数在大约 2000 次调用后返回带有错误符号的结果。

我已经在两台机器之间进行了测试,一台是 CentOS 5.8(Final)机器,它在其中运行得非常奇怪,另一台是 RHEL 6.3(圣地亚哥)机器,它失败了。

两台机器都使用 Boost 1.50.0 和 13.1.3 20130607 Intel 编译器。 CentOS机器使用gcc 4.1.2 20080704,RHEL机器使用gcc 4.4.6 20120305。

这是我的代码:

template<typename FloatType> FloatType funcT(FloatType z, FloatType phi,
                                             int n, int m, int p)

  using namespace boost::math;
  FloatType sqrt2PiZ = sqrt((2 * M_PI)/z);
  FloatType nrmLeg = normalizedLegendre(n,m,-sin(phi));
  FloatType besselJ = cyl_bessel_j(p + 0.5, z);

  std::cout << "  " << p << "," << z << "  besselJ: " << besselJ << std::endl;

  return sqrt2PiZ * nrmLeg * besselJ;

在两台机器上运行时,我发现两者之间唯一不同的术语是 besselJ 术语。对于 1980 年对该函数的第一次调用,它们返回相同的结果,但是,在第 1981 次调用中,RHEL 机器突然切换其结果的符号。前几个失败的术语打印如下(RHEL SIDE):

  ...
  1,7.90559 besselJ: -0.0504874
  2,7.90559 besselJ: 0.264237
  3,7.90559 besselJ: 0.217608
  ...

在 MATLAB 中使用 besselJ 函数运行参考测试,我发现对于这些输入,符号应该是相反的,而且 CentOS 机器确实与 MATLAB 一致。

我决定用 besselJ 函数编写一个简单的 hello-world 样式示例来尝试确定失败的原因:

#include <boost/math/special_functions/bessel.hpp>
#include <iostream>

int main(int argc, char** argv)

  double besselTerm = boost::math::cyl_bessel_j(1.5, 7.90559);
  std::cout << besselTerm << std::endl;

此测试在 BOTH 机器上返回预期值 0.0504874。

此时,我正在努力确定问题的原因。这似乎是一些奇怪的编译器错误或堆栈损坏。但是,堆栈损坏如何给出除了一个位之外的确切正确答案?

有没有人在使用 boost 或 Intel 编译器时遇到过类似的问题?

其他信息: 已经发现,带有 --fast-math 标志的 GCC 4.4.6 上的最小案例测试会中断。通过使用 -std=c++11 标志(这是较大的项目使用的),我还能够使英特尔编译器失败的最小测试用例。

【问题讨论】:

boost::math::cyl_bessel_j 的输入真的一样吗?还是它们与 LSB 不同,而那些数字只是没有被打印出来。 它们是一样的。如果不是,则两台机器的 sqrt2PiZ 术语将不同,我已经验证该术语是相同的。 看起来它们甚至在打印输出 1,7.90559 besselJ: -0.0504874 和最小示例 cyl_bessel_j(1.5, 7.90559) 之间也有所不同。 现在这很奇怪。你是如何进行测试的?我的最小示例在两台机器上都给出了积极的信号。 有趣。根据--fast-math 的存在/不存在,我得到不同的结果(仅在符号上有所不同)。 4.8.1-10ubuntu9。也许这是一个错误。我的猜测是,对于错误报告来说,这可能还不够小。看看你是否能分辨出 cyl_bessel_j 内部哪里出了问题。 【参考方案1】:

一个错误已提交到 boost 库 trac 系统。

然而,发现问题出在 std c++ 库中,表明 GCC 4.4.7 中存在问题。

Boost 开发人员创建了解决此问题的解决方法补丁: https://github.com/boostorg/math/commit/9f8ffee4b7a3f82b1c582735d43522d7d0cde746

【讨论】:

以上是关于可能的编译器错误:在两台机器之间使用带有英特尔编译器的 boost bessel 函数的奇怪结果?的主要内容,如果未能解决你的问题,请参考以下文章

同一个C语言程序,若在两台不同指令系统的机器上运行,编译后的程序是不是一样?能否用同一个编译器编译?

如何通过socket编程在两台机器之间发送文件?

使用带有 libmodbus 或 pymodbus 的 USB 连接在两台 PC 之间进行 Modbus 模拟

如何实现Robot框架在两台不同机器上并行测试执行?

为啥此代码段错误(在分配期间)与 pgi 而不是英特尔?

使用git在两台机器间同步代码