Skip to content
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
fd041d5
changes for avx512
Aug 8, 2024
263d49c
minor edits to avx512 check
Aug 20, 2024
97905aa
some more changes
Aug 23, 2024
8f8655e
fixes
akashsha1 Aug 28, 2024
a498916
more fixes
akashsha1 Aug 28, 2024
72173df
Modify faiss submodule to point to local repo.
mulugetam Aug 28, 2024
3f8eaa1
Fix avx-512 flag check.
mulugetam Aug 28, 2024
02f08f7
Fix formatting issue.
mulugetam Aug 28, 2024
19798e4
Merge branch 'main' into intel/avx512faiss
akashsha1 Sep 7, 2024
3a9a29b
few more fixes
akashsha1 Sep 7, 2024
96325af
remove extra class files
akashsha1 Sep 7, 2024
bcf2f88
address CR feedback
akashsha1 Sep 10, 2024
086a4d0
fix spotless check
akashsha1 Sep 10, 2024
7dd0a9f
Update CHANGELOG.md
akashsha1 Sep 10, 2024
6813cb7
update build script per CR feedback
akashsha1 Sep 10, 2024
097c7c1
update CI script
akashsha1 Sep 10, 2024
9517637
update dev guide and build script
akashsha1 Sep 13, 2024
273cac0
DCO check Signed-off by Akash Shankaran <akash.shankaran@intel.com>
akashsha1 Sep 13, 2024
8bcb7eb
Update scripts/build.sh
akashsha1 Sep 16, 2024
14c6486
changes for avx512
Aug 8, 2024
7f36e50
minor edits to avx512 check
Aug 20, 2024
d5c58ee
some more changes
Aug 23, 2024
0658dac
fixes
akashsha1 Aug 28, 2024
4fac524
more fixes
akashsha1 Aug 28, 2024
e36a545
Modify faiss submodule to point to local repo.
mulugetam Aug 28, 2024
3d402be
Fix avx-512 flag check.
mulugetam Aug 28, 2024
8de2aa3
Fix formatting issue.
mulugetam Aug 28, 2024
17007bd
Refactor Around Mapper and Mapping (#1939)
jmazanec15 Aug 10, 2024
e007ca4
Integrate Lucene Vector field with native engines to use KNNVectorFor…
navneet1v Aug 12, 2024
cc51ec9
Disallow invalid characters for physical file name to be included wit…
0ctopus13prime Aug 12, 2024
074f44d
Quantization Framework Implementation with 1bit and MultiBit Binary Q…
Vikasht34 Aug 13, 2024
7dad9b1
Integrate KNNVectorValues with vector ANN Search flow (#1952)
navneet1v Aug 14, 2024
09489f0
BackPort Java Doc Fix with Code Improvements (#1959)
Vikasht34 Aug 14, 2024
d506241
Quantization Framework Code Structure Improvement (#1967)
Vikasht34 Aug 15, 2024
08fe9f3
Adds rescore parameter to KNNQuery (#1969)
jmazanec15 Aug 15, 2024
6312f68
Encapsulate dimension, vector data type validation/processing inside …
jmazanec15 Aug 15, 2024
3979043
Fix bwc version for rescore (#1975)
jmazanec15 Aug 16, 2024
029e119
Fixing the dimension for the vector when using Lucene field in ModelF…
navneet1v Aug 19, 2024
9d3dc67
Disables rewrite code path to debug latency issues (#1987)
shatejas Aug 19, 2024
59d187c
Add quantization state cache (#1960)
Aug 20, 2024
48807b7
Integrates FAISS iterative builds with NativeEngines990KnnVectorsForm…
shatejas Aug 20, 2024
0b10d99
Add support for qframework from interface (#1994)
jmazanec15 Aug 21, 2024
74a60b2
Fix string for qframe parser key (#1999)
jmazanec15 Aug 22, 2024
9a8b1f5
k-NN query rescore support for native engines (#1984)
jmazanec15 Aug 22, 2024
e9fdfae
Add HNSW changes to support Faiss byte vector (#1823)
naveentatikonda Aug 23, 2024
76c031e
Integration of Quantization Framework for Binary Quantization with In…
Vikasht34 Aug 26, 2024
4b8ed7e
Parallelize make to reduce build time (#2006)
naveentatikonda Aug 28, 2024
51c6d86
Align dimensions to the nearest multiple of 8 in QuantizationState (#…
Vikasht34 Aug 29, 2024
8de553e
Changes NativeEngineKNNQuery to execute search and rescore in (#2014)
shatejas Aug 30, 2024
d42f3fe
Add IVF changes to support Faiss byte vector (#2002)
naveentatikonda Aug 30, 2024
c7fba2b
Makes NativeEngines990KnnVectorFormat as default for index version (#…
shatejas Sep 3, 2024
e04706e
Adds graph build time metrics in NativeEngines990KnnVectorsWriter (#2…
shatejas Sep 3, 2024
28133e3
Fixing the format name for NativeEngines990KnnVectorsFormat (#2025)
navneet1v Sep 4, 2024
711e734
Introduce compression and mode mapping parms (#2019)
jmazanec15 Sep 4, 2024
c3db30b
Fix memory overflow caused by cache behavior (#2015)
kotwanikunal Sep 4, 2024
f267a68
Add release notes for 2.17 (#2037)
naveentatikonda Sep 4, 2024
652490d
Add quantization state reader and writer (#1997)
Sep 5, 2024
f024c50
Introduce mode and compression param resolution (#2034)
jmazanec15 Sep 5, 2024
d8a1691
Fix tests related to quantization state (#2045)
Sep 5, 2024
d7ec5ed
Add spaceType as a top level parameter while creating vector field. (…
navneet1v Sep 5, 2024
690b733
Fix the force merge with Quantization failures when a segment has del…
navneet1v Sep 5, 2024
5683af9
Add model version to model metadata and change model metadata reads t…
Sep 5, 2024
c68bf6a
Add tests for top level spaceType parameter with different combinatio…
navneet1v Sep 6, 2024
cf4c6a6
Fix expected string for get model response tests (#2062)
Sep 6, 2024
30635ce
Throws and exception for radial search when mapping is for on-disk mo…
shatejas Sep 7, 2024
c659b4a
few more fixes
akashsha1 Sep 7, 2024
d4c7a7a
few more fixes
akashsha1 Sep 7, 2024
b3baf43
address CR feedback
akashsha1 Sep 10, 2024
6f24bb4
fix spotless check
akashsha1 Sep 10, 2024
0214423
Update CHANGELOG.md
akashsha1 Sep 10, 2024
94c7ec8
update build script per CR feedback
akashsha1 Sep 10, 2024
c98520d
update CI script
akashsha1 Sep 10, 2024
721e000
update dev guide and build script
akashsha1 Sep 13, 2024
c1b83d3
DCO check Signed-off by Akash Shankaran <akash.shankaran@intel.com>
akashsha1 Sep 13, 2024
8a4ab86
Update scripts/build.sh
akashsha1 Sep 16, 2024
347e750
Merge branch 'intel/avx512faiss' of https://github.com/akashsha1/k-NN…
akashsha1 Sep 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ buildscript {
isSnapshot = "true" == System.getProperty("build.snapshot", "true")
simd_enabled = System.getProperty("simd.enabled", "true")
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
nproc_count = System.getProperty("nproc.count", "1")
avx512_enabled = System.getProperty("avx512.enabled", "true")
// This flag determines whether the CMake build system should apply a custom patch. It prevents build failures
// when the cmakeJniLib task is run multiple times. If the build.lib.commit_patches is true, the CMake build
// system skips applying the patch if the patches have been applied already. If build.lib.commit_patches is
Expand Down Expand Up @@ -317,6 +318,7 @@ task cmakeJniLib(type:Exec) {
args.add(".")
args.add("-DKNN_PLUGIN_VERSION=${opensearch_version}")
args.add("-DSIMD_ENABLED=${simd_enabled}")
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
args.add("-DAVX512_ENABLED=${avx512_enabled}")
args.add("-DCOMMIT_LIB_PATCHES=${commit_lib_patches}")
args.add("-DAPPLY_LIB_PATCHES=${apply_lib_patches}")
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
Expand Down
10 changes: 9 additions & 1 deletion jni/cmake/init-faiss.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,17 @@ if(NOT DEFINED SIMD_ENABLED)
set(SIMD_ENABLED true) # set default value as true if the argument is not set
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
endif()

if(${CMAKE_SYSTEM_NAME} STREQUAL Windows OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64" OR NOT ${SIMD_ENABLED})
if(NOT DEFINED AVX512_ENABLED)
set(AVX512_ENABLED true) # set default value as true if the argument is not set
endif()

if(${CMAKE_SYSTEM_NAME} STREQUAL Windows OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64" OR NOT SIMD_ENABLED)
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
set(FAISS_OPT_LEVEL generic) # Keep optimization level as generic on Windows OS as it is not supported due to MINGW64 compiler issue. Also, on aarch64 avx2 is not supported.
set(TARGET_LINK_FAISS_LIB faiss)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux AND SIMD_ENABLED AND AVX512_ENABLED)
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
set(FAISS_OPT_LEVEL avx512) # Keep optimization level as avx512 to improve performance on Linux. This is not present on mac systems.
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
set(TARGET_LINK_FAISS_LIB faiss_avx512)
string(PREPEND LIB_EXT "_avx512") # Prepend "_avx512" to lib extension to create the library as "libopensearchknn_faiss_avx512.so" on linux
else()
set(FAISS_OPT_LEVEL avx2) # Keep optimization level as avx2 to improve performance on Linux and Mac.
set(TARGET_LINK_FAISS_LIB faiss_avx2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public class KNNConstants {
private static final String JNI_LIBRARY_PREFIX = "opensearchknn_";
public static final String FAISS_JNI_LIBRARY_NAME = JNI_LIBRARY_PREFIX + FAISS_NAME;
public static final String FAISS_AVX2_JNI_LIBRARY_NAME = JNI_LIBRARY_PREFIX + FAISS_NAME + "_avx2";
public static final String FAISS_AVX512_JNI_LIBRARY_NAME = JNI_LIBRARY_PREFIX + FAISS_NAME + "_avx512";
public static final String NMSLIB_JNI_LIBRARY_NAME = JNI_LIBRARY_PREFIX + NMSLIB_NAME;

public static final String COMMON_JNI_LIBRARY_NAME = JNI_LIBRARY_PREFIX + COMMONS_NAME;
Expand Down
31 changes: 30 additions & 1 deletion src/main/java/org/opensearch/knn/index/KNNSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ public class KNNSettings {
public static final String KNN_FAISS_AVX2_DISABLED = "knn.faiss.avx2.disabled";
public static final String QUANTIZATION_STATE_CACHE_SIZE_LIMIT = "knn.quantization.cache.size.limit";
public static final String QUANTIZATION_STATE_CACHE_EXPIRY_TIME_MINUTES = "knn.quantization.cache.expiry.minutes";
public static final String KNN_FAISS_AVX512_DISABLED = "knn.faiss.avx512.disabled";

/**
* Default setting values
*/
public static final boolean KNN_DEFAULT_FAISS_AVX2_DISABLED_VALUE = false;
public static final boolean KNN_DEFAULT_FAISS_AVX512_DISABLED_VALUE = false;
public static final String INDEX_KNN_DEFAULT_SPACE_TYPE = "l2";
public static final String INDEX_KNN_DEFAULT_SPACE_TYPE_FOR_BINARY = "hamming";
public static final Integer INDEX_KNN_DEFAULT_ALGO_PARAM_M = 16;
Expand Down Expand Up @@ -302,6 +304,12 @@ public class KNNSettings {
Dynamic
);

public static final Setting<Boolean> KNN_FAISS_AVX512_DISABLED_SETTING = Setting.boolSetting(
KNN_FAISS_AVX512_DISABLED,
KNN_DEFAULT_FAISS_AVX512_DISABLED_VALUE,
NodeScope
);

/**
* Dynamic settings
*/
Expand Down Expand Up @@ -429,6 +437,10 @@ private Setting<?> getSetting(String key) {
return KNN_FAISS_AVX2_DISABLED_SETTING;
}

if (KNN_FAISS_AVX512_DISABLED.equals(key)) {
return KNN_FAISS_AVX512_DISABLED_SETTING;
}

if (KNN_VECTOR_STREAMING_MEMORY_LIMIT_IN_MB.equals(key)) {
return KNN_VECTOR_STREAMING_MEMORY_LIMIT_PCT_SETTING;
}
Expand Down Expand Up @@ -461,7 +473,8 @@ public List<Setting<?>> getSettings() {
KNN_FAISS_AVX2_DISABLED_SETTING,
KNN_VECTOR_STREAMING_MEMORY_LIMIT_PCT_SETTING,
QUANTIZATION_STATE_CACHE_SIZE_LIMIT_SETTING,
QUANTIZATION_STATE_CACHE_EXPIRY_TIME_MINUTES_SETTING
QUANTIZATION_STATE_CACHE_EXPIRY_TIME_MINUTES_SETTING,
KNN_FAISS_AVX512_DISABLED_SETTING
);
return Stream.concat(settings.stream(), Stream.concat(getFeatureFlags().stream(), dynamicCacheSettings.values().stream()))
.collect(Collectors.toList());
Expand Down Expand Up @@ -499,6 +512,22 @@ public static boolean isFaissAVX2Disabled() {
}
}

public static boolean isFaissAVX512Disabled() {
try {
return KNNSettings.state().getSettingValue(KNNSettings.KNN_FAISS_AVX512_DISABLED);
} catch (Exception e) {
// In some UTs we identified that cluster setting is not set properly an leads to NPE. This check will avoid
// those cases and will still return the default value.
log.warn(
"Unable to get setting value {} from cluster settings. Using default value as {}",
KNN_FAISS_AVX512_DISABLED,
KNN_DEFAULT_FAISS_AVX512_DISABLED_VALUE,
e
);
return KNN_DEFAULT_FAISS_AVX512_DISABLED_VALUE;
}
}

public static Integer getFilteredExactSearchThreshold(final String indexName) {
return KNNSettings.state().clusterService.state()
.getMetadata()
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/org/opensearch/knn/jni/FaissService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import static org.opensearch.knn.index.KNNSettings.isFaissAVX2Disabled;
import static org.opensearch.knn.jni.PlatformUtils.isAVX2SupportedBySystem;
import static org.opensearch.knn.jni.PlatformUtils.isAVX512SupportedBySystem;;

/**
* Service to interact with faiss jni layer. Class dependencies should be minimal
Expand All @@ -35,10 +36,16 @@ class FaissService {
static {
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {

// Even if the underlying system supports AVX2, users can override and disable it by using the
// Even if the underlying system supports AVX512 and AVX2, users can override and disable it by using the
// 'knn.faiss.avx2.disabled' setting by setting it to true in the opensearch.yml configuration
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
if (!isFaissAVX2Disabled() && isAVX2SupportedBySystem()) {
System.loadLibrary(KNNConstants.FAISS_AVX2_JNI_LIBRARY_NAME);
if (!isFaissAVX2Disabled()) {
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
if (isAVX512SupportedBySystem()) {
System.loadLibrary(KNNConstants.FAISS_AVX512_JNI_LIBRARY_NAME);
} else if (isAVX2SupportedBySystem()) {
System.loadLibrary(KNNConstants.FAISS_AVX2_JNI_LIBRARY_NAME);
} else {
System.loadLibrary(KNNConstants.FAISS_JNI_LIBRARY_NAME);
}
} else {
System.loadLibrary(KNNConstants.FAISS_JNI_LIBRARY_NAME);
}
Expand Down
37 changes: 36 additions & 1 deletion src/main/java/org/opensearch/knn/jni/PlatformUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import java.nio.file.Paths;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.Locale;
import java.util.stream.Stream;

public class PlatformUtils {

Expand Down Expand Up @@ -58,7 +60,6 @@ public static boolean isAVX2SupportedBySystem() {
}

} else if (Platform.isLinux()) {

// The "/proc/cpuinfo" is a virtual file which identifies and provides the processor details used
// by system. This info contains "flags" for each processor which determines the qualities of that processor
// and it's ability to process different instruction sets like mmx, avx, avx2 and so on.
Expand All @@ -80,4 +81,38 @@ public static boolean isAVX2SupportedBySystem() {
}
return false;
}

public static boolean isAVX512SupportedBySystem() {

if (!Platform.isIntel() || Platform.isMac()) {
Comment thread
akashsha1 marked this conversation as resolved.
Outdated
return false;
}

if (Platform.isLinux()) {
// The "/proc/cpuinfo" is a virtual file which identifies and provides the processor details used
// by system. This info contains "flags" for each processor which determines the qualities of that processor
// and it's ability to process different instruction sets like mmx, avx, avx2, avx512 and so on.
// https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-cpuinfo
// Here, we are trying to read the details of all processors used by system and find if any of the processor
// supports AVX512 instructions supported by faiss.
String fileName = "/proc/cpuinfo";

// AVX512 has multiple flags, which control various features. k-nn requires the same set of flags as faiss to compile
// using avx512. Please update these if faiss updates their compilation instructions in the future.
// https://github.com/facebookresearch/faiss/blob/main/faiss/CMakeLists.txt
String[] avx512 = { "avx512f", "avx512cd", "avx512vl", "avx512dq", "avx512bw" };

try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Boolean>) () -> {
Stream<String> linestream = Files.lines(Paths.get(fileName));
String flags = linestream.filter(line -> line.startsWith("flags")).findFirst().orElse("");
return Arrays.stream(avx512).allMatch(flags::contains);
});

} catch (Exception e) {
logger.error("[KNN] Error reading file [{}]. [{}]", fileName, e.getMessage(), e);
}
}
return false;
}
}
58 changes: 58 additions & 0 deletions src/test/java/org/opensearch/knn/jni/PlatformUtilTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import static org.mockito.Mockito.mockStatic;
import static org.opensearch.knn.jni.PlatformUtils.isAVX2SupportedBySystem;
import static org.opensearch.knn.jni.PlatformUtils.isAVX512SupportedBySystem;

public class PlatformUtilTests extends KNNTestCase {
public static final String MAC_CPU_FEATURES = "machdep.cpu.leaf7_features";
Expand Down Expand Up @@ -124,4 +125,61 @@ public void testIsAVX2SupportedBySystem_platformIsLinux_throwsExceptionReturnsFa

}

// AVX512 tests

public void testIsAVX512SupportedBySystem_platformIsNotIntel_returnsFalse() {
try (MockedStatic<Platform> mockedPlatform = mockStatic(Platform.class)) {
mockedPlatform.when(Platform::isIntel).thenReturn(false);
assertFalse(isAVX512SupportedBySystem());
}
}

public void testIsAVX512SupportedBySystem_platformIsMac_returnsFalse() {
try (MockedStatic<Platform> mockedPlatform = mockStatic(Platform.class)) {
mockedPlatform.when(Platform::isMac).thenReturn(false);
assertFalse(isAVX512SupportedBySystem());
}
}

public void testIsAVX512SupportedBySystem_platformIsIntelMac_returnsFalse() {
try (MockedStatic<Platform> mockedPlatform = mockStatic(Platform.class)) {
mockedPlatform.when(Platform::isIntel).thenReturn(true);
mockedPlatform.when(Platform::isMac).thenReturn(true);
assertFalse(isAVX512SupportedBySystem());
}
}

public void testIsAVX512SupportedBySystem_platformIsIntelWithOSAsWindows_returnsFalse() {
try (MockedStatic<Platform> mockedPlatform = mockStatic(Platform.class)) {
mockedPlatform.when(Platform::isIntel).thenReturn(true);
mockedPlatform.when(Platform::isWindows).thenReturn(true);
assertFalse(isAVX512SupportedBySystem());
}
}

public void testIsAVX512SupportedBySystem_platformIsLinuxAllAVX512FlagsPresent_returnsTrue() {
try (MockedStatic<Platform> mockedPlatform = mockStatic(Platform.class)) {
mockedPlatform.when(Platform::isIntel).thenReturn(true);
mockedPlatform.when(Platform::isLinux).thenReturn(true);

try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
mockedFiles.when(() -> Files.lines(Paths.get(LINUX_PROC_CPU_INFO)))
.thenReturn(Stream.of("flags: AVX2 avx512f avx512cd avx512vl avx512dq avx512bw", "dummy string"));
assertTrue(isAVX512SupportedBySystem());
}
}
}

public void testIsAVX512SupportedBySystem_platformIsLinuxSomeAVX512FlagsPresent_returnsFalse() {
try (MockedStatic<Platform> mockedPlatform = mockStatic(Platform.class)) {
mockedPlatform.when(Platform::isIntel).thenReturn(true);
mockedPlatform.when(Platform::isLinux).thenReturn(true);

try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {
mockedFiles.when(() -> Files.lines(Paths.get(LINUX_PROC_CPU_INFO)))
.thenReturn(Stream.of("flags: AVX2 avx512vl avx512dq avx512bw avx512vbmi umip pku ospke avx512_vbmi2", "dummy string"));
assertFalse(isAVX512SupportedBySystem());
}
}
}
}