I have the following function in my kernel source code:
double bondAngle(double3 pI, double3 pJ, double3 pK){
double3 pJK =normalize(pK-pJ);
double3 pJI = normalize(pI-pJ);
double3 _pJI = pI-pJ;
double3 _pJK =pK-pJ;
double3 test = (double3)(0.0,0.0,pK[2]-pJ[2]);
double3 testn = normalize(test);
if(isnan(acos(dot(pJI,pJK)/(length(pJI)*length(pJK))))){
printf("___\n"
"pI %f %f %f\n"
"pJ %f %f %f\n"
"pK %f %f %f\n"
"pJI %f %f %f\n"
"pJK %f %f %f\n"
"pJIn %f %f %f\n"
"pJKn %f %f %f\n"
"test %f %f %f\n"
"testn %f %f %f\n"
"dot(pJI,pJK) %f\n"
"___\n"
,
pI[0],pI[1],pI[2],
pJ[0],pJ[1],pJ[2],
pK[0],pK[1],pK[2],
_pJI[0],_pJI[1],_pJI[2],
_pJK[0],_pJK[1],_pJK[2],
pJI[0],pJI[1],pJI[2],
pJK[0],pJK[1],pJK[2],
test[0],test[1],test[2],
testn[0],testn[1],testn[2],
dot(pJI,pJK)
);
}
return acos(dot(pJI,pJK)/(length(pJI)*length(pJK)));
}
I don't see any obvious mistakes, but when I call the function on my dataset, some of the double3s are normalized to their length squared, instead of 1.0. Here is an exemplary log from my program.
___
pI -2.500000 -2.500000 0.005000
pJ -2.500000 -2.500000 -2.500000
pK -2.500000 -2.500000 2.500000
pJI 0.000000 0.000000 2.505000
pJK 0.000000 0.000000 5.000000
pJIn 0.000000 0.000000 1.000000
pJKn 0.000000 0.000000 25.000000
test 0.000000 0.000000 5.000000
testn 0.000000 0.000000 25.000000
dot(pJI,pJK) 25.000000
___
For my OpenCL driver, I'm using the Intel SDK version 7.0.0.4443, the value of cl.device_info.VERSION is 4143, and I am running my code on a laptop with integrated graphics.
Full kernel code: https://pastebin.com/uP9ARpph
Okay. I found the answer. Turns out practically all double-precision operations in my program were unreliable. I changed my program to use floats instead, and it works fine.