[英]Accurate computation of modified Bessel functions - Using netlib Fortran routines in CUDA?
我正在处理在CUDA中精确计算零阶I0的修正贝塞尔函数的问题。
很长一段时间,根据论文,我一直在使用理性的切比雪夫近似
JM Blair,“修正贝塞尔函数I_0(x)和I_1(x)的理性切比雪夫近似”,数学。 Comput。,vol。 28,n。 126,pp.581-583,1974年4月。
与Matlab提供的结果相比,它给出了1e-29的平均误差。 不幸的是,这个看似很高的精度对于我正在研究的新应用来说已经不够了。
Matlab使用DE Amos开发的Fortran例程
Amos,DE,“用于复杂论证和非负序的贝塞尔函数的子程序包”,桑迪亚国家实验室报告,SAND85-1018,1985年5月。
Amos,DE,“用于复杂论证和非负序的贝塞尔函数的便携式包”,Trans。 数学。 软件,1986年。
可以从netlib / amos网站下载。
有一些方法可以在C / C ++代码中使用这些Fortran例程,方法是在库文件中编译它们,然后使用C / C ++包装器(参见netlib_wrapping )。 我想知道是否有任何方法可以使那些Fortran例程中的设备功能被CUDA内核调用。
关于问题的更多细节
我有两个代码,一个用Matlab编写,另一个用CUDA编写。 两者都按三个步骤操作:
1) 通过修改的贝塞尔函数I0进行缩放和数据的零填充 ;
2) FFT ;
3) 插值 。
我将两者都与“精确”结果进行比较:作为步骤3)的输出,Matlab给出的相对均方根误差为1e-10%,而CUDA为1e-2%,因此我开始研究原因。
两个代码的第一步之间的均方差,即100*sqrt(sum(abs(U_Matlab_step_1-U_CUDA_step_1).^2))/sqrt(sum(abs(U_Matlab_step_1).^2))
,为0%
( mean(mean(abs(U_Matlab-U_CUDA)))=6e-29
代替)所以我会说它很好。 不幸的是,当我转到第2步时,错误会增加到2e-4%
。 最后,如果我用Matlab的步骤1)的输出提供CUDA的步骤2),那么步骤2)的rms误差变为1e-14%
,这使我认为不准确的来源是由于第一步,即,修改贝塞尔函数的计算。
有兴趣发展本次讨论
我想知道这是否可归因于浮点运算之间的精度差异。
有几件事要检查
圆桌会议
addition | x + y | __dadd_[rn|rz|ru|rd](x, y)
multiplication | x * y | __dmul_[rn|rz|ru|rd](x, y)
Fused-Mult-Add | fma(x, y, z) | __fma_[rn|rz|ru|rd](x, y, z)
reciprocal | 1.0 / x | __drcp_[rn|rz|ru|rd](x)
division | x / y | __ddiv_[rn|rz|ru|rd](x, y)
square root | sqrt(x) | __dsqrt_[rn|rz|ru|rd](x)
mode | interpretation
rn | round to nearest, ties to even
rz | round towards zero
ru | round towards +∞
rd | round towards -∞
来自http://developer.download.nvidia.com/assets/cuda/files/NVIDIA-CUDA-Floating-Point.pdf
我找到了一个介绍性的技术讲座来回答你的问题。 这是PDF的链接。 所以是的,这是可能的,但是我无法通过前面提到的脚本将遗留的fortran代码转换为CUDA C,也许直接联系开发人员。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.