[vector] ClassCastException in C2 with Mask rebracketing

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Thu Feb 15 17:50:46 UTC 2018


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