Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.
7230 Discussions

differences between c standard library and MKL

hagai
Beginner
1,623 Views

Hi,

I have some differences between the c standard library and mkl when using vdTanh and tanh.

[cpp]double val = 0.020630512405774085;
double e1 = tanh(val);
double e2;

vdTanh(1, &val, &e2);[/cpp]

The results are different in the last 2 digits of the double. Any ideas why this happens?

I am trying to compare some code which was written without MKL to a code with MKL. Should I have such differences?

Thanks,

Hagai.

0 Kudos
9 Replies
newton_particle
Beginner
1,623 Views

Make sure you are aligning the first value of your arrays (or, in this case your variable) to the 16-byte boundary to guarantee accuracy. See the section marked Aligning Data for Numerical Stability in the Users Guide for more details.

Newton
--------

0 Kudos
newton_particle
Beginner
1,623 Views
Quoting - Hagai.
  1. double val=0.020630512405774085;
  2. double e1=tanh(val);
  3. double e2;
  4. vdTanh(1,&val,&e2);

FYI: the precise answer to the above is: 0.02062758600 // I ran it through Maple and Google and got the same answer.


Newton
--------

(Q) Is there not an edit post button on this forum?? or am I going blind?? :o

0 Kudos
TimP
Honored Contributor III
1,623 Views

The Edit button was turned on for many of us, with a general correction of permissions last week. If you still don't see it, you might ask the forum administrators.

With the regard to the difference you quote, MKL math functions would not be using extended precision, so a relative difference on the order of DBL_EPSILON would be expected. Asking for more digits in printf() doesn't influence the compiler in its choice of math functions. You can make as many "last digits" wrong as you choose, within the limitations of your printf() library, by choosing to display more digits.

0 Kudos
newton_particle
Beginner
1,623 Views
Quoting - tim18
With the regard to the difference you quote, MKL math functions would not be using extended precision, so a relative difference on the order of DBL_EPSILON would be expected.

I often find that there is a variation on the last 2 digits relate to an either/or combination of processor type, and alignment issues. Both of which can cause the issue Hagai is describing. For example, the box Im currently using hosts an Athlon 64 FX-## processor which also presents the issue described.


The output I pasted above was produced using Maple to 100dp, so it is actually a precise value in Hagai's example. It's a useful check as it is calculated with an arbitrary length floating point simulation that gets around these issues (at a cost of speed). But yes, your point about console output rounding is a good note.


The issue from alignment (or other) error is worth identifyin, especially in iteration scenarios, where the error can be compounded. In financial applications, for example, this is a 'very' serious issue.

Newton
--------

0 Kudos
hagai
Beginner
1,623 Views

Hi guys,

Thanks for your responses. I tried using aligned values but that didn't change the result. I am not using printf or any other kind of output printing, I just watch the result in the debugger.

Could it just be that MKL and the standard library use different precision?

This is the new code:

[cpp]	double* pval = reinterpret_cast(MKL_malloc(sizeof(double), 16 ));
	double* pe1 = reinterpret_cast(MKL_malloc(sizeof(double), 16 ));
	double* pe2 = reinterpret_cast(MKL_malloc(sizeof(double), 16 ));
	*pval = 0.020630512405774085;
	*pe1 = tanh(*pval);
	vdTanh(1, pval, pe2);
	
	bool ret = *pe1 == *pe2;
	MKL_free(pval);
	MKL_free(pe1);
	MKL_free(pe2);
	return ret;
[/cpp]

0 Kudos
newton_particle
Beginner
1,623 Views

Hi Hagai,

I was only half paying attention in my previous posts. In your tests you are calling vector math functions. If you check in the Reference Manual for the section on VML Service Functions, you will see that there are 3 levels of accuracy available, via the SetMode() function:

VML_HA -> High accuracy versions of VML functions will be used.
VML_LA -> Low accuracy versions of VML functions will be used.
VML_EP -> Enhanced Performance accuracy versions of VML functions will be used.

The other factors, previously mentioned, can also play a part (CPU + Alignment). Beyond that, it is highly unlikely you will get a match by testing for equality as floating point numbers cannot reliably be compared for exact equality ( http://teaching.idallen.com/cst8110/97s/floating_point.html ).

An example of where this problem frequently comes up is testing Asserts in tools like NUnit. To deal with this problem you must specify a tolerance for floating point comparisons; using: GlobalSettings.DefaultFloatingPointTolerance

As floating point values are only approximations of real numbers, you can never universally achieve true precision; only a value that is for all practical purposes good enough.

*If* you have a particular scientific/mathematical need for arbitrary levels of floating point precision, that are far beyond that of 32/64-bit precision, then your only real option is to use more specialized libraries, such as: the GMP MP Bignum Library ( http://gmplib.org/ ); or the MPFR library ( http://www.mpfr.org/ ).

Can I ask why float precision is so important to you?

Newton
--------

0 Kudos
TimP
Honored Contributor III
1,623 Views

Hagai has not yet explained what is wanted. A careful implementation of tanhl() should work to 20 significant digits, if that is what is wanted. Current icc includes the -fp:extended switch to request intermediate long double precision, but that would go only part way. With Microsoft compilers and that version of "the C standard library," there is no support for long double as a distinct data type. There may exist implementations where tanh() and tanhl() share a careful long double implementation, but Hagai has given no indication which library this is. The MKL functions under discussion clearly are limited to double, with no possibility of extended accuracy.

0 Kudos
Eugeny_G_Intel
Employee
1,623 Views
Hello. Different math libraries can give different results. But two different libraries give the same result more often if they have upper error bound more tight (for example MUER, maximum ulp error requirement). For example Intel Compilers LIBM MUER is about 0.55 ulp for most functions. VML HA functions MUER is 0.55-1.0 ulp, VML LA functions MUER is 4.0 ulp.
0 Kudos
hagai
Beginner
1,623 Views

Hi,

Precision is important to me because I want to compare my results to someone else's code, which uses the standard library rather than MKL. I worked around this by dividing the difference by the value, but it's not good enough.

0 Kudos
Reply