Subject: [bug#76477] [PATCH] gnu: faiss: Update to 1.10.0.

From: Nicolas Graves <[email-masked]>
Date: Fri, 21 Feb 2025 19:24:28 +0100

* gnu/packages/graph.scm (faiss): Update to 1.10.0.
[source]: Adapt snippet. Add patch.
[arguments]: Delete likely uneeded {phases}. Adapt {configure-flags}.
[native-inputs]: Add openmpi.
(python-faiss): Update to 1.10.0.
[build-system]: Switch to cmake-build-system.
[arguments]: Rewrite all arguments.
[inputs]: Improve-style. Switch python for python-wrapper.
[native-inputs]: Add python-scipy.
[propagated-inputs]: Remove python-matplotlib.

* gnu/packages/patches/faiss-tests-CMakeLists-find-googletest.patch:
Add patch.
* gnu/local.mk: Likewise.

* gnu/packages/graph.scm
---
 gnu/local.mk                                  |   1 +
 gnu/packages/graph.scm                        | 202 ++++++++----------
 ...iss-tests-CMakeLists-find-googletest.patch |  53 +++++
 3 files changed, 146 insertions(+), 110 deletions(-)
 create mode 100644 gnu/packages/patches/faiss-tests-CMakeLists-find-googletest.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index c7f63c458a..464e3896b6 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1258,6 +1258,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/fail2ban-python310-server-action.patch	\
   %D%/packages/patches/fail2ban-python310-server-actions.patch	\
   %D%/packages/patches/fail2ban-python310-server-jails.patch	\
+  %D%/packages/patches/faiss-tests-CMakeLists-find-googletest.patch	\
   %D%/packages/patches/falcosecurity-libs-shared-build.patch	\
   %D%/packages/patches/farstream-gupnp.patch                         \
   %D%/packages/patches/farstream-make.patch                          \
diff --git a/gnu/packages/graph.scm b/gnu/packages/graph.scm
index f29a71c0d7..467a7f661b 100644
--- a/gnu/packages/graph.scm
+++ b/gnu/packages/graph.scm
@@ -62,6 +62,7 @@ (define-module (gnu packages graph)
   #:use-module (gnu packages linux)
   #:use-module (gnu packages machine-learning)
   #:use-module (gnu packages maths)
+  #:use-module (gnu packages mpi)
   #:use-module (gnu packages multiprecision)
   #:use-module (gnu packages ncurses)
   #:use-module (gnu packages pkg-config)
@@ -582,85 +583,36 @@ (define-public python-pygsp
 (define-public faiss
   (package
     (name "faiss")
-    (version "1.5.0")
-    (source (origin
-              (method git-fetch)
-              (uri (git-reference
-                    (url "https://github.com/facebookresearch/faiss")
-                    (commit (string-append "v" version))))
-              (file-name (git-file-name name version))
-              (sha256
-               (base32
-                "0pk15jfa775cy2pqmzq62nhd6zfjxmpvz5h731197c28aq3zw39w"))
-              (modules '((guix build utils)))
-              (snippet
-               '(begin
-                  (substitute* "utils.cpp"
-                    (("#include <immintrin.h>")
-                     "#ifdef __SSE__\n#include <immintrin.h>\n#endif"))
-                  #t))))
+    (version "1.10.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/facebookresearch/faiss")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "1x6z94f6vhh7ppsn7wll46k7i63lzcnc3r3rv5zfarljybqhrsjd"))
+       ;; Including but skipping perf_tests requires to patch
+       ;; perf_tests/CMakeLists.txt. KISS: Remove it instead.
+       (modules '((guix build utils)))
+       (snippet #~(begin
+                    (delete-file-recursively "perf_tests")
+                    (substitute* "CMakeLists.txt"
+                      (("add_subdirectory\\(perf_tests\\)") ""))))
+       (patches
+        (search-patches "faiss-tests-CMakeLists-find-googletest.patch"))))
     (build-system cmake-build-system)
     (arguments
-     `(#:configure-flags
-       (list "-DBUILD_WITH_GPU=OFF"     ; thanks, but no thanks, CUDA.
-             "-DBUILD_TUTORIAL=OFF")    ; we don't need those
-       #:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'prepare-build
-           (lambda _
-             (let ((features (list ,@(let ((system (or (%current-target-system)
-                                                       (%current-system))))
-                                       (cond
-                                        ((string-prefix? "x86_64" system)
-                                         '("-mavx" "-msse2" "-mpopcnt"))
-                                        ((string-prefix? "i686" system)
-                                         '("-msse2" "-mpopcnt"))
-                                        (else
-                                         '()))))))
-               (substitute* "CMakeLists.txt"
-                 (("-m64") "")
-                 (("-mpopcnt") "")      ; only some architectures
-                 (("-msse4")
-                  (string-append
-                   (string-join features)
-                   " -I" (getcwd)))
-                 ;; Build also the shared library
-                 (("ARCHIVE DESTINATION lib")
-                  "LIBRARY DESTINATION lib")
-                 (("add_library.*" m)
-                  "\
-add_library(objlib OBJECT ${faiss_cpu_headers} ${faiss_cpu_cpp})
-set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
-add_library(${faiss_lib}_static STATIC $<TARGET_OBJECTS:objlib>)
-add_library(${faiss_lib} SHARED $<TARGET_OBJECTS:objlib>)
-install(TARGETS ${faiss_lib}_static ARCHIVE DESTINATION lib)
-\n")))
-
-             ;; See https://github.com/facebookresearch/faiss/issues/520
-             (substitute* "IndexScalarQuantizer.cpp"
-               (("#define USE_AVX") ""))
-
-             ;; Make header files available for compiling tests.
-             (mkdir-p "faiss")
-             (for-each (lambda (file)
-                         (mkdir-p (string-append "faiss/" (dirname file)))
-                         (copy-file file (string-append "faiss/" file)))
-                       (find-files "." "\\.h$"))
-             #t))
-         (replace 'check
-           (lambda _
-             (invoke "make" "-C" "tests"
-                     (format #f "-j~a" (parallel-job-count)))))
-         (add-after 'install 'remove-tests
-           (lambda* (#:key outputs #:allow-other-keys)
-             (delete-file-recursively
-              (string-append (assoc-ref outputs "out")
-                             "/test"))
-             #t)))))
+     (list #:configure-flags
+           #~'("-DFAISS_ENABLE_GPU=OFF"     ; thanks, but no thanks, CUDA.
+               "-DFAISS_ENABLE_PYTHON=OFF"
+               "-DBUILD_TESTING=ON")))
     (inputs
      (list openblas))
     (native-inputs
-     (list googletest))
+     (list googletest openmpi))
     (home-page "https://github.com/facebookresearch/faiss")
     (synopsis "Efficient similarity search and clustering of dense vectors")
     (description "Faiss is a library for efficient similarity search and
@@ -672,45 +624,75 @@ (define-public faiss
 (define-public python-faiss
   (package (inherit faiss)
     (name "python-faiss")
-    (build-system python-build-system)
+    (build-system cmake-build-system)
     (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'chdir
-           (lambda _ (chdir "python") #t))
-         (add-after 'chdir 'build-swig
-           (lambda* (#:key inputs #:allow-other-keys)
-             (with-output-to-file "../makefile.inc"
-               (lambda ()
-                 (let ((python-version ,(version-major+minor (package-version python))))
-                   (format #t "\
-PYTHONCFLAGS =-I~a/include/python~a/ -I~a/lib/python~a/site-packages/numpy/core/include
-LIBS = -lpython~a -lfaiss
-SHAREDFLAGS = -shared -fopenmp
-CXXFLAGS = -fpermissive -fopenmp -fPIC
-CPUFLAGS = ~{~a ~}~%"
-                           (assoc-ref inputs "python*") python-version
-                           (assoc-ref inputs "python-numpy") python-version
-                           python-version
-                           (list ,@(let ((system (or (%current-target-system)
-                                                     (%current-system))))
-                                     (cond
-                                       ((string-prefix? "x86_64" system)
-                                        '("-mavx" "-msse2" "-mpopcnt"))
-                                       ((string-prefix? "i686" system)
-                                        '("-msse2" "-mpopcnt"))
-                                       (else
-                                         '()))))))))
-             (substitute* "Makefile"
-               (("../libfaiss.a") ""))
-             (invoke "make" "cpu"))))))
+     (list
+      #:imported-modules `(,@%cmake-build-system-modules
+                           (guix build gremlin)
+                           (guix build python-build-system))
+      #:modules '((guix build cmake-build-system)
+                  ((guix build python-build-system) #:prefix python:)
+                  (guix build utils)
+                  (guix build gremlin)
+                  (ice-9 match)
+                  (srfi srfi-1)
+                  (srfi srfi-26))
+      #:phases
+      #~(modify-phases %standard-phases
+          (add-after 'unpack 'chdir
+            (lambda _ (chdir "faiss/python")))
+          (add-before 'install 'python-build
+            (lambda _
+              ((assoc-ref python:%standard-phases 'build)
+               #:use-setuptools? #t)))
+          (replace 'install
+            (lambda args
+              (apply
+               (assoc-ref python:%standard-phases 'install)
+               #:use-setuptools? #t
+               #:configure-flags ''()
+               args)
+              (for-each
+               delete-file
+               (find-files #$output
+                           "_*faiss_example_external_module\\.(so|py)$"))))
+          ;; Move check phase after 'install.
+          (delete 'check)
+          (add-after 'install 'check
+            (lambda* (#:key inputs outputs tests? #:allow-other-keys)
+              (if tests?
+                  (with-directory-excursion "../../tests"
+                    (let* ((version #$(version-major+minor
+                                       (package-version
+                                        (this-package-input "python-wrapper"))))
+                           (destination (string-append "/lib/python" version
+                                                       "/site-packages/")))
+                      (setenv
+                       "PYTHONPATH"
+                       (string-join
+                        (filter
+                         directory-exists?
+                         (map (match-lambda
+                                ((name . directory)
+                                 (string-append directory destination)))
+                              (append outputs inputs)))
+                        ":")))
+                    (for-each
+                     (lambda (file)
+                       (invoke "python" file))
+                     (remove (cut member <> '(;; External module removed
+                                              "./external_module_test.py"
+                                              ;; Avoid torch dependency
+                                              "./torch_test_contrib.py"
+                                              "./torch_test_neural_net.py"))
+                             (find-files "." "\\.py$"))))
+                  (format #t "test suite not run~%")))))))
+    (native-inputs
+     (list python-scipy))
     (inputs
-     `(("faiss" ,faiss)
-       ("openblas" ,openblas)
-       ("python*" ,python)
-       ("swig" ,swig)))
+     (list faiss openblas python-wrapper swig))
     (propagated-inputs
-     (list python-matplotlib python-numpy))
+     (list python-numpy))
     (description "Faiss is a library for efficient similarity search and
 clustering of dense vectors.  This package provides Python bindings to the
 Faiss library.")))
diff --git a/gnu/packages/patches/faiss-tests-CMakeLists-find-googletest.patch b/gnu/packages/patches/faiss-tests-CMakeLists-find-googletest.patch
new file mode 100644
index 0000000000..5183bac08a
--- /dev/null
+++ b/gnu/packages/patches/faiss-tests-CMakeLists-find-googletest.patch
@@ -0,0 +1,53 @@
+From 9f845321de3bdd2b840c42b977c1c092ac553cc2 Mon Sep 17 00:00:00 2001
+From: Nicolas Graves <[email-masked]>
+Date: Fri, 21 Feb 2025 12:05:59 +0100
+Subject: [PATCH] tests/CMakeLists.txt: Find googletest package from inputs
+
+---
+ tests/CMakeLists.txt | 29 +----------------------------
+ 1 file changed, 1 insertion(+), 28 deletions(-)
+
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+index dfab76e0..16a51b0b 100644
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -48,35 +48,8 @@ if (FAISS_ENABLE_PYTHON)
+   target_link_libraries(faiss_test PUBLIC faiss_example_external_module)
+ endif()
+ 
+-include(FetchContent)
+-FetchContent_Declare(
+-  googletest
+-  GIT_REPOSITORY https://github.com/google/googletest.git
+-  GIT_TAG 58d77fa8070e8cec2dc1ed015d66b454c8d78850 # release-1.12.1
+-  OVERRIDE_FIND_PACKAGE)
+-set(BUILD_GMOCK CACHE BOOL OFF)
+-set(INSTALL_GTEST CACHE BOOL OFF)
+-FetchContent_MakeAvailable(googletest)
+-
+-if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake
+-   AND NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/GTestConfig.cmake)
+-  file(
+-    WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake
+-    [=[
+-include(CMakeFindDependencyMacro)
+-find_dependency(googletest)
+-if(NOT TARGET GTest::GTest)
+-  add_library(GTest::GTest INTERFACE IMPORTED)
+-  target_link_libraries(GTest::GTest INTERFACE GTest::gtest)
+-endif()
+-if(NOT TARGET GTest::Main)
+-  add_library(GTest::Main INTERFACE IMPORTED)
+-  target_link_libraries(GTest::Main INTERFACE GTest::gtest_main)
+-endif()
+-]=])
+-endif()
+-
+ find_package(OpenMP REQUIRED)
++find_package(GTest REQUIRED)
+ find_package(GTest CONFIG REQUIRED)
+ 
+ target_link_libraries(faiss_test PRIVATE
+-- 
+2.48.1
+
-- 
2.48.1

-- 
Best regards,
Nicolas Graves