- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the information. We will investigate it internally, and back to here if there is update.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page