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

Unsatisfied link error with ippi-5.1.dll when using JNI

cyndy_koobs
Beginner
706 Views

I have spent quite a bit of time trying to learn how to use a some functions in the IP library (5.1) from my java application. I finally reduced it down to one function to simplify things so I could reduce the amount if places I could make mistakes. What I have done is created a java wrapper around the one ip library function call 'ippiFilter_16s_AC4R'. I used the javah.exe tool to create the native method header file. I used the sample native C code downloaded from the intel site (w_ipp-sample-java_p_5.1.006.zip) - jipp_ip.c to create a dll. I had a thousand problems a first, unwittingly trying to compile as a C++ programin VS 2005; after "fixing" it to compile as a C++ program I used "Depends" and Anywhere PE Viewer to make sure my function was being exported, etc, which it was. And it was correctly "depending" upon ippi-5.1.dll which correctly depended upon ippicore.dll which depends upon libguide40.dll. Whew!

I checked my path variable to make sure that it included the dependent dlls directory (C:Program FilesIntelIPP5.1ia32in) which it did. So, everything looked great. My java app has no problem loading my wrapper dll; when I try and call the one native function, I get the infamous "java.lang.UnsatisfiedLinkError: ippiFilter_16s_AC4R"error. I have tried everything I know of;from copying the dependentdlls into the same directory as my wrapper dll to recompilingthe native code as a 'C' program since I noticed that the function was being "decorated" and I thought that was causing a problem.

Whatdid finally catch my eye was something that I saw in both "Depends" and the PE Viewer - the ''ippiFilter_16s_AC4R' is shown with a 'Hint' value of 1162 in the ippi-5.1.dll parent import function list view but the actual Ordinal value is 1163. I'm probably grasping at strawsbut I'm just plain out of ideas after banging my head on the wall for several days now.

If anyone has any ideas on what I am doing wrong or missing, I would love to hear them.

Thanks, Cyndy

0 Kudos
10 Replies
Vladimir_Dudnik
Employee
706 Views

Hello Cyndy,

it isa bit not clear regarding IPP java integration sample. Were you able to build IPP java sample? Does it work as expected?

Regards,
Vladimir

0 Kudos
cyndy_koobs
Beginner
706 Views

Vladimir - I was able to build the IPP java sample and it runs just like I would expect. What I have done since yesterday is to toss the JNI path I was on and just include the .java sample files as part of my application since I'm guessing that was the intent of them anyway. I just call the ipp native functions that are in ip.javausing "jipp.ip.ippiFilter_16s_AC4R(args1, arg2....)" as an example. I built the .c sample files into their respective .dlls and load the one that I need (ie, jippi.dll). When I call the native function, it loads the jippi dll which then finds the ippcore-5.1 dll, and so on. So far, so good.

I am crashing the JVM when I make the native function call above:

#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x497b5e20, pid=3484, tid=164
#
# Java VM: Java HotSpot Client VM (1.5.0_10-b03 mixed mode)
# Problematic frame:
# C [ippit7-5.1.dll+0x3a5e20]
#

but I think this has more to do perhaps with me passing bad parameters to the function. If you have any pointers in determining what is going wrong, I'd like to hear them.

thanks for the reply and interest,

Cyndy

0 Kudos
Vladimir_Dudnik
Employee
706 Views

Cyndy

Did you notice from IPP manual that ippiFilter function assumes you provide appropriate border around the image?

Regards,
Vladimir

0 Kudos
cyndy_koobs
Beginner
706 Views

I did but I then again I didn't. I now have added that to my code but I am having a problem with the step size when calling the ippiFilter_16s_C1R function. I have been combing the forum for info from others who are using the various filtering functions. So, I'm a little farther but still not there yet.

thx, Cyndy

0 Kudos
Vladimir_Dudnik
Employee
706 Views

Step is measured as a number of bytes between adjacent image rows. For 16-bit images it isequal to width*2 + number of bytes to pad line (if any)

See IPP manual for more details.

Regards,
Vladimir

0 Kudos
cyndy_koobs
Beginner
706 Views

I still seem to be thrashing around with this step business even though I could probably quote the IPP manual by now. Trust me, I have read, re-read various parts of the manual probably 50 times by now :-). Let me give you an example (this is where I am at the moment):

Image size: 1024 x 1024
Filter size: 3x3 with anchor at (1,1)
Source and Target arrays are shorts (16 bits in Java)

I allocate the target array: asReturn = new short[(iWidth+2) * (iHeight+2)];
the +2 to accomodate the 1 pixel pad around the original image

for the call to ippiFilter_16s_C1R ( short pSrc[], int srcStep, short pDst[], int dstStep, IppiSize dstRoiSize___str_1, int pKernel[], IppiSize kernelSize___str_2, IppiPoint anchor___str_3, int divisor);

short pSource[] = short[] asSourceArray[(1024 * 1024)]
int srcStep = 1024 * 2
short pDst[] = asReturn (target array from above)
int dstStep = (1024 * 2) + 4
IppiSize dstRoiSize = IppiSize(1024, 1024)
int pKernel[] = 3 x 3 integer array
IppiSize kernelSize = IppiSize(3,3)
IppiPoint anchor = IppiPoint(1,1)
int divisor = 1

I go from crashing the JVM to the error "Step value is not valid", depending on how I tweak the parameters trying to get it to work. I have been struggling with this for quite a few days. Any help or pointers is greatly appreciated.

thx, Cyndy

0 Kudos
Vladimir_Dudnik
Employee
706 Views

Hi Cyndy

you need to provide border pixels in source image not in destination image.

Regards,
Vladimir

0 Kudos
cyndy_koobs
Beginner
706 Views

I didn't add the previous step (call to CopyReplicateBorder) which may have caused some confusion. Here is the previous step before the call to IppiFilter again assuming 3x3 Filter Size with (1,1) anchor:

ok = ip.ippiCopyReplicateBorder_16s_C1R(asSourceArray, iXDim*2, new IppiSize(iXDim, iYDim), asTempArray, dstStep, dstRoiSize, 1, 1);

where:
asSourceArray = short array of iXDim * iYDim size
iXDim and iYDim are the width and height of image to be filtered
srcStep = iXDim * 2
srcRoiSize = IppiSize(iXDim, iYDim)
dstStep = (iXDim * 2) + 4
dstRoiSize = IppiSize(iXDim + (getFilterWidth()-1), iYDim + (getFilterHeight()-1)
asTempArray = short array of (iXDim + 2) * (iYDim + 2) size

this comes back with ok = 0. so then, the call to Fitler:

ok = ip.ippiFilter_16s_C1R(asTempArray, dstStep, asTargetArray, (iXDim*2), new IppiSize(iXDim, iYDim), maiFilter, miKernelSize, new IppiPoint(1,1), getDivisor());

where:
asTempArray = "new" source array from previous CopyReplicateBorder (was the destination array in the previous step)
srcStep (dstStep from previous step) = (iXDim * 2) + 4
asTargetArray = short array of iXDim * iYDim size
dstStep = iXDim*2
dstRoiSize = IppiSize(iXDim, iYDim)
maiFilter = integer array of filter coefficients
miKernelSize = 3
anchor = IppiPoint(1,1)
divisor = 1

so, now I HAVE provided border pixels in the source image being filtered. So, what am I missing??

thanks for your help while I stumble through this,
Cyndy

0 Kudos
Vladimir_Dudnik
Employee
706 Views

Cyndy,

please look at comments from our expert:

Image size: 1024 x 1024
Source and Target arrays are shorts (16 bits in Java)

I allocate the target array: asReturn = new short[(iWidth+2) * (iHeight+2)];

must be for Src the +2 to accomodate the 1 pixel pad around the original image

for the call to ippiFilter_16s_C1R ( short pSrc[], int srcStep, short pDst[], int dstStep, IppiSize dstRoiSize___str_1, int pKernel[], IppiSize kernelSize___str_2, IppiPoint anchor___str_3, int divisor);

short pSource[] = short[] asSourceArray[(1024 * 1024)]
int srcStep = 1024 * 2 must be dstStep
short pDst[] = asReturn (target array from above)
int dstStep = (1024 * 2) + 4

must be srcStep
IppiSize dstRoiSize = IppiSize(1024, 1024)

SOURCE:

first point

?

KKKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
KKK***************************************x
KKK***************************************x
x*****************************************x
x*****************************************x
x*****************************************x
x*****************************************x
x*****************************************x
x***************************************KKK
x***************************************KKK
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKKK
^
|
Last point

DESTINATION:
*****************************************
*****************************************
*****************************************
*****************************************
*****************************************
*****************************************
*****************************************
*****************************************
*****************************************

x border pixels
* - image (ROI) pixels their number is equal to the number of output points
K - ker nel

So if anybody wants to process 1024-wide image with 3-wide kernel, he needs allocation of 1024+2 points for rows as he should provide border pixels for roi=1024 so it is visible from the picture that srcStep = (1024+2)*sizeof(point), dstStep=1024*sizeof(point).

Regards,
Vladimir

0 Kudos
pszagfa
Beginner
706 Views

Cyndy -

I had a similar problem with a ippResize function. If you look carefully at jipp_ip.c you might see that whoever used the "javah" to generate the .c and .h files has caused digits to be placed in the function prototype. Note the "_116" and "_1AC" in the name.

..Filter32f_116s_1AC4R

I think this is because the names are so similar, the autogeneration inserts the "1" digits. For whatever reason, JNI is not able to sort this out at runtime.

Try renaming the function in the .h and .c file to something totally unique like "MyFilter" and make sure to change the call on the java side. This worked for me.

Paul

0 Kudos
Reply