Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
6763 Discussions

why two different IPP versions given different numerical results?

blade
Beginner
429 Views

Hello,

I am replacing the legacy library with a relatively newer IPP (2019). While performing tests I noticed resizing an image using Linear interpolation is giving different numerical results.

In the code below, I shrink a given matrix by half in each dimension using the legacy IPP library and IPP2019. I am expecting the two results to match, but they do not.

How do I fix this such that both the method give the exact same result?

 

The code below shows the problem. This is on Windows 10 and VS2017.

//################## START  #######################


#include <cstring>
#include <iostream>
#include <ipp.h>
#include <ippi.h>
#include <ippcore.h>
#include <ippi90legacy.h>
#include <ippi90legacy_redef.h>

 

/*!
Quick and dirty resize test comparing legacy and new IPP version.
Resized a matrix by scalefactor of 0.5 to bLeg using LegacyIPP and
to bNew using new IPP version lib.
*/
void TestResizeLinear() {
IppStatus sts = ippStsNoErr;

double const sf = 0.5;//scale factor to shrink the 2d matrix by

size_t const W = 8;
size_t const H = 8;
IppiSize srcSize = { W, H };
IppiRect srcRect = { 0, 0, W, H };
unsigned short A[W * H] =
{
163, 5, 60, 236, 148, 163, 58, 254,
109, 242, 176, 19, 92, 121, 254, 31,
25, 244, 32, 116, 85, 79, 133, 66,
160, 68, 222, 240, 207, 229, 164, 127,
217, 22, 187, 0, 209, 113, 203, 177,
251, 33, 240, 6, 7, 98, 160, 17,
47, 179, 47, 66, 61, 202, 142, 135,
212, 152, 9, 41, 240, 29, 155, 74
};


size_t const destW = size_t(W * sf + 0.5);
size_t const destH = size_t(H * sf + 0.5);
IppiRect destRect = { 0, 0, destW, destH };
unsigned short* pBLeg = new unsigned short[destW * destH];
memset(pBLeg, 0, destW * destH * sizeof(*pBLeg));

int interpolation = IPPI_INTER_LINEAR;
int buffSize = 0;
sts = ippiResizeGetBufSize(srcRect, destRect, 1, interpolation, &buffSize);
Ipp8u* pBuff = ippsMalloc_8u(buffSize);
double shift = 0;
sts = ippiResizeSqrPixel_16u_C1R(A, srcSize, W * sizeof(*A), srcRect,
pBLeg, destW * sizeof(*pBLeg), destRect,
sf, sf, shift, shift, interpolation, pBuff);
ippsFree(pBuff);
//Done with resizing using IPPlegacy. Next, resize using IPP2019.

unsigned short* pBNew = new unsigned short[destW * destH];
memset(pBNew, 0, destW * destH * sizeof(*pBNew));
IppiSize destSize = { destW, destH };
IppiPoint destOffset = { 0, 0 };

enum AAOPTION { WITHAA = 0, NOAA };
int SpecSize = 0;
int initBufSize = 0;
sts = ippiResizeGetSize_16u(srcSize, destSize, IppiInterpolationType::ippLinear, AAOPTION::WITHAA, &SpecSize, &initBufSize);
IppiResizeSpec_32f* pSpec = (IppiResizeSpec_32f*)ippsMalloc_8u(SpecSize);
Ipp8u* pInitBuf = (Ipp8u*)ippsMalloc_8u(initBufSize);
sts = ippiResizeLinearInit_16u(srcSize, destSize, pSpec);

int bufSize = 0;
sts = ippiResizeGetBufferSize_8u(pSpec, destSize, 1, &bufSize);
Ipp8u* pWorkBuffer = (Ipp8u*)ippsMalloc_8u(bufSize);

sts = ippiResizeLinear_16u_C1R(A, W * sizeof(*A),
pBNew, destW * sizeof(*pBNew),
destOffset, destSize,
IppiBorderType::ippBorderRepl, 0,
pSpec, pWorkBuffer);

ippsFree(pSpec);
ippsFree(pInitBuf);
ippsFree(pWorkBuffer);

//print out the differences.
//Differences between IPPLegacy and IPP2019 results expected to be zero. But got :
/*
-1 -1 0 0
0 0 0 0
-1 0 -1 0
-1 -1 0 0
*/
std::clog << "Differences in the two output matices:" << std::endl;
for (size_t r = 0; r < destH; r++) {
for (size_t c = 0; c < destW; c++) {
std::clog << " " << pBLeg[r * destW + c] - pBNew[r * destW + c] << " ";
}
std::clog << std::endl;
}


delete[] pBNew;
delete[] pBLeg;
return;
}

