我在OpenCL中实现了一些并行BLAS例程。为了检查内核是否正确,我还以一种天真的方式实现了相同的例程。在执行内核之后,我将内核结果与天真实现的结果进行比较。
我知道我无法将float
值与==
进行比较。因此,我计算两个floats
的绝对差值,并检查它是否超出限制。我已经阅读了this article,其中介绍了一些比较floats
的其他方法。但问题是,我不确定用于比较floats
的限制。在我的情况下,限制似乎高度依赖于BLAS例程和输入大小。
例如,我实现了asum
来计算浮点值向量的绝对和。对于大小为16 777 216的输入向量,天真实现与我的并行化实现之间的差异为96!对于1 048 576的输入大小,差异仅为0.5。我相当肯定我的内核是正确的,因为我手动检查了小输入大小的结果。由于输入矢量较大,我猜测差异会累积。
我的问题是,有没有办法计算可能来自float
不准确的最大差异?有没有办法知道差异何时由于内核代码中的错误而确定?
答案 0 :(得分:2)
你可以在这里使用一种称为区间数学的技术。
您可以跟踪大多数和最少值,而不是出现一些您认为可以接受的固定错误。#34;实际上&#34 ;指的是。
Wikipedia has an article on it
如果我找不到图书馆,我要做的就是创建一个间隔浮动类型。它包含两个浮点数,表示间隔可以表示的最高和最低(包含)值。
它会覆盖+
和*
以及/
和-
以包含舍入的效果。写作需要花时间。
因此,如果您添加{1.0,1.0}
和{2.0,2.0}
,则答案为{3.0,3.0}
,因为3.0
中的值范围可能足以说明错误在1.0
和2.0
s。
减去2.0,答案变为{0.9999999999997, 1.00000000003}
或类似,因为{3.0, 3.0}
中的错误大于{1.0, 1.0}
隐含的错误。
同样适用于乘法和除法。
这些间隔可能非常容易达到每个可能的数量,包括inf / nan"如果你涉及分工。并且,如上所述,减法会导致严重的问题;如果你有大的术语取消,你很容易得到比你想象的更大的误差条。
最后,如果您的OpenCL解决方案在该时间间隔内产生一个值,您可以说"嗯,它没有错误"。