Intel® Integrated Performance Primitives
Community support and discussions relating to developing high-performance vision, signal, security, and storage applications.
6600 Discussions

ippsThreshold_LTAbsVal_64f weird behaviour

agildr
Novice
521 Views

Hi,

I'm trying to use ippsThreshold_LTAbsVal_64f to replace small numbers by zero.

According to the documentation a call like ippsThreshold_LTAbsVal_64f(xPtr, resultPtr, length, eps, 0.0) should replace all numbers in x that are in magnitude smaller than eps by zero.

To quote the docs, the logic is:

if( ABS(x[i]) < level ) y[i] = value;
else y[i] = x[i];

I have written the following C# program. I hope it is OK to post C# code, I also had no problems with any other IPP function from C# so far, only this one.

static class IPP
{
	[SuppressUnmanagedCodeSecurity, DllImport("libippcore.so", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
	public static extern int ippInit();

	[SuppressUnmanagedCodeSecurity, DllImport("libipps.so", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
	public static extern unsafe int ippsThreshold_LTAbsVal_64f(double* pSrc, double* pDst, int len, double level, double value);
}

static class Program
{
	static unsafe void IppSanityCheck(int index1, int index2)
	{
		const int length = 10000;
		var array = new double[length];
		var result = new double[length];

		const double eps = 1e-6;
		// setting some indices to values |.| > eps
		array[index1] = 100.0;
		array[index2] = -95.0;

		for (var i = 0; i < length; i++)
		{
			if (array[i] != 0.0)
			{
				Console.WriteLine("Input index {0} contains non-zero value: {1}", i, array[i]);
			}
		}

		fixed (double* arrayPtr = array, resultPtr = result)
		{
			var statusCode = IPP.ippsThreshold_LTAbsVal_64f(arrayPtr, resultPtr, length, eps, 0);
			Console.WriteLine("{0} exited with {1}", nameof(IPP.ippsThreshold_LTAbsVal_64f), statusCode);
		}

		// expect same vector as result
		for (var i = 0; i < length; i++)
		{
			if (Math.Abs(array[i] - result[i]) > 1e-16)
			{
				Console.WriteLine("Result index {0} differs from input: {1} vs. {2}", i, array[i], result[i]);
			}
		}
	}

	static void Main(string[] args)
	{
		if (IPP.ippInit() == 0)
		{
			IppSanityCheck(534, 1096);
			IppSanityCheck(1,2);
		}
		return;
	}
}

This is the output:

Input index 534 contains non-zero value: 100
Input index 1096 contains non-zero value: -95
ippsThreshold_LTAbsVal_64f exited with 0
Result index 534 differs from input: 100 vs. 0
Result index 1096 differs from input: -95 vs. 0
Input index 1 contains non-zero value: 100
Input index 2 contains non-zero value: -95
ippsThreshold_LTAbsVal_64f exited with 0
The program 'dotnet' has exited with code 0 (0x0).

As you can see when calling it with the first input (all zero except for indices 534 and 1096) the non-zero indices get replaced by zero (wrong). When calling it with the second input (now indices 1 and 2) they are not replaced (correct).

Running on Docker/WSL2, x64, Debian 10, .NET 5, IPP is from the Intel APT repo:

# uname -a
Linux 2d1918de08d8 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 GNU/Linux
# dpkg -l | grep intel
ii  intel-oneapi-runtime-ipp           2021.3.0-333           amd64        Intel® Integrated Performance Primitives runtime
ii  intel-oneapi-runtime-ipp-common    2021.3.0-333           all          Intel® Integrated Performance Primitives runtime common
ii  intel-oneapi-runtime-openmp        2021.3.0-3350          amd64        Intel® OpenMP* Runtime Library runtime
ii  intel-oneapi-runtime-openmp-common 2021.3.0-3350          all          l_openmp.runtime.description>
ii  intel-oneapi-runtime-tbb           2021.3.0-511           amd64        Intel® oneAPI Threading Building Blocks runtime
ii  intel-oneapi-runtime-tbb-common    2021.3.0-511           all          Intel® oneAPI Threading Building Blocks runtime common
#

But I have tried on Windows as well and the behavior is the same.

Best,

agildr

Labels (1)
0 Kudos
5 Replies
ShanmukhS_Intel
Moderator
462 Views

Hi,


Thanks for reaching out to us.


We have tried compiling and executing the shared code. 


>>if( ABS(x[i]) < level ) y[i] = value;

else y[i] = x[i];


As per the absolute threshold formula, among the indices shared by you,


Considering 1st case 100 

Absolute of 100 which is 100 and greater than 1e-6. Hence the threshold doesn't get affected.


Considering 2nd case -95

Absolute of -95 which is 95 and greater than 1e-6. Hence the threshold doesn't get affected.


Kindly let us know if any difference in understanding.


Best Regards,

Shanmukh.SS


agildr
Novice
427 Views

Hi Shanmukh.SS,

 

Yes, with the values supplied (0, -95, 100) the result should be the same as the input, since nothing ever is under the threshold (in magnitude), and zero already is equal to zero.

 

This works with the vector [0,100,-95,0,...,0] (length 10000). However, in the case where I put the 100 at index 534 and -95 at index 1096 I get a different vector (all zeroes) back.

 

Best,

agildr

ShanmukhS_Intel
Moderator
392 Views

Hi,


Thank you for sharing the details. The issue is reproducible with indices 534 and 1096 for which the results should have been 100 and -95. Instead, it is returning 0.


We are looking into your issue. We will get back to you soon.


Best Regards,

Shanmukh.SS


Andrey_B_Intel
Employee
343 Views

Hi Agildr.

I confirm this issue with ippsThreshold_LTAbsVal_64f.

Fix will be available in one of next IPP releases.

Thanks.

Andrey.

 

agildr
Novice
278 Views

Hi Andrey,

 

Thanks for the reply.

Can you maybe offer any insights on which constellations trigger this bug?

I'm asking because I have another test case, posting it below.

const int len = 10000;
var x = new double[len];
var y = new double[len];
x[1] = 100;
x[2] = -95;
unsafe
{
  fixed (double* xPtr = x, yPtr = y)
  {
    IPP.ippsThreshold_LTAbsVal_64f(xPtr, yPtr, len, 0.01, 1000);
  }
}

First elements of y:

1000
100	
-95	
1000
1000
0	
0	
1000
1000
0	
0	
1000
1000
0	
0	
1000

Best,

Luca

Reply