int main(int argc, char** argv) {

TestResizeLinear();

return 0;
}

//################### END #####################

 

Thanks!

0 Kudos
1 Solution
Ruqiu_C_Intel
Moderator
90 Views

Based on code backtracking, legacy function ippiResizeSqrPixel_16u_C1R was implemented with SSSE3, while new ippiResizeLinear_16u_C1R has been improved with newer instruction for newer CPUs.

Kindly noted that the older version does not include optimizations for newer CPU instructions, which means it may not be delivering the best possible performance for your system. Additionally, using such an outdated version poses certain security risks, as newer updates typically address vulnerabilities that have been identified over time.

For both improved performance and enhanced security, we strongly recommend upgrading to the latest version of the product. The new version has been optimized for modern hardware and includes important security patches.




View solution in original post

0 Kudos
5 Replies
Ruqiu_C_Intel
Moderator
411 Views

Hi,


IPP 9.0 was very old version, IPP has been optimized with newer instruction align to Intel new hardware. You can use setCpuFeatures to set the processor-specific library code for the specified processor features. https://www.intel.com/content/www/us/en/docs/ipp/developer-guide-reference/2021-12/setcpufeatures.html


May I ask which CPU platform that you are running?


And be keep in mind that both IPP 9.0 and IPP 2019 were out of support. Please update to IPP latest version from here: https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html


Regards,

Ruqiu


0 Kudos
blade
Beginner
374 Views

Hi,

Thanks for the info.

 

I tried the same program with VS 2022 and fresh download and install of OneaAPI IPP and got the same difference running the same code.

 

I am running this on an Intel CPU (obviously) and can get the details by printing out the CPU info via IPP functions sometime later today or tomorrow. While I work to do that, can you elaborate on what should I be looking for? My goal is to remove the numerical difference in results, and if that is not possible then to root cause the difference.

 

Thanks!

0 Kudos
blade
Beginner
327 Views

Here is the info related to the IPP version and the CPU features on the machine that is giving the different numerical outputs between IPP Legacy and newest version of IPP:

Processor 12th Gen Intel(R) Core(TM) i9-12900H, 2500 Mhz, 14 Core(s), 20 Logical Processor(s)

 ippIP AVX2 (l9) 2021.12.0 (r0x9b172c15) 2021. 12. 0. -1692980203
CPU Features: FEFFF
Cpu features enabled: FEFFF

Differences in the two output matrices:
 -1  -1  0  0
 0  0  0  0
 -1  0  -1  0
 -1  -1  0  0

 

Hope this helps to determine how to fix the differences.

 

Thanks

 

0 Kudos
Ruqiu_C_Intel
Moderator
268 Views

Thanks for the information. We will investigate it internally, and back to here if there is update.


0 Kudos
Ruqiu_C_Intel
Moderator
91 Views

Based on code backtracking, legacy function ippiResizeSqrPixel_16u_C1R was implemented with SSSE3, while new ippiResizeLinear_16u_C1R has been improved with newer instruction for newer CPUs.

Kindly noted that the older version does not include optimizations for newer CPU instructions, which means it may not be delivering the best possible performance for your system. Additionally, using such an outdated version poses certain security risks, as newer updates typically address vulnerabilities that have been identified over time.

For both improved performance and enhanced security, we strongly recommend upgrading to the latest version of the product. The new version has been optimized for modern hardware and includes important security patches.




0 Kudos
Reply