[Beignet] [PATCH] utests: fix test case builtin_tgamma.
Rebecca N. Palmer
rebecca_palmer at zoho.com
Thu Apr 23 07:33:18 PDT 2015
> Should use tgamma instead of tgammaf when generating reference.
That I agree with: we don't want the error of libc tgammaf (~4ulp)
appearing to be our error.
> And the ulp bound is <= 16ulp
That I wouldn't: it's defined in terms of the infinitely precise value,
not the correctly-rounded-float value, so (e.g.)16.3ulp would round to
16ulp and pass the test when it shouldn't.
Also, if it's that close to failing for positive inputs, it probably
fails for negative inputs (which this test currently doesn't test).
> I find that even with your patch the builtin_tgamma still fails.
For me the maximum error is 8ulp on the old test (i.e. positive input
and including tgammaf's error), 4ulp (positive input) 6ulp (negative
input) on my fixed test, so this is a real hardware-dependent error
not just test issues. What result do you get with this patch?
--------
Compare with tgamma instead of tgammaf for better accuracy.
Include negative inputs, and handle the resulting denormals.
Print maximum error found.
Signed-off-by: Rebecca Palmer <rebecca_palmer at zoho.com>
diff --git a/utests/builtin_tgamma.cpp b/utests/builtin_tgamma.cpp
index 47cc5f4..b7db69b 100644
--- a/utests/builtin_tgamma.cpp
+++ b/utests/builtin_tgamma.cpp
@@ -20,10 +20,15 @@ void builtin_tgamma(void)
if (env_strict == NULL || strcmp(env_strict, "0") == 0)
ULPSIZE_FACTOR = 10000.;
- for (int j = 0; j < 1024; j ++) {
+ cl_device_fp_config fp_config;
+ clGetDeviceInfo(device, CL_DEVICE_SINGLE_FP_CONFIG, sizeof(cl_device_fp_config), &fp_config, 0);
+ bool denormals_supported = fp_config & CL_FP_DENORM;
+ float max_ulp = 0, max_ulp_at = 0;
+
+ for (int j = 0; j < 128; j ++) {
OCL_MAP_BUFFER(0);
for (int i = 0; i < n; ++i) {
- src[i] = ((float*)buf_data[0])[i] = (j*n+i+1) * 0.001f;
+ src[i] = ((float*)buf_data[0])[i] = j - 64 + i*0.001f;
}
OCL_UNMAP_BUFFER(0);
@@ -32,7 +37,14 @@ void builtin_tgamma(void)
OCL_MAP_BUFFER(1);
float *dst = (float*)buf_data[1];
for (int i = 0; i < n; ++i) {
- float cpu = tgammaf(src[i]);
+ float cpu = tgamma(src[i]);
+ if (!denormals_supported && std::fpclassify(cpu)==FP_SUBNORMAL && dst[i]==0) {
+ cpu = 0;
+ }
+ if (fabsf(cpu - dst[i]) > cl_FLT_ULP(cpu) * max_ulp) {
+ max_ulp = fabsf(cpu - dst[i]) / cl_FLT_ULP(cpu);
+ max_ulp_at = src[i];
+ }
if (isinf(cpu)) {
OCL_ASSERT(isinf(dst[i]));
} else if (fabsf(cpu - dst[i]) >= cl_FLT_ULP(cpu) * ULPSIZE_FACTOR) {
@@ -42,6 +54,7 @@ void builtin_tgamma(void)
}
OCL_UNMAP_BUFFER(1);
}
+ printf("max error=%f ulp at x=%f ", max_ulp, max_ulp_at);
}
MAKE_UTEST_FROM_FUNCTION(builtin_tgamma);
More information about the Beignet
mailing list