Webrev for throwing some exceptions from HSAIL
Christian Thalinger
christian.thalinger at oracle.com
Tue Dec 10 11:27:52 PST 2013
On Dec 10, 2013, at 9:31 AM, Gilles Duboscq <duboscq at ssw.jku.at> wrote:
> On Tue, Dec 10, 2013 at 5:41 PM, Tom Deneau <tom.deneau at amd.com> wrote:
>
>> Gilles --
>>
>> Some comments below
>>
>> -- Tom
>>
>>> -----Original Message-----
>>> From: graal-dev-bounces at openjdk.java.net [mailto:graal-dev-
>>> bounces at openjdk.java.net] On Behalf Of Gilles Duboscq
>>> Sent: Tuesday, December 10, 2013 9:05 AM
>>> To: Doug Simon
>>> Cc: Caspole, Eric; graal-dev at openjdk.java.net
>>> Subject: Re: Webrev for throwing some exceptions from HSAIL
>>>
>>> Hi Eric,
>>>
>>> The deoptimization mechanism and the exception mechanism are two
>>> completely different things.
>>> When a deoptimization happens, your only choice is to restart execution
>> in the interpreter.
>>>
>>> To do so, the deoptimization points are decorated with LIRFrameState in
>> the
>>> backend. This LIRFrameState gives you information that allow to rebuild
>> the
>>> interpreter frames. For each frame you have a method, a bci, the stack
>> and
>>> local values and the owned monitors.
>>>
>>
>> Yes, this was indeed a baby step.
>>
>> We realized with graal's policy of providing the framestate back at the
>> last
>> side-effecting bytecode means we don't get even get the exact bci on
>> deoptimizations.
>>
>> Our plan for the next phase is to provide enough information and
>> actually build up the correct interpreter frames back and restart
>> execution in the interpreter back on the host side.
>>
>
> OK, but i wonder what are the semantics there since the data has already
> been partially modified by the other kernel workitems which didn't
> deoptimize.
> In general when we think about parallelization we consider that it's only
> safe to parallelize sections where there is no deoptimization since this
> means we are guaranteed not to deopt to a state of the data that is invalid
> for the interpreter.
> I suppose in the case of streams you are relying on the relaxed semantics
> of parallel streams.
> How are you going to ensure that all element are processed in the case of
> deoptimization?
Correct. This is something we have talked about already in the Sumatra scope. Before we can throw exceptions in GPUs we have to have some kind of work item logic. I think trying to throw exceptions without having properly set up work items and a way to undo or record which items have already been processed is premature and not something we want.
We need to resume talking about work items and start to implement it.
>
>
>>
>>
>>> Once a deoptimization happened you can not just throw an exception
>>> because the deoptimization informations will not tell you where the
>> problem
>>> actually happened, it is also not guaranteed that you have a meaningful
>>> exception to throw corresponding to the deoptimization reason and it is
>>> not even guaranteed that there actually was any problem at all!
>>>
>>
>> Is this true even when the DeoptimizationReason is something explicit like
>> BoundsCheckException?
>> (realizing that all the problems with exact bci mentioned above still hold)
>>
>
> Yes, the compiler does not apply the exception semantics to the
> deoptimizations. We use deoptimization for exceptions (amongst other
> things) because it make optimization easier since we don't need to respect
> exception semantics for deoptimization and we just let the interpreter
> figure out if and where the exception should be thrown.
>
>
>>
>>> I think this was the reason you were using OptimisticOptimizations.NONE
>>> previously which should get rid of most deoptimizations and get
>>> exceptions instead. But i suspect it was not really used everywhere
>> which could
>>> cause problems such as the "not compiled exception handler" deopt reason.
>>> Maybe we should try to have a look at those things together over Skype
>>> (my username is gilwooden) or something similar.
>>>
>>
>> I'm not really sure what affect OptimisticOptimizations.NONE or ALL had on
>> any of this.
>> With both NONE and ALL, we definitely still got both DeoptNodes and
>> UnwindNodes. (The
>> UnwindNodes came from profiling information I think).
>> We switched to ALL in the latest just to make it more similar to what the
>> AMD64 backend
>> was doing.
>>
>
> If you really implement deoptimization then ALL is the way to go.
> But i thought you would prefer unwind nodes which tell you that an
> exception actually needs to be thrown.
> The fact that you still got a mixture of deopt and unwind nodes probably
> means that there was a problem around inlining where the root method and
> the inlinined methods didn't use the same policy.
>
>
>>
>>> -Gilles
>>>
>>>
>>>
>>> On Tue, Dec 10, 2013 at 1:03 PM, Doug Simon <doug.simon at oracle.com>
>>> wrote:
>>>
>>>> Hi Eric,
>>>>
>>>> Apart from the Eclipse errors and warnings (see below), the Java code
>>>> looks ok.
>>>>
>>>> gpu_hsail.cpp:
>>>>
>>>> inline void init() {
>>>>
>>>> Why a separate init() function for HSAILKernelException? Seems like an
>>>> inline constructor would do the same thing.
>>>>
>>>> thread->set_gpu_exception_method(mh());
>>>>
>>>> If the exception happens in an inlined method, then mh() is the wrong
>>>> value here (and bci will be wrong as well).
>>>>
>>>> gpu_hsail.hpp:
>>>>
>>>> static bool execute_kernel_void_1d(address kernel, int dimX, jobject
>>>> args, methodHandle mh, TRAPS);
>>>>
>>>> Why is the mh parameter no longer passed by reference?
>>>>
>>>> -Doug
>>>>
>>>> Description Resource Path Location Type
>>>> The import com.oracle.graal.api.code is never used
>>>> HSAILControlFlow.java
>>>> /com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail line
>>> 36
>>>> Java Problem
>>>> The value of the field HSAILHotSpotLoweringProvider.host is not used
>>>> HSAILHotSpotLoweringProvider.java
>>>> /com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail
>>>> line 39 Java Problem
>>>> 'abstract' modifier out of order with the JLS suggestions.
>>>> HSAILHotSpotLoweringProvider.java
>>>> /com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail
>>>> line 41 Checkstyle Problem
>>>> The value of the local variable bci is not used
>>>> HSAILHotSpotLIRGenerator.java
>>>> /com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail
>>>> line 222 Java Problem
>>>> Name '_y' must match pattern '^[a-z][a-zA-Z0-9]*$'.
>>> ClassCastTest.java
>>>>
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 42 Checkstyle Problem
>>>> Line matches the illegal pattern 'System\.(out|err)\.print'.
>>>> ClassCastTest.java
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 73 Checkstyle Problem
>>>> The import java.lang.reflect is never used HSAILAssembler.java
>>>> /com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail line
>>> 26
>>>> Java Problem
>>>> The import com.oracle.graal.debug.internal is never used
>>>> HSAILCompilationResult.java
>>>> /com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail
>>>> line 37 Java Problem
>>>> First sentence should end with a period. ClassCastTest.java
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 14 Checkstyle Problem
>>>> Name '_x' must match pattern '^[a-z][a-zA-Z0-9]*$'.
>>> ClassCastTest.java
>>>>
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 27 Checkstyle Problem
>>>> Name '_y' must match pattern '^[a-z][a-zA-Z0-9]*$'.
>>> ClassCastTest.java
>>>>
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 27 Checkstyle Problem
>>>> Name '_x' must match pattern '^[a-z][a-zA-Z0-9]*$'.
>>> ClassCastTest.java
>>>>
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 42 Checkstyle Problem
>>>> The import org.junit.Assert.assertTrue is never used
>>> ClassCastTest.java
>>>>
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 11 Java Problem
>>>> Line does not match expected header line of ' \* Copyright \(c\)
>>>> (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All
>>> rights
>>>> reserved.'. ClassCastTest.java
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 2 Checkstyle Problem
>>>> First sentence should end with a period. BoundsCheckTest.java
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 29 Checkstyle Problem
>>>> The import java.util.Arrays is never used ClassCastTest.java
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 9 Java Problem
>>>> Line matches the illegal pattern 'System\.(out|err)\.print'.
>>>> BoundsCheckTest.java
>>>>
>>> /com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsai
>>> l/test
>>>> line 67 Checkstyle Problem
>>>>
>>>>
>>>>
>>>> On Dec 10, 2013, at 1:31 AM, Caspole, Eric <Eric.Caspole at amd.com>
>>> wrote:
>>>>
>>>>> Hi everybody,
>>>>> Tom and I came up with our first baby steps of throwing exceptions
>>> from
>>>> HSAIL kernels back into "regular" java. This is for the context of
>>> running
>>>> as a parallel stream such as a parallel().forEach(). This works such
>>> that
>>>> the first kernel workitem to set an atomic after detecting a problem
>>> "wins"
>>>> to report the exception back to java. The kernel workitems that
>>> detect a
>>>> problem return early even if they lose to set the flag, and the others
>>> run
>>>> on normally. This is about the same as you get with CPU parallel
>>> streams.
>>>>>
>>>>> http://cr.openjdk.java.net/~ecaspole/hsail_exceptions/<
>>>> http://cr.openjdk.java.net/%7Eecaspole/hsail_exceptions/>
>>>>>
>>>>> We can now detect ArrayIndexOutOfBounds and ClassCastExceptions via
>>>> explicit checks in the HSAIL code, and return a deoptimization reason
>>> to
>>>> the CPU side. In the JVM kernel launch code, we check for these
>>> exceptions,
>>>> then save the method, reason and bci in the thread, then throw using
>>> the
>>>> THROW/CHECK mechanism from C++ back to java. When the thread later
>>> gets to
>>>> fillInStackTrace, it uses the saved info in the thread to add the
>>> kernel
>>>> lambda method as the top frame in the stack trace.
>>>>>
>>>>> Let us know what you think.
>>>>> Thanks,
>>>>> Eric
More information about the graal-dev
mailing list