Skip to content

Commit ccf4b19

Browse files
committed
This allows VectorUtilProvider tests to be executed although hardware may not fully support vectorization or if C2 is not enabled (#12376)
1 parent d3dcbfd commit ccf4b19

File tree

4 files changed

+21
-15
lines changed

4 files changed

+21
-15
lines changed

lucene/core/src/java/org/apache/lucene/util/VectorUtil.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
/** Utilities for computations with numeric arrays */
2121
public final class VectorUtil {
2222

23-
// visible for testing
24-
static final VectorUtilProvider PROVIDER = VectorUtilProvider.lookup();
23+
private static final VectorUtilProvider PROVIDER = VectorUtilProvider.lookup(false);
2524

2625
private VectorUtil() {}
2726

lucene/core/src/java/org/apache/lucene/util/VectorUtilProvider.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ interface VectorUtilProvider {
5454
/** The minimal version of Java that has the bugfix for JDK-8301190. */
5555
static final Version VERSION_JDK8301190_FIXED = Version.parse("20.0.2");
5656

57-
static VectorUtilProvider lookup() {
57+
static VectorUtilProvider lookup(boolean testMode) {
5858
final int runtimeVersion = Runtime.version().feature();
5959
if (runtimeVersion >= 20 && runtimeVersion <= 21) {
6060
// is locale sane (only buggy in Java 20)
@@ -71,7 +71,7 @@ static VectorUtilProvider lookup() {
7171
"Java vector incubator module is not readable. For optimal vector performance, pass '--add-modules jdk.incubator.vector' to enable Vector API.");
7272
return new VectorUtilDefaultProvider();
7373
}
74-
if (isClientVM()) {
74+
if (!testMode && isClientVM()) {
7575
LOG.warning("C2 compiler is disabled; Java vector incubator API can't be enabled");
7676
return new VectorUtilDefaultProvider();
7777
}
@@ -80,9 +80,10 @@ static VectorUtilProvider lookup() {
8080
// have private access through the lookup:
8181
final var lookup = MethodHandles.lookup();
8282
final var cls = lookup.findClass("org.apache.lucene.util.VectorUtilPanamaProvider");
83-
final var constr = lookup.findConstructor(cls, MethodType.methodType(void.class));
83+
final var constr =
84+
lookup.findConstructor(cls, MethodType.methodType(void.class, boolean.class));
8485
try {
85-
return (VectorUtilProvider) constr.invoke();
86+
return (VectorUtilProvider) constr.invoke(testMode);
8687
} catch (UnsupportedOperationException uoe) {
8788
// not supported because preferred vector size too small or similar
8889
LOG.warning("Java vector incubator API was not enabled. " + uoe.getMessage());

lucene/core/src/java20/org/apache/lucene/util/VectorUtilPanamaProvider.java

+14-8
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ final class VectorUtilPanamaProvider implements VectorUtilProvider {
4343
* <p>it could be that it has only AVX1 and integer vectors are fast. it could also be that it has
4444
* no AVX and integer vectors are extremely slow. don't use integer vectors to avoid landmines.
4545
*/
46-
private static final boolean IS_AMD64_WITHOUT_AVX2 =
47-
Constants.OS_ARCH.equals("amd64") && INT_SPECIES_PREF_BIT_SIZE < 256;
46+
private final boolean hasFastIntegerVectors;
4847

4948
static {
5049
if (INT_SPECIES_PREF_BIT_SIZE >= 256) {
@@ -67,8 +66,8 @@ private static <T> T doPrivileged(PrivilegedAction<T> action) {
6766
return AccessController.doPrivileged(action);
6867
}
6968

70-
VectorUtilPanamaProvider() {
71-
if (INT_SPECIES_PREF_BIT_SIZE < 128) {
69+
VectorUtilPanamaProvider(boolean testMode) {
70+
if (!testMode && INT_SPECIES_PREF_BIT_SIZE < 128) {
7271
throw new UnsupportedOperationException(
7372
"Vector bit size is less than 128: " + INT_SPECIES_PREF_BIT_SIZE);
7473
}
@@ -83,9 +82,16 @@ private static <T> T doPrivileged(PrivilegedAction<T> action) {
8382
"We hit initialization failure described in JDK-8309727: " + se);
8483
}
8584

85+
// check if the system is x86 and less than 256-bit vectors:
86+
var isAMD64withoutAVX2 = Constants.OS_ARCH.equals("amd64") && INT_SPECIES_PREF_BIT_SIZE < 256;
87+
this.hasFastIntegerVectors = testMode || false == isAMD64withoutAVX2;
88+
8689
var log = Logger.getLogger(getClass().getName());
8790
log.info(
88-
"Java vector incubator API enabled; uses preferredBitSize=" + INT_SPECIES_PREF_BIT_SIZE);
91+
"Java vector incubator API enabled"
92+
+ (testMode ? " (test mode)" : "")
93+
+ "; uses preferredBitSize="
94+
+ INT_SPECIES_PREF_BIT_SIZE);
8995
}
9096

9197
@Override
@@ -295,7 +301,7 @@ public int dotProduct(byte[] a, byte[] b) {
295301
int res = 0;
296302
// only vectorize if we'll at least enter the loop a single time, and we have at least 128-bit
297303
// vectors (256-bit on intel to dodge performance landmines)
298-
if (a.length >= 16 && IS_AMD64_WITHOUT_AVX2 == false) {
304+
if (a.length >= 16 && hasFastIntegerVectors) {
299305
// compute vectorized dot product consistent with VPDPBUSD instruction
300306
if (INT_SPECIES_PREF_BIT_SIZE >= 256) {
301307
// optimized 256/512 bit implementation, processes 8/16 bytes at a time
@@ -352,7 +358,7 @@ public float cosine(byte[] a, byte[] b) {
352358
int norm2 = 0;
353359
// only vectorize if we'll at least enter the loop a single time, and we have at least 128-bit
354360
// vectors (256-bit on intel to dodge performance landmines)
355-
if (a.length >= 16 && IS_AMD64_WITHOUT_AVX2 == false) {
361+
if (a.length >= 16 && hasFastIntegerVectors) {
356362
if (INT_SPECIES_PREF_BIT_SIZE >= 256) {
357363
// optimized 256/512 bit implementation, processes 8/16 bytes at a time
358364
int upperBound = PREF_BYTE_SPECIES.loopBound(a.length);
@@ -442,7 +448,7 @@ public int squareDistance(byte[] a, byte[] b) {
442448
int res = 0;
443449
// only vectorize if we'll at least enter the loop a single time, and we have at least 128-bit
444450
// vectors (256-bit on intel to dodge performance landmines)
445-
if (a.length >= 16 && IS_AMD64_WITHOUT_AVX2 == false) {
451+
if (a.length >= 16 && hasFastIntegerVectors) {
446452
if (INT_SPECIES_PREF_BIT_SIZE >= 256) {
447453
// optimized 256/512 bit implementation, processes 8/16 bytes at a time
448454
int upperBound = PREF_BYTE_SPECIES.loopBound(a.length);

lucene/core/src/test/org/apache/lucene/util/TestVectorUtilProviders.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class TestVectorUtilProviders extends LuceneTestCase {
2727

2828
private static final double DELTA = 1e-3;
2929
private static final VectorUtilProvider LUCENE_PROVIDER = new VectorUtilDefaultProvider();
30-
private static final VectorUtilProvider JDK_PROVIDER = VectorUtil.PROVIDER;
30+
private static final VectorUtilProvider JDK_PROVIDER = VectorUtilProvider.lookup(true);
3131

3232
private static final int[] VECTOR_SIZES = {
3333
1, 4, 6, 8, 13, 16, 25, 32, 64, 100, 128, 207, 256, 300, 512, 702, 1024

0 commit comments

Comments
 (0)