2017-05-26 40 views
1

我在OpenCL中实现了一些并行BLAS例程。为了检查内核是否正确,我也以一种天真的方式实现了相同的例程。在执行内核之后,我将内核结果与朴素实现的结果进行比较。检查并行BLAS例程的结果

据我所知,我无法将float的值与==进行比较。因此,我计算两个floats的绝对差异并检查它是否超出限制。我已阅读this article,其中描述了其他几种比较floats的方法。然而,我的问题是,我不确定用于比较floats的限制。在我的情况下,极限似乎高度依赖于BLAS例程和输入大小。

例如,我实现了asum,它计算了浮点值向量的绝对和。对于大小为16 777 216的输入向量,天真实现和我的并行实现之间的差异是96!对于1 048 576的输入大小,差异仅为0.5。我相当肯定我的内核是正确的,因为我手动检查了小输入大小的结果。我猜测由于大的输入矢量,差异会累积。

我的问题是,有没有一种方法可以计算最大的差异,可以源自float不准确?有没有办法知道由于内核代码中的错误而导致差异何时确定?

+0

预期偏差取决于输入的大小,因此没有单个常量限制,您可以使用 – harold

+0

我知道确切的输入大小,因为我只想检查一些正确性。 –

+0

没有严格的规定? –

回答

2

有一种称为区间数学的技术,您可以在这里使用。

而不必你认为可以接受一些固定的错误,你跟踪至少值给定的浮点运算可以“实际上是”被提及的。

Wikipedia has an article on it

如果我找不到库,我要做的是创建一个区间浮点类型。它包含两个浮点数,它们表示间隔可以表示的最高和最低(含)值。

它将覆盖+*/-以包括舍入的效果。这将需要工作来写。

所以,如果你添加{1.0,1.0}{2.0,2.0},答案是{3.0,3.0},如3.0值的范围可以大到足以解释在1.02.0 S上的错误。

减去2.0并且答案变成{0.9999999999997, 1.00000000003}或类似,因为{3.0, 3.0}中的错误大于{1.0, 1.0}暗示的错误。

这同样适用于乘法和除法。

如果您涉及分工,这些时间间隔可能会非常容易地达到“每个可能的数字,包括inf/nan”。而且,如前所述,减法会导致严重的问题;如果你有大的条款取消,你可以很容易地结束比你想象的更大的误差线。最后,如果你的OpenCL解决方案在间隔内产生一个值,你可以说“好吧,这没有错”。

+0

谢谢你的建议。你能否详细说明为什么在'{0.9999999999997,1.00000000003}'中减去2.0的结果?我认为在区间数学中,你会从“{3.0,3.0}”这两个元素中减去2.0。为什么会导致两个不同的值? –

+0

@Richard由于四舍五入,“1.0”值的范围表示为“1.0”处的1 +/-浮点错误。当你在2.0处减去2 +/-误差和在3.0处减去3 +/-误差时,你会得到1 +/-(在2.0时出错+在3.0时出错)。由于浮点错误以较高的幅度上升,这大于'错误在1.0'。因此,为了反映这一点,浮点值的间隔不再是'最大值1.0可以表示,最小值1.0可以表示',而是'最大值1.0000000003可以表示,最小值0.999999997可以表示'(这些值不是确切的) 。 – Yakk