Skip to content

Commit

Permalink
Make: Forward SimSIMD settings
Browse files Browse the repository at this point in the history
Caution: This replaces USES_NATIVE_F16 settings with USES_FP16LIB.
  • Loading branch information
ashvardanian committed Nov 9, 2023
1 parent 3578c50 commit 6f2857f
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 75 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"linalg",
"longlong",
"memmap",
"MSVC",
"Napi",
"ndarray",
"ndim",
Expand Down
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ option(USEARCH_INSTALL "Install CMake targets" OFF)
option(USEARCH_USE_OPENMP "Use OpenMP for a thread pool" OFF)
option(USEARCH_USE_SIMSIMD "Use SimSIMD hardware-accelerated metrics" OFF)
option(USEARCH_USE_JEMALLOC "Use JeMalloc for faster memory allocations" OFF)
option(USEARCH_USE_NATIVE_F16 "Use native half-precision types" OFF)
option(USEARCH_USE_FP16LIB "Use software emulation for half-precision types" OFF)

option(USEARCH_BUILD_TEST_CPP "Compile a native unit test in C++" ${USEARCH_IS_MAIN_PROJECT})
option(USEARCH_BUILD_BENCH_CPP "Compile a native benchmark in C++" ${USEARCH_IS_MAIN_PROJECT})
Expand Down Expand Up @@ -69,7 +69,7 @@ target_compile_definitions(

# Supplementary compilation settings affecting "index_plugins.hpp"
target_compile_definitions(
${USEARCH_TARGET_NAME} INTERFACE $<$<NOT:$<BOOL:${USEARCH_USE_NATIVE_F16}>>:USEARCH_USE_NATIVE_F16=0>
${USEARCH_TARGET_NAME} INTERFACE $<$<NOT:$<BOOL:${USEARCH_USE_FP16LIB}>>:USEARCH_USE_FP16LIB=0>
)

target_compile_definitions(
Expand Down Expand Up @@ -302,7 +302,7 @@ function (setup_target TARGET_NAME)

# Supplementary compilation settings affecting "index_plugins.hpp"
target_compile_definitions(
${TARGET_NAME} PRIVATE $<$<NOT:$<BOOL:${USEARCH_USE_NATIVE_F16}>>:USEARCH_USE_NATIVE_F16=0>
${TARGET_NAME} PRIVATE $<$<NOT:$<BOOL:${USEARCH_USE_FP16LIB}>>:USEARCH_USE_FP16LIB=0>
)

target_compile_definitions(${TARGET_NAME} PRIVATE $<$<NOT:$<BOOL:${USEARCH_USE_SIMSIMD}>>:USEARCH_USE_SIMSIMD=0>)
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The CMakeLists.txt file has a number of options you can pass:
- `USEARCH_USE_OPENMP` - use OpenMP for parallelism
- `USEARCH_USE_SIMSIMD` - use SimSIMD for vectorization
- `USEARCH_USE_JEMALLOC` - use Jemalloc for memory management
- `USEARCH_USE_NATIVE_F16` - use native half-precision floating point
- `USEARCH_USE_FP16LIB` - use software emulation for half-precision floating point

Putting all of this together on Ubuntu and compiling the "release" version using the GCC 12 compiler:

Expand All @@ -58,7 +58,7 @@ cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=gcc-12 \
-DCMAKE_CXX_COMPILER=g++-12 \
-DUSEARCH_USE_NATIVE_F16=1 \
-DUSEARCH_USE_FP16LIB=1 \
-DUSEARCH_USE_OPENMP=1 \
-DUSEARCH_USE_SIMSIMD=1 \
-DUSEARCH_USE_JEMALLOC=1 \
Expand All @@ -80,7 +80,7 @@ cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="/opt/homebrew/opt/llvm/bin/clang" \
-DCMAKE_CXX_COMPILER="/opt/homebrew/opt/llvm/bin/clang++" \
-DUSEARCH_USE_NATIVE_F16=1 \
-DUSEARCH_USE_FP16LIB=1 \
-DUSEARCH_USE_OPENMP=1 \
-DUSEARCH_USE_SIMSIMD=1 \
-DUSEARCH_USE_JEMALLOC=1 \
Expand Down
101 changes: 74 additions & 27 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,83 @@
"include_dirs": [
"<!@(node -p \"require('node-addon-api').include\")",
"include",
"<!(echo $USEARCH_USE_SIMSIMD == '1' ? 'simsimd/include' : '')",
"<!(echo $USEARCH_USE_NATIVE_F16 == '1' ? 'fp16/include' : '')",
"<!(if [ -z \"$USEARCH_USE_SIMSIMD\" ]; then echo 'simsimd/include'; fi)",
"<!(if [ -z \"$USEARCH_USE_FP16LIB\" ]; then echo 'fp16/include'; fi)",
],
"dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
"defines": [
"<!(echo $USEARCH_USE_SIMSIMD == '1' ? 'USEARCH_USE_SIMSIMD=1' : 'USEARCH_USE_SIMSIMD=0')",
"<!(echo $USEARCH_USE_NATIVE_F16 == '1' ? 'USEARCH_USE_NATIVE_F16=1' : 'USEARCH_USE_NATIVE_F16=0')"
"conditions": [
[
'OS=="linux"',
{
"cflags_cc": [
"-std=c++17",
"-O3",
"-ffast-math",
"-Wno-unknown-pragmas",
"-fdiagnostics-color=always",
"-fexceptions",
"-g1",
'<!(if [ "$USEARCH_USE_OPENMP" = "1" ]; then echo \'-fopenmp\'; fi)',
],
"ldflags": [
'<!(if [ "$USEARCH_USE_OPENMP" = "1" ]; then echo \'-lgomp\'; fi)'
],
"defines": [
"USEARCH_USE_OPENMP=<!(echo ${USEARCH_USE_OPENMP:-1})",
"USEARCH_USE_SIMSIMD=<!(echo ${USEARCH_USE_SIMSIMD:-1})",
"USEARCH_USE_FP16LIB=<!(echo ${USEARCH_USE_FP16LIB:-1})",
"SIMSIMD_TARGET_X86_AVX512=<!(echo ${SIMSIMD_TARGET_X86_AVX512:-1})",
"SIMSIMD_TARGET_ARM_SVE=<!(echo ${SIMSIMD_TARGET_ARM_SVE:-1})",
"SIMSIMD_TARGET_X86_AVX2=<!(echo ${SIMSIMD_TARGET_X86_AVX2:-1})",
"SIMSIMD_TARGET_ARM_NEON=<!(echo ${SIMSIMD_TARGET_ARM_NEON:-1})",
],
},
],
[
'OS=="mac"',
{
"xcode_settings": {"MACOSX_DEPLOYMENT_TARGET": "10.15"},
"cflags_cc": [
"-std=c++17",
"-O3",
"-ffast-math",
"-fcolor-diagnostics",
"-Wno-unknown-pragmas",
"-fexceptions",
"-g1",
],
"defines": [
"USEARCH_USE_OPENMP=<!(echo ${USEARCH_USE_OPENMP:-0})",
"USEARCH_USE_SIMSIMD=<!(echo ${USEARCH_USE_SIMSIMD:-0})",
"USEARCH_USE_FP16LIB=<!(echo ${USEARCH_USE_FP16LIB:-1})",
"SIMSIMD_TARGET_X86_AVX512=<!(echo ${SIMSIMD_TARGET_X86_AVX512:-0})",
"SIMSIMD_TARGET_ARM_SVE=<!(echo ${SIMSIMD_TARGET_ARM_SVE:-0})",
"SIMSIMD_TARGET_X86_AVX2=<!(echo ${SIMSIMD_TARGET_X86_AVX2:-1})",
"SIMSIMD_TARGET_ARM_NEON=<!(echo ${SIMSIMD_TARGET_ARM_NEON:-1})",
],
},
],
[
'OS=="win"',
{
"msvs_settings": {
"VCCLCompilerTool": {
"Optimization": "2",
"AdditionalOptions": ["/fp:fast", "/W1"],
}
},
"defines": [
"USEARCH_USE_OPENMP=0",
"USEARCH_USE_SIMSIMD=<(USEARCH_USE_SIMSIMD?USEARCH_USE_SIMSIMD:'0')",
"USEARCH_USE_FP16LIB=<(USEARCH_USE_FP16LIB?USEARCH_USE_FP16LIB:'1')",
"SIMSIMD_TARGET_X86_AVX512=<(SIMSIMD_TARGET_X86_AVX512?SIMSIMD_TARGET_X86_AVX512:'0')",
"SIMSIMD_TARGET_ARM_SVE=<(SIMSIMD_TARGET_ARM_SVE?SIMSIMD_TARGET_ARM_SVE:'0')",
"SIMSIMD_TARGET_X86_AVX2=<(SIMSIMD_TARGET_X86_AVX2?SIMSIMD_TARGET_X86_AVX2:'0')",
"SIMSIMD_TARGET_ARM_NEON=<(SIMSIMD_TARGET_ARM_NEON?SIMSIMD_TARGET_ARM_NEON:'0')",
],
},
],
],
"cflags": [
"-fexceptions",
"-Wno-unknown-pragmas",
"-Wno-maybe-uninitialized",
],
"cflags_cc": [
"-fexceptions",
"-Wno-unknown-pragmas",
"-Wno-maybe-uninitialized",
"-std=c++17",
],
"xcode_settings": {
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
"CLANG_CXX_LIBRARY": "libc++",
"MACOSX_DEPLOYMENT_TARGET": "10.15",
},
"msvs_settings": {
"VCCLCompilerTool": {
"ExceptionHandling": 1,
"AdditionalOptions": ["-std:c++17"],
}
},
}
]
}
50 changes: 27 additions & 23 deletions include/usearch/index_plugins.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

#include <usearch/index.hpp> // `expected_gt` and macros

#if !defined(USEARCH_USE_OPENMP)
#define USEARCH_USE_OPENMP 0
#endif

#if USEARCH_USE_OPENMP
#include <omp.h> // `omp_get_num_threads()`
#endif
Expand All @@ -21,18 +25,18 @@
#include <sys/auxv.h> // `getauxval()`
#endif

#if !defined(USEARCH_USE_NATIVE_F16)
#if !defined(USEARCH_USE_FP16LIB)
#if defined(__AVX512F__)
#define USEARCH_USE_NATIVE_F16 1
#define USEARCH_USE_FP16LIB 0
#elif defined(USEARCH_DEFINED_ARM)
#include <arm_fp16.h> // `__fp16`
#define USEARCH_USE_NATIVE_F16 1
#define USEARCH_USE_FP16LIB 0
#else
#define USEARCH_USE_NATIVE_F16 0
#define USEARCH_USE_FP16LIB 1
#endif
#endif

#if !USEARCH_USE_NATIVE_F16
#if USEARCH_USE_FP16LIB
#include <fp16/fp16.h>
#endif

Expand All @@ -41,27 +45,27 @@
#endif

#if USEARCH_USE_SIMSIMD

// Propagate the `f16` settings
#define SIMSIMD_NATIVE_F16 USEARCH_USE_NATIVE_F16
#if defined(USEARCH_DEFINED_LINUX)
#define SIMSIMD_NATIVE_F16 !USEARCH_USE_FP16LIB

#if !defined(SIMSIMD_TARGET_X86_AVX512) && defined(USEARCH_DEFINED_LINUX)
#define SIMSIMD_TARGET_X86_AVX512 1
#endif

#if !defined(SIMSIMD_TARGET_ARM_SVE) && defined(USEARCH_DEFINED_LINUX)
#define SIMSIMD_TARGET_ARM_SVE 1
#endif

#if !defined(SIMSIMD_TARGET_X86_AVX2) && (defined(USEARCH_DEFINED_LINUX) || defined(USEARCH_DEFINED_APPLE))
#define SIMSIMD_TARGET_X86_AVX2 1
#endif

#if !defined(SIMSIMD_TARGET_ARM_NEON) && (defined(USEARCH_DEFINED_LINUX) || defined(USEARCH_DEFINED_APPLE))
#define SIMSIMD_TARGET_ARM_NEON 1
#include <simsimd/simsimd.h>
#elif defined(USEARCH_DEFINED_APPLE)
#define SIMSIMD_TARGET_X86_AVX512 0
#define SIMSIMD_TARGET_ARM_SVE 0
#define SIMSIMD_TARGET_X86_AVX2 1
#define SIMSIMD_TARGET_ARM_NEON 1
#include <simsimd/simsimd.h>
#else
#define SIMSIMD_TARGET_X86_AVX512 0
#define SIMSIMD_TARGET_ARM_SVE 0
#define SIMSIMD_TARGET_X86_AVX2 0
#define SIMSIMD_TARGET_ARM_NEON 0
#include <simsimd/simsimd.h>
#endif

#include <simsimd/simsimd.h>
#endif

namespace unum {
Expand All @@ -77,7 +81,7 @@ struct uuid_t {
class f16_bits_t;
class i8_converted_t;

#if USEARCH_USE_NATIVE_F16
#if !USEARCH_USE_FP16LIB
#if defined(USEARCH_DEFINED_ARM)
using f16_native_t = __fp16;
#else
Expand Down Expand Up @@ -298,7 +302,7 @@ inline expected_gt<metric_kind_t> metric_from_name(char const* name) {
}

inline float f16_to_f32(std::uint16_t u16) noexcept {
#if USEARCH_USE_NATIVE_F16
#if !USEARCH_USE_FP16LIB
f16_native_t f16;
std::memcpy(&f16, &u16, sizeof(std::uint16_t));
return float(f16);
Expand All @@ -308,7 +312,7 @@ inline float f16_to_f32(std::uint16_t u16) noexcept {
}

inline std::uint16_t f32_to_f16(float f32) noexcept {
#if USEARCH_USE_NATIVE_F16
#if !USEARCH_USE_FP16LIB
f16_native_t f16 = f16_native_t(f32);
std::uint16_t u16;
std::memcpy(&u16, &f16, sizeof(std::uint16_t));
Expand Down
2 changes: 1 addition & 1 deletion python/lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,7 @@ PYBIND11_MODULE(compiled, m) {

m.attr("USES_OPENMP") = py::int_(USEARCH_USE_OPENMP);
m.attr("USES_SIMSIMD") = py::int_(USEARCH_USE_SIMSIMD);
m.attr("USES_NATIVE_F16") = py::int_(USEARCH_USE_NATIVE_F16);
m.attr("USES_FP16LIB") = py::int_(USEARCH_USE_FP16LIB);

py::enum_<metric_punned_signature_t>(m, "MetricSignature")
.value("ArrayArray", metric_punned_signature_t::array_array_k)
Expand Down
4 changes: 2 additions & 2 deletions python/scripts/cluster.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
"metadata": {},
"outputs": [],
"source": [
"from usearch.index import Index, USES_SIMSIMD, USES_NATIVE_F16\n",
"from usearch.index import Index, USES_SIMSIMD, USES_FP16LIB\n",
"\n",
"index = Index(ndim=vectors.shape[1], metric=\"cos\", dtype=\"i8\")\n",
"index.hardware_acceleration, USES_SIMSIMD, USES_NATIVE_F16"
"index.hardware_acceleration, USES_SIMSIMD, USES_FP16LIB"
]
},
{
Expand Down
6 changes: 3 additions & 3 deletions python/usearch/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
DEFAULT_EXPANSION_SEARCH,
USES_OPENMP,
USES_SIMSIMD,
USES_NATIVE_F16,
USES_FP16LIB,
)

MetricKindBitwise = (
Expand Down Expand Up @@ -1204,7 +1204,7 @@ def specs(self) -> Dict[str, Union[str, int, bool]]:
"path": self.path,
"compiled_with_openmp": USES_OPENMP,
"compiled_with_simsimd": USES_SIMSIMD,
"compiled_with_native_f16": USES_NATIVE_F16,
"compiled_with_native_f16": USES_FP16LIB,
}

def __repr__(self) -> str:
Expand Down Expand Up @@ -1242,7 +1242,7 @@ def _repr_pretty_(self, printer, cycle) -> str:
"- binary",
f"-- uses OpenMP: {USES_OPENMP}",
f"-- uses SimSIMD: {USES_SIMSIMD}",
f"-- supports half-precision: {USES_NATIVE_F16}",
f"-- supports half-precision: {USES_FP16LIB}",
f"-- uses hardware acceleration: {self.hardware_acceleration}",
"- state",
f"-- size: {self.size:,} vectors",
Expand Down
Loading

0 comments on commit 6f2857f

Please sign in to comment.