Saalma / aparapi

Automatically exported from code.google.com/p/aparapi
Other
0 stars 0 forks source link

OpenCL compile fails #34

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I'm trying to leverage OpenCL to calculate the Levenstein difference between 
two strings. I've altered the algorithm so only primitives and 1D arrays are 
used, and no char primitive is used, but I always get:

Feb 06, 2012 8:32:45 PM com.amd.aparapi.KernelRunner warnFallBackAndExecute
WARNING: Reverting to Java Thread Pool (JTP) for class 
org.quelea.SongDuplicateChecker$1: OpenCL compile failed

I've attached the code - I'm not sure if this is a bug or something I'm doing 
wrongly?

Original issue reported on code.google.com by berry...@gmail.com on 6 Feb 2012 at 8:35

Attachments:

GoogleCodeExporter commented 8 years ago
Interestingly, if you comment out these lines:

if(s_i == t_j) {
   cost = 0;
}
else {
    cost = 1;
}

...and then just initialise cost to 0 on its declaration, the code will compile 
and run (though obviously won't generate the correct result.) It seems to be 
the if statement causing the error which seems a bit odd?

Original comment by berry...@gmail.com on 6 Feb 2012 at 8:55

GoogleCodeExporter commented 8 years ago
I found a workaround in that the equivalent ternary statement works fine. That 
surprises me - I assumed that they'd compile the same way, is there a subtle 
difference?

Original comment by berry...@gmail.com on 6 Feb 2012 at 9:10

GoogleCodeExporter commented 8 years ago
Sorry, forgot to include the equivalent ternary statement above:

cost = s_i == t_j ? 0 : 1;

Original comment by berry...@gmail.com on 6 Feb 2012 at 9:10

GoogleCodeExporter commented 8 years ago
Actually, I get the following error:

clBuildProgram failed
************************************************
<program source>:45:70: error: use of undeclared identifier 'cost'
             int c = this->val$d[((firstSize * (i - 1)) + (j - 1))] + cost;
                                                                      ^

************************************************

Feb 6, 2012 12:49:52 PM com.amd.aparapi.KernelRunner warnFallBackAndExecute
WARNING: Reverting to Java Thread Pool (JTP) for class gov.pnnl.ia.gpu.test$1: 
OpenCL compile failed

Original comment by ryan.lam...@gmail.com on 6 Feb 2012 at 9:32

GoogleCodeExporter commented 8 years ago
Which makes sense since you cannot declare variables without initializing them 
first...we've run into this same limitation with our kernels as well.

FYI, if you use the Trunk code char support has been added :)

Original comment by ryan.lam...@gmail.com on 6 Feb 2012 at 9:33

GoogleCodeExporter commented 8 years ago
Ah I see! That does make a lot of sense. And thanks for the tip about the char 
support - don't suppose 2D arrays is in there as well?

Oh and how do you get the specific OpenCL error displayed? Is it an option I 
need to add? I'm just getting the "reverting to JTP" warning.

Original comment by berry...@gmail.com on 6 Feb 2012 at 9:38

GoogleCodeExporter commented 8 years ago
Thanks for reporting this. 

So for me when I initialize cost to 0 (line 25) I don't have to comment out the 
two lines or switch to the ternary form. 

So on line 25 (of your code) I just swapped 'int cost=0;' for 'int cost;'

Can you try this and just confirm. 

If you still see a compile error try setting 
-Dcom.amd.aparapi.enableShowGeneratedOpenCL=true this should dump the generated 
opencl and might help us diagnose. 

Are you using eclipse's java compiler or Oracles?

There is a subtle difference parsing the ternary form of "a = b?c:d;" instead 
of "if (b)c;else d; but I too would expect to have the same issue parsing the 
bytecodes. 

Essentially the stack is offset (by both conditional paths) after executing 
"b?c:d" wheres a normal if()..else.. we don't expect the stack to be effected 
by following either path.

The problem stems from not being able to determine the scope of the 'cost' 
variable unless we initialize it. 

Gary

Original comment by frost.g...@gmail.com on 6 Feb 2012 at 9:39

GoogleCodeExporter commented 8 years ago
Thanks for the quick feedback guys.

Gary, yup I can confirm that works if I change it as you describe (Oracle 
JDK7.) It does seem to be a scoping problem - I'm not a compiler guy at all, 
but seem to remember hearing a talk somewhere that explained determining the 
scope in the Java compiler for these sorts of cases was a decidedly complex 
problem!

Original comment by berry...@gmail.com on 6 Feb 2012 at 9:50

GoogleCodeExporter commented 8 years ago
On a related point, in the attached code I've tried to take the working example 
and apply it to work with a number of strings (so it has a practical use.) 
However, I end up with a generic NullPointerException rather than a specific 
OpenCL compile error:

Exception in thread "main" java.lang.NullPointerException
    at com.amd.aparapi.KernelWriter.convertType(KernelWriter.java:111)
    at com.amd.aparapi.KernelWriter.write(KernelWriter.java:260)
    at com.amd.aparapi.KernelRunner.execute(KernelRunner.java:1197)
    at com.amd.aparapi.Kernel.execute(Kernel.java:1523)
    at com.amd.aparapi.Kernel.execute(Kernel.java:1469)
    at com.amd.aparapi.Kernel.execute(Kernel.java:1454)
    at org.quelea.utils.opencl.LevenshteinDistance.compare(LevenshteinDistance.java:104)
    at org.quelea.utils.opencl.LevenshteinDistance.main(LevenshteinDistance.java:32)
Java Result: 1

I suspect this may be because there's 2D arrays involved, in the following line:

result[getGlobalId()] = ld(s1Arr[getGlobalId()], s2Arr[getGlobalId()], 
s1Length, s2Length);

...s1Arr and s2Arr are 2D arrays of integers. I "hoped" it'd just count as a 1D 
array since all I'm doing is retrieving the 1D array from the 2D array based on 
the global ID and using that, but is this not allowed either and hence is 
what's causing the issue?

Original comment by berry...@gmail.com on 6 Feb 2012 at 9:56

Attachments:

GoogleCodeExporter commented 8 years ago
Two dimensional arrays (well, arrays of arrays) will throw a NPE in the Aparapi 
code.

See http://code.google.com/p/aparapi/issues/detail?id=10

Original comment by ryan.lam...@gmail.com on 6 Feb 2012 at 10:05

GoogleCodeExporter commented 8 years ago
Sadly no we just can't access 2D arrays.

The NPE is actually bad coding on my behalf,  this code is only expecting so 
see primitives or single dimension arrays of primitives and should be more 
defensive.  I think it has been fixed in the main branch (it is time for me to 
create a new set of binary builds isn't it!) or at least it will generated an 
Aparapi exception complaining that we can't access 2D arrays.

As Ryan indicated (he is clearly faster than me at typing ;)) I think you are 
hitting issue #10.  http://code.google.com/p/aparapi/issues/detail?id=10

Moving 2D arrays to the GPU would be expensive due to the layout of Java arrays.

Although I think I know *how* to do it if someone wanted to try to implement 
it....

Gary

Original comment by frost.g...@gmail.com on 6 Feb 2012 at 10:15

GoogleCodeExporter commented 8 years ago
Just an FYI, when I receive the error above (uninitialized method local 
variables) and OpenCL dies, Aparapi never returns or fails over to JTP mode. 
Should I file a new bug on that condition and use the attachment on this ticket 
as the test case?

Original comment by ryan.lam...@gmail.com on 8 Feb 2012 at 7:47

GoogleCodeExporter commented 8 years ago
I also get that behaviour - it just seems to hang rather than falling over to a 
thread pool.

Original comment by berry...@gmail.com on 8 Feb 2012 at 9:40

GoogleCodeExporter commented 8 years ago

Original comment by frost.g...@gmail.com on 14 Feb 2012 at 5:29

GoogleCodeExporter commented 8 years ago
I just got around to trying to fix this.  I thought I had wrapped all tests in 
ClassParseExceptions, but this is not detected until OpenCL write time which is 
a shock.  I think this should be detected earlier.  

Worse case I will defend the KernelRunner from any exception and fall back.  I 
will also see if this particular error can't be detected earlier.  I need to 
create a junit case for this. 

Thanks 'berry120' 

Original comment by frost.g...@gmail.com on 20 Feb 2012 at 9:29

GoogleCodeExporter commented 8 years ago
I made the changes suggested above.  Now any exception encountered at codegen 
time is converted to CodeGenException so should revert to JTP.  Fix is in SVN 
R#287

Original comment by frost.g...@gmail.com on 20 Feb 2012 at 9:41