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

ippiTranspose crashing

TZeit
Beginner
1,109 Views

Hi,

I am calling ippTranspose with the following parameters (and valid buffer pointers of course):

void *pSrc = <input buffer>;
void *pDst = <output buffer>;
int iWidth  = 640;
int iHeight = 480;
int iSrcStep = iWidth * 3;
int iDstStep = iHeight * 3;
int iSrcOffset = iSrcStep * (iHeight - 1);
int iSrcStepT  = -iSrcStep;
IppiSize sizeSrc = { iWidth, iHeight };
ippiTranspose_8u_C3R((Ipp8u*)pSrc + iSrcOffset, iSrcStepT, (Ipp8u*)pDst, iDstStep, sizeSrc);

It crashes here:

  050BD325  add         esi,ecx
  050BD327  add         edi,3
  050BD32A  sub         ebx,1
  050BD32D  je          _p8_owniTranspose_8u_C3R+51h (50BD2E1h)
  050BD32F  jmp         _p8_owniTranspose_8u_C3R+7Ah (50BD30Ah)
  050BD331  sub         ebx,9
  050BD334  jl          _p8_owniTranspose_8u_C3R+116h (50BD3A6h)
> 050BD336  movd        xmm0,dword ptr [esi]
  050BD33A  movd        xmm1,dword ptr [ecx+esi]
  050BD33F  movd        xmm2,dword ptr [esi+ecx*2]
  050BD344  movd        xmm3,dword ptr [ebp+esi]
  050BD34A  movd        xmm4,dword ptr [esi+ecx*4]
  050BD34F  lea         esi,[esi+ecx*4]
  050BD352  punpckldq   xmm0,xmm1
  050BD356  punpckldq   xmm2,xmm3

It looks like it processes the first source line (which is actually the last) and then ESI points to the next line after the last line instead of respecting the given source step to the next line before the last line.

Am I doing something wrong or is this a bug?
IPP version is 8.1 U1 (included with C++ Composer XE 2013 SP1 U4).

0 Kudos
7 Replies
Igor_A_Intel
Employee
1,109 Views

Hi Toni,

why do you use the negative step for source image? Does your pSrc points to the last row of the image? If it points to the top row - you shouldn't use the negative step...

regards, Igor

0 Kudos
TZeit
Beginner
1,109 Views

Hi Igor,

pSrc points to the first row. I use a negative step because want to rotate the image by 90° (or 270°, depending if you look at it clockwise or counter-clockwise).

Additional information: I tested some other random images meanwhile, the same code works fine with 4 channels and the C4R variant (and factor 4 for the step sizes of course).

Regards, Toni

0 Kudos
TZeit
Beginner
1,109 Views

Some hot news:
I posted this because I was sure it is related to IPP and because it is 100% reproducible with the identical result. Now I changed some code quite far away from the ippiTranspose call and the crash is gone and everything works - even when ippiTranspose is called with the same input/output data and identical parameters. So currently I guess it is some kind of side-effect of another issue somewhere in the code around and is not related to IPP. I'll let you know if I found out what actually went wrong...

0 Kudos
Chao_Y_Intel
Moderator
1,109 Views

Toni, 

Thanks for your update.  If you see if there is any problem with IPP,  please help to submit some test code, that will help us quickly isolate the problem. 

Thanks,
Chao

0 Kudos
TZeit
Beginner
1,109 Views

Hi Chao,

it took some time until I could start testing again. Now I am sure this is an IPP bug. I only know this for sure for the P8 8u C3R variant of ippiTranspose and for IPP 8.1.1 - I did not test other variants and versions but some of these might of course contain the same issue. The code crashes reliably because of out-of-bounds read access (after the last pixel of the image). The PX variant of ippiTranspose_8u_C3R does not crash and works correctly but the P8 variant (using SSE) does. You can test this easily by omitting ippInit.

I added fully "working" test code below. It uses VirtualAlloc() to ensure the requested size of memory is exactly allocated. Other allocation methods (ippMalloc, malloc, new, stack, ...) do not crash reliably because they obviously take some part out of their own memory pool. This does not cause an access violation when ippTranspose reads out-of-bounds because it just reads something else out of the the pool.

Are you going to fix this?

Best regards,
Toni

#include <windows.h>
#include <ippi.h>
#include <ippcore.h>

static const int iWidth    = 640;
static const int iHeight   = 480;
static const int iChannels = 3;

int main(int argc, char **args)
{
  IppiSize size = { iWidth, iHeight };
  int iImageSize    = iWidth * iHeight * iChannels;
  int iSourceStride = iWidth * iChannels;
  int iDestStride   = iHeight * iChannels;
  int iSourceOffset = (iSourceStride * (iHeight - 1));
  
  Ipp8u *pSourceImage = (Ipp8u*)VirtualAlloc(NULL, iImageSize, MEM_COMMIT, PAGE_READWRITE);
  Ipp8u *pDestination = new Ipp8u[iImageSize];

  ippInit();
  ippiTranspose_8u_C3R(pSourceImage + iSourceOffset, -iSourceStride, pDestination, iDestStride, size);

  delete [] pDestination;
  VirtualFree(pSourceImage, 0, MEM_RELEASE);
  return 0;
}
0 Kudos
TZeit
Beginner
1,109 Views

Hello... is still somebody here reading this thread?

0 Kudos
Igor_A_Intel
Employee
1,109 Views

Hi Toni,

thank you for the reproducer - I've reproduced the issue - will be fixed in the next IPP release.

regards, Igor

0 Kudos
Reply