[vector] ClassCastException in C2 with Mask rebracketing

Adam Pocock adam.pocock at oracle.com
Thu Feb 15 18:48:46 UTC 2018


Hi Vladimir,

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.

Any idea when the generalized intrinsics will land?

Thanks,

Adam

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
>>

-- 
Adam Pocock
Principal Member of Technical Staff
Machine Learning Research Group
Oracle Labs, Burlington, MA



More information about the panama-dev mailing list