[vector] ClassCastException in C2 with Mask rebracketing
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Fri Feb 16 23:14:19 UTC 2018
> Yep, the problem went away with "-XX:-UseVectorApiIntrinsics". My vector
> shapes are unchanging though, everything is fixed at S256Bit as that's
> what I've got on my desktop. I thought the rebracket for things like
> masks were supposed to be optimised out, as a Float 256 Mask is the same
> bit string as an Integer 256 Mask.
Yes, rebracketing turns into an no-op when boxes go away. Otherwise, the
operand has to be boxed/reboxed.
> Any idea when the generalized intrinsics will land?
The first batch is already there, but no exact dates when the rest follow.
Best regards,
Vladimir Ivanov
> On 15/02/18 12:50, Vladimir Ivanov wrote:
>> Adam,
>>
>> Thanks for the report.
>>
>> I hit a similar problem with vectors and tracked it down to a changes
>> in Parse::do_call (disabled C->optimize_virtual_call() on vectors).
>> The bug is devirtualized non-inlined call can float before the type
>> check it depends on. It leads to a wrong method being called when type
>> check fails and manifests as a CCE in interpreter after deoptimization
>> (due to failed type check). It usually happens when vector shapes
>> change at runtime: C2 produces a method specialized for some
>> particular vector shape and then the first time the method observes a
>> different vector shape.
>>
>> The problem is specific to original intrinsics which rely on some
>> inlining tweaks (like in Parse::do_call) to make intrinsification more
>> reliable.
>>
>> I suggest you to try -XX:-UseVectorApiIntrinsics and check whether the
>> problem goes away.
>>
>> Generalized intrinsics will be used (where available) and they
>> shouldn't be prone to that problem (relevant code path in
>> Parse::do_call is used only for original intrinsics).
>>
>> Unfortunately, not all operations are covered by generalized
>> intrinsics yet. So, generated code quality may suffer as well.
>>
>> I didn't bother fixing the bug because the plan is to replace original
>> intrinsics with generalized ones and remove inlining tweaks.
>>
>> Best regards,
>> Vladimir Ivanov
>>
>> On 2/15/18 8:11 PM, Adam Pocock wrote:
>>> Hi,
>>>
>>> I've been working on more involved machine learning demos on top of
>>> the vector API. As part of that I built a binary search demo that
>>> searches n vectors at the same time using an n-wide SIMD. This keeps
>>> rebracketing the Mask from Integer to Float and back again as it
>>> searches through the arrays.
>>>
>>> Paul Sandoz has been helping me debug it, and when this code is run
>>> using C1 or lower it executes fine, but when it's recompiled with C2
>>> (triggered by executing binarySearchCDF in a loop with the same
>>> arguments and a print statement, takes about 300-500 iterations) it
>>> throws a ClassCastException (stack trace below). Turning off C2 with
>>> "-XX:TieredStopAtLevel=3" allows the loop to complete.
>>>
>>> Code:
>>>
>>> public static <S extends Vector.Shape> IntVector<S>
>>> binarySearchCDF(IntSpecies<S> spec, float[][] input, int fromIndex,
>>> int toIndex, FloatVector<S> key) {
>>> IntVector<S> low = spec.broadcast(fromIndex);
>>> IntVector<S> high = spec.broadcast(toIndex - 1);
>>> IntVector<S> one = spec.broadcast(1);
>>>
>>> Mask<Float,S> mask = key.species().trueMask();
>>>
>>> int[] indicesBuffer = new int[key.length()];
>>> float[] valuesBuffer = new float[key.length()];
>>>
>>> while (mask.anyTrue()) {
>>> IntVector<S> mid =
>>> low.add(high,mask.rebracket(Integer.class)).shiftR(1);
>>> mid.intoArray(indicesBuffer,0);
>>> for (int i = 0; i < valuesBuffer.length; i++) {
>>> valuesBuffer[i] = input[i][indicesBuffer[i]];
>>> }
>>> FloatVector<S> values =
>>> key.species().fromArray(valuesBuffer,0);
>>>
>>> Mask<Integer,S> lessThanKey =
>>> values.lessThan(key).and(mask).rebracket(Integer.class);
>>> low = low.blend(mid.add(one),lessThanKey);
>>> Mask<Integer,S> greaterThanKey =
>>> values.greaterThan(key).and(mask).rebracket(Integer.class);
>>> high = high.blend(mid.sub(one),greaterThanKey);
>>> Mask<Integer,S> equalsKey =
>>> values.equal(key).and(mask).rebracket(Integer.class);
>>> low = low.blend(mid,equalsKey);
>>> mask = mask.and(equalsKey.rebracket(Float.class).not());
>>> mask = mask.and(low.lessThan(high).rebracket(Float.class));
>>> }
>>>
>>> return low;
>>> }
>>>
>>> Stack trace:
>>>
>>> Caused by: java.lang.ClassCastException:
>>> jdk.incubator.vector/jdk.incubator.vector.Int256Vector$Int256Mask
>>> cannot be cast to
>>> jdk.incubator.vector/jdk.incubator.vector.Float256Vector$Float256Mask
>>> at
>>> jdk.incubator.vector/jdk.incubator.vector.Float256Vector$Float256Mask.and(Float256Vector.java:488)
>>>
>>> at
>>> jdk.incubator.vector/jdk.incubator.vector.Float256Vector$Float256Mask.and(Float256Vector.java:430)
>>>
>>> at
>>> mlrg.topicmodel/com.oracle.labs.mlrg.topicmodel.util.vector.BinarySearch.binarySearchCDF(BinarySearch.java:37)
>>>
>>>
>>> Line 37 is:
>>> mask = mask.and(equalsKey.rebracket(Float.class).not());
>>>
>>> Thanks,
>>>
>>> Adam
>>>
>
More information about the panama-dev
mailing list