8262096: Vector API fails to work due to VectorShape initialization exception

Reviewed-by: psandoz, vlivanov
This commit is contained in:
Jie Fu 2021-03-02 23:29:50 +00:00
parent 93ffe6a6a2
commit 40bdf52e24
2 changed files with 51 additions and 23 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -60,7 +60,7 @@ public enum VectorShape {
/** Shape of length 512 bits */ /** Shape of length 512 bits */
S_512_BIT(512), S_512_BIT(512),
/** Shape of maximum length supported on the platform */ /** Shape of maximum length supported on the platform */
S_Max_BIT(VectorSupport.getMaxLaneCount(byte.class) * Byte.SIZE); S_Max_BIT(getMaxVectorBitSize(byte.class));
final int vectorBitSize; final int vectorBitSize;
final int vectorBitSizeLog2; final int vectorBitSizeLog2;
@ -211,10 +211,7 @@ public enum VectorShape {
/*package-private*/ /*package-private*/
static VectorShape largestShapeFor(Class<?> etype) { static VectorShape largestShapeFor(Class<?> etype) {
int laneCount = VectorSupport.getMaxLaneCount(etype); return VectorShape.forBitSize(getMaxVectorBitSize(etype));
int elementSize = LaneType.of(etype).elementSize;
int vectorBitSize = laneCount * elementSize;
return VectorShape.forBitSize(vectorBitSize);
} }
/** /**
@ -244,23 +241,32 @@ public enum VectorShape {
int prefBitSize = Integer.MAX_VALUE; int prefBitSize = Integer.MAX_VALUE;
for (LaneType type : LaneType.values()) { for (LaneType type : LaneType.values()) {
Class<?> etype = type.elementType; Class<?> etype = type.elementType;
int maxLaneCount = VectorSupport.getMaxLaneCount(etype); prefBitSize = Math.min(prefBitSize, getMaxVectorBitSize(etype));
int maxSize = type.elementSize * maxLaneCount;
// FIXME: Consider removing, since unlikely to occur on modern hardware
if (maxSize < Double.SIZE) {
String msg = "shape unavailable for lane type: " + etype.getName();
throw new UnsupportedOperationException(msg);
}
prefBitSize = Math.min(prefBitSize, maxSize);
} }
// If these assertions fail, we must reconsider our API portability assumptions. // If these assertions fail, we must reconsider our API portability assumptions.
assert(prefBitSize >= Double.SIZE && prefBitSize < Integer.MAX_VALUE / Long.SIZE); assert(prefBitSize >= Double.SIZE && prefBitSize < Integer.MAX_VALUE / Long.SIZE);
assert(prefBitSize/Byte.SIZE == VectorSupport.getMaxLaneCount(byte.class)); assert(prefBitSize == getMaxVectorBitSize(byte.class));
VectorShape shape = VectorShape.forBitSize(prefBitSize); VectorShape shape = VectorShape.forBitSize(prefBitSize);
PREFERRED_SHAPE = shape; PREFERRED_SHAPE = shape;
return shape; return shape;
} }
/**
* Returns the maximum vector bit size for a given element type.
*
* @param etype the element type.
* @return the maximum vector bit.
*/
/*package-private*/
static int getMaxVectorBitSize(Class<?> etype) {
// VectorSupport.getMaxLaneCount may return -1 if C2 is not enabled,
// or a value smaller than the S_64_BIT.vectorBitSize / elementSizeInBits if MaxVectorSize < 16
// If so default to S_64_BIT
int maxLaneCount = VectorSupport.getMaxLaneCount(etype);
int elementSizeInBits = LaneType.of(etype).elementSize;
return Math.max(maxLaneCount * elementSizeInBits, S_64_BIT.vectorBitSize);
}
private static @Stable VectorShape PREFERRED_SHAPE; private static @Stable VectorShape PREFERRED_SHAPE;
// ==== JROSE NAME CHANGES ==== // ==== JROSE NAME CHANGES ====

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,16 @@ import org.testng.annotations.Test;
* @run testng PreferredSpeciesTest * @run testng PreferredSpeciesTest
*/ */
/**
* @test
* @bug 8262096
* @requires vm.compiler2.enabled
* @summary Test the initialization of vector shapes
* @modules jdk.incubator.vector java.base/jdk.internal.vm.vector
* @run testng/othervm -XX:MaxVectorSize=8 PreferredSpeciesTest
* @run testng/othervm -XX:MaxVectorSize=4 PreferredSpeciesTest
*/
public class PreferredSpeciesTest { public class PreferredSpeciesTest {
@DataProvider @DataProvider
public static Object[][] classesProvider() { public static Object[][] classesProvider() {
@ -49,26 +59,35 @@ public class PreferredSpeciesTest {
@Test(dataProvider = "classesProvider") @Test(dataProvider = "classesProvider")
void testVectorLength(Class<?> c) { void testVectorLength(Class<?> c) {
VectorSpecies<?> species = null; VectorSpecies<?> species = null;
int elemSize = 0;
if (c == byte.class) { if (c == byte.class) {
species = ByteVector.SPECIES_PREFERRED; species = ByteVector.SPECIES_PREFERRED;
elemSize = Byte.SIZE;
} else if (c == short.class) { } else if (c == short.class) {
species = ShortVector.SPECIES_PREFERRED; species = ShortVector.SPECIES_PREFERRED;
elemSize = Short.SIZE;
} else if (c == int.class) { } else if (c == int.class) {
species = IntVector.SPECIES_PREFERRED; species = IntVector.SPECIES_PREFERRED;
elemSize = Integer.SIZE;
} else if (c == long.class) { } else if (c == long.class) {
species = LongVector.SPECIES_PREFERRED; species = LongVector.SPECIES_PREFERRED;
elemSize = Long.SIZE;
} else if (c == float.class) { } else if (c == float.class) {
species = FloatVector.SPECIES_PREFERRED; species = FloatVector.SPECIES_PREFERRED;
elemSize = Float.SIZE;
} else if (c == double.class) { } else if (c == double.class) {
species = DoubleVector.SPECIES_PREFERRED; species = DoubleVector.SPECIES_PREFERRED;
elemSize = Double.SIZE;
} else { } else {
throw new IllegalArgumentException("Bad vector element type: " + c.getName()); throw new IllegalArgumentException("Bad vector element type: " + c.getName());
} }
VectorShape shape = VectorShape.preferredShape(); VectorShape shape = VectorShape.preferredShape();
System.out.println("class = "+c+"; preferred shape"+shape+"; preferred species = "+species+"; maxSize="+VectorSupport.getMaxLaneCount(c)); int maxLaneCount = Math.max(VectorSupport.getMaxLaneCount(c), 64 / elemSize);
System.out.println("class = "+c+"; preferred shape"+shape+"; preferred species = "+species+"; maxSize="+maxLaneCount);
Assert.assertEquals(species.vectorShape(), shape); Assert.assertEquals(species.vectorShape(), shape);
Assert.assertEquals(species.length(), Math.min(species.length(), VectorSupport.getMaxLaneCount(c))); Assert.assertEquals(species.length(), Math.min(species.length(), maxLaneCount));
} }
@Test(dataProvider = "classesProvider") @Test(dataProvider = "classesProvider")
@ -96,12 +115,15 @@ public class PreferredSpeciesTest {
} else { } else {
throw new IllegalArgumentException("Bad vector element type: " + c.getName()); throw new IllegalArgumentException("Bad vector element type: " + c.getName());
} }
VectorSpecies largestSpecies = VectorSpecies.ofLargestShape(c);
VectorShape largestShape = VectorShape.forBitSize(VectorSupport.getMaxLaneCount(c) * elemSize);
System.out.println("class = "+c+"; largest species = "+largestSpecies+"; maxSize="+VectorSupport.getMaxLaneCount(c)); int maxLaneCount = Math.max(VectorSupport.getMaxLaneCount(c), 64 / elemSize);
VectorSpecies largestSpecies = VectorSpecies.ofLargestShape(c);
VectorShape largestShape = VectorShape.forBitSize(maxLaneCount * elemSize);
System.out.println("class = "+c+"; largest species = "+largestSpecies+"; maxSize="+maxLaneCount);
Assert.assertEquals(largestSpecies.vectorShape(), largestShape); Assert.assertEquals(largestSpecies.vectorShape(), largestShape);
Assert.assertEquals(largestSpecies.length(), VectorSupport.getMaxLaneCount(c)); Assert.assertEquals(largestSpecies.length(), maxLaneCount);
Assert.assertEquals(largestSpecies.length(), Math.max(species.length(), VectorSupport.getMaxLaneCount(c))); Assert.assertEquals(largestSpecies.length(), Math.max(species.length(), maxLaneCount));
} }
} }