Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Lars_A_
Beginner
168 Views

[IPP903] ippiPyramidLayerDown_32f_C1R is giving access violation errors

Dear Intel

We are working on updating our software in C# from IPP 8.0.2 to IPP 9.0.3.

We have problems calling “ippiPyramidLayerDown_32f_C1R”. Calling “ippiPyramidLayerDown_8u_C1R” works fine and gives no errors.

We have noticed the following:

  • Sometimes we get an error of access violation.
  • Sometimes we get a return value of -6 corresponding to “ippStsSizeErr: Incorrect value for data size”.
  • There The values of the width and height in the pPyramidStruct[0].pRoi[0] is wrong.
    Our roi is 513x511 and the value in pRoi[0] is 492247304x0.

pRoiError.PNG

Our C# implementation of the “IppiPyramid” structure look like this (and is also attached):

ippiPyramid.PNG
Please find attached the C# code for the dll imports and the pyramidDown function.

Are we implementing the “IppiPyramid” structure wrongly?

Best Regards
Kristian Thomsen

 

 

0 Kudos
6 Replies
Thomas_Jensen1
Beginner
168 Views

Just a thought, are you very sure that your C# struct "private struct IppiPyramid" is compatible in size with IPP?

If any member is aligned differently, or has a difference in 32-bit / 64-bit, it will fail.

Thomas

Lars_A_
Beginner
168 Views

Dear Thomas

Thank you for your response.

We are running all our software in 64bit.

are you very sure that your C# struct "private struct IppiPyramid" is compatible in size with IPP?

No, we don't know that for sure. Do you know how we can check it?

Regards Kristian

Thomas_Jensen1
Beginner
168 Views

Look in ippcv.h :

typedef struct _IppiPyramid {
    Ipp8u         **pImage;
    IppiSize      *pRoi;
    Ipp64f        *pRate;
    int           *pStep;
    Ipp8u         *pState;
    int            level;
} IppiPyramid;


A test could be to compare sizeof of the C++ and C# structures; they should be the same.

Thomas

 

Lars_A_
Beginner
168 Views

Thank you for your answer Thomas.

We have made a small C++ consol application and tested the sizeof the IppiPyramid struct. We have also tested it in C#. Both in C++ and C# we get a size of 48 in 64bit. (we are only interested in using 64 bit.) The code is attached.

However when we print out the address in memory of each variable in the IppiPyramid struct we see that the each variabel in the C# implementation is placed with an offset of 8 bytes when compared to the C++ implementation.

In C++ this method was used:

IppiPyramid pyr;
std::cout << (unsigned long)&pyr.pImage - (unsigned long)&pyr;

In C# this method was used:

var pyr = new IppiPyramid();
ulong ptrMain;
{

	TypedReference tr = __makeref(pyr);
	IntPtr ptr = **(IntPtr**)(&tr);
	string pointerDisplay = ptr.ToString();
	Console.Write("pyr:");
	Console.WriteLine(pointerDisplay);
	ptrMain = (ulong)ptr;
}
fixed (void* adress = &pyr.pImage)
{
	Console.Write("pImage:");
	Console.WriteLine((ulong)adress - ptrMain);
}

The output looks like this:

adressOffset.PNG

  • We are not sure what to make out of this though?
  • In C# should IppiPyramid be a class or a struct?

Our code is attached.

Regards Kristian

Thomas_Jensen1
Beginner
168 Views

Greetings Kristian,

You are on the right track. Very good work to visualize the offsets of each field in the struct, now you can see where the problem is.

My main development platform is Delphi/Pascal and there, I can declare a struct as a record, and in addition, as a packed record. A packed record is a struct in which the fields are positioned without "air", also less code-efficient, but often a useful feature; i.e., if saving a struct to file.

In your world, your C# starts at offset 8; this looks like a class, since a class can have a VMT in the beginning.

Your work will be: in C#, how can you define a raw struct, ending up with what you see in C++.

Thomas

 

Lars_A_
Beginner
168 Views

We tried changing from class to a struct, and the offsets are now identical to the C++ ones.

But we still have problem passing the structure to the functions that uses the ippiPyramid.

Conceptually, I don't really understand how it could work... for instance, we allocate:

IppiPyramid pyr;
IppiPyramid* pPyramidStruct = &pyr;

and initialize

ippStatus = ippiPyramidGetSize(&pyramidStructSize, &pyramidBufferSize, level, input.GetRoiSize(), rate);
HandleReturnValue(ippStatus);

in the C++ example from Intel the following happens

IppiPyramid *pPyrStruct    = NULL;
 
...

/* Initializes Gaussian structure for pyramids */
check_sts( status = ippiPyramidInit(&pPyrStruct, level, roiSize, rate, pPyrStrBuffer, pPyrBuffer) )

now from what I understand, the pyrimadStruct is 'really' allocated inside the pyramidInit, and then the pPyrStruct pointer is updated to point to the allocated memory...

This allocated memory is then unmanaged memory, how will .net manage that?

Is there something I am missing?

Reply