如何在不知道底层数据类型的情况下确定二进制数据的数值接近度

问题描述 投票:0回答:2

我目前正在为 OpenCL 内核实现重放功能,您可以在其中指定要独立于原始程序重放的内核,然后将其与独立执行该内核所需的相关信息一起捕获。我大部分时间都在使用它,但目前有一部分在努力:

为了确保没有愚蠢的错误,我想用原始内核的结果验证重放内核的结果。在我最初的用例中,我可以确定多次运行同一个内核时,结果完全相同,一点一点。这意味着我可以计算 OpenCL 缓冲区/图像的哈希值并检查是否相等。

但这不适用于大多数内核,因为浮点数学不是关联的,并且不能保证每次操作的顺序都相同。在这种情况下,使用哈希不起作用,我需要某种非常标准的 epsilon 接近度测试。

问题是,在我当前的实现中,我不知道二进制缓冲区的数据类型是什么,它可以是 int8 和 fp64 之间的任何类型。

现在的问题是,确定两个缓冲区之间的差异(从原始程序重放和捕获)的策略是什么,由于浮点数学中缺乏关联性而导致的差异很小。

floating-point opencl binary-data
2个回答
1
投票

假设你有相同长度的 Buffer1 和 Buffer2。为了便于讨论,让我们假设它们的字节长度是 24 的倍数,并且始终是相同的数据类型。您的不精确性问题不适用于整数数学,也不应适用于字符串,因此它们应该相同。您可以通过计算和比较它们的哈希值来比较它们。浮点结果的问题。假设缓冲区都是同一类型,fp16、bf16、fp24、fp32 或 fp64,但您不知道是哪种类型。您可以计算一个“错误”值,例如对于 fp16,

e_fp16 += 1 if ((a == 0) && (b != 0))
e_fp16 += 1 if ((a != 0) && (b == 0))
e_fp16 += (abs((b-a)/a)) if ((a != 0) && (b != 0))

每种类型的浮点格式一个。然后取最小值作为“错误”。

e = min(e_fp16, e_bf16, e_fp24, e_fp32, e_fp64)

0
投票

代码需要知道底层数据的类型。

没有它,信号位差异是显着还是微小是未知的。


某种 epsilon 接近度测试(用于浮点数)

为每个浮点值分配一个 index:0 表示 0.0,1 表示最小可编码的正浮点值,...,直到 N,表示最大值。然后 -1 表示最少可编码的负浮点值,...(这很容易通过一些位操作,但取决于实现)

然后使用简单的整数减法来评估接近度。

© www.soinside.com 2019 - 2024. All rights reserved.