--- title: "Installing faissR and auditing native capabilities" author: "Stefano Cacciatore" package: faissR output: BiocStyle::html_document: toc: true toc_float: true vignette: > %\VignetteIndexEntry{Installing faissR and auditing native capabilities} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` # Build contract A functional `faissR` installation requires R development headers, `Rcpp >= 1.1.0`, `Biobase`, a C++20 compiler, and ABI-compatible FAISS headers and libraries. `Biobase` supplies the Bioconductor example workflow in the main vignette; the native nearest-neighbour implementation itself does not call Biobase code. Unix builds also require a Fortran compiler; native Windows builds use the C++ exact fallback instead. CUDA, FAISS GPU, and RAPIDS cuVS are optional. They become mandatory only when their strict build switches are set. The package does not vendor these native libraries and never installs a system package manager dependency silently. Install or update `Rcpp` from CRAN before building from source when a Linux distribution supplies an older version. The native metadata constructors require the variadic list-construction API; older versions can fail during compilation. Use `FAISSR_REQUIRE_FAISS=1` for a production or CI build. This makes a missing or unusable FAISS installation fatal. A *diagnostic-only* build can be emitted on explicitly recognized automated targets that do not provide FAISS. Such an artifact can load and explain the missing capability, but it cannot perform a nearest-neighbour search and is not a functional platform result. # Tested combinations * **Functional CPU package check:** macOS arm64 with R 4.6.0, FAISS 1.14.3, libomp 22.1.x, clang 22.1.1, and GNU Fortran 12.2.0. * **Publication CPU/CUDA campaign:** Debian 13 with R 4.5.3, FAISS 1.14.3, cuVS 26.06, CUDA 13.2, and an NVIDIA L40S with driver 595.58.03. The frozen image did not retain the compiler executable and version. * **Linux CPU CI definition:** Ubuntu with the current Bioconductor devel R, FAISS 1.14.3 built from source, and the hosted GCC/GFortran toolchain recorded by the job. * **macOS CPU CI definition:** macOS with the current Bioconductor devel R, static FAISS supplied through an R-macos recipe prefix, and the hosted clang/GFortran toolchain recorded by the job. The CI rows describe tracked workflows. They become release evidence only after the corresponding hosted jobs complete successfully. # Linux CPU-only installation Ubuntu releases do not all provide `libfaiss-dev`. The following reproducible path builds FAISS 1.14.3 without CUDA, Python bindings, or tests and installs it under `/opt/faiss`. ```{bash, eval=FALSE} sudo apt-get update sudo apt-get install -y build-essential cmake ninja-build gfortran \ git libopenblas-dev liblapack-dev git clone --depth 1 --branch v1.14.3 \ https://github.com/facebookresearch/faiss.git faiss-1.14.3 cmake -S faiss-1.14.3 -B faiss-1.14.3/build -G Ninja \ -DFAISS_ENABLE_GPU=OFF -DFAISS_ENABLE_PYTHON=OFF \ -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=ON \ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/faiss cmake --build faiss-1.14.3/build --parallel sudo cmake --install faiss-1.14.3/build FAISS_HOME=/opt/faiss \ FAISSR_REQUIRE_FAISS=1 \ FAISSR_USE_CUDA=0 FAISSR_USE_CUVS=0 \ R CMD INSTALL faissR_0.99.47.tar.gz ``` When the distribution supplies compatible development files, installing `libfaiss-dev`, `libblas-dev`, and `liblapack-dev` and omitting `FAISS_HOME` is sufficient when those libraries match the R toolchain. R's bundled `libRblas`/`libRlapack` omit some single-precision routines required by FAISS, including `ssyrk_`. On Linux, configure checks a small FAISS client by compiling and loading it in a fresh R process. If needed, it adds a complete external LP64 BLAS/LAPACK provider while retaining R's own numerical-library flags. A failed probe stops installation and records the compiler/loader details in `config.log`. ```{bash, eval=FALSE} sudo apt-get install libfaiss-dev libblas-dev liblapack-dev FAISSR_NUMERICAL_LIBS="-llapack -lblas" R CMD INSTALL faissR_0.99.47.tar.gz ``` The explicit `FAISSR_NUMERICAL_LIBS` setting is optional when automatic detection succeeds. It must match FAISS's LP64 ABI; use additional `-L` and runtime-search-path flags for a nonstandard prefix. Do not replace R's `libRblas` or `libRlapack`. The probe verifies linking/loading rather than all possible numerical operations or ABI combinations. ## Optional Linux performance configuration An ABI-compatible LP64 OpenBLAS build is an optional CPU performance configuration for FAISS, not a requirement to replace R's configured BLAS. Benefits depend on the method, matrix shape, query batch size, and threading; graph traversal does not necessarily benefit from a faster dense BLAS. Keep the BLAS, LAPACK, and Fortran link flags reported by `R CMD config`. Do not overwrite `libRblas` or mix incompatible integer or compiler ABIs. When benchmarking FAISS OpenMP parallelism, start with one BLAS thread to avoid nested thread-pool oversubscription. For a pthread OpenBLAS build, for example, start R with `OPENBLAS_NUM_THREADS=1` and choose faissR's `n_threads` explicitly. An OpenMP OpenBLAS build instead shares `OMP_NUM_THREADS` control; check the installed provider before setting thread limits. Compare alternative settings on representative workloads in separate R sessions, and retain the configuration only when observed runtime improves without changing results. This is an opt-in deployment choice, not a modification of publication results. See the [OpenBLAS runtime documentation][openblas-runtime] for provider-specific thread controls. [openblas-runtime]: https://www.openmathlib.org/OpenBLAS/docs/runtime_variables/ # macOS CPU-only installation Bioconductor and CRAN macOS binary builders use the [R-macos recipes](https://github.com/R-macos/recipes) system for static native dependencies. faissR's `configure` detects `/opt/R/arm64` and `/opt/R/x86_64`. The repository contains a candidate FAISS recipe that must pass the upstream arm64 and x86_64 recipe builds before submission. For a source build outside a prepared binary-builder environment, point the package at compatible FAISS and OpenMP prefixes. `configure` does not invoke a system package manager: ```{bash, eval=FALSE} FAISS_HOME=/path/to/faiss \ LIBOMP_HOME=/path/to/openmp \ FAISSR_REQUIRE_FAISS=1 \ R CMD INSTALL faissR_0.99.47.tar.gz ``` Alternatively, pass separate FAISS paths with `--configure-vars='INCLUDE_DIR=... LIB_DIR=...'`. An already active conda or mamba environment is also accepted when it contains `faiss-cpu` and `libomp`; set both `FAISS_HOME` and `LIBOMP_HOME` to `$CONDA_PREFIX`. `configure` never creates or modifies the environment. # Windows CPU-only installation Use an Rtools-compatible FAISS CPU build, not an MSVC binary. Set `FAISS_HOME` to its installation prefix, containing `include/faiss` and `lib/libfaiss.a` or `lib/libfaiss.dll.a`. The configure step compiles and loads a small DLL using the active R toolchain. It checks all required single- and double-precision BLAS/LAPACK symbols before compiling the package, and tries the complete Rtools `-llapack -lblas` libraries when R's own libraries are insufficient. R's `LAPACK_LIBS`, `BLAS_LIBS`, and `FLIBS` are retained. ```{r windows-install, eval=FALSE} Sys.setenv(FAISS_HOME = "C:/local/faiss", FAISSR_REQUIRE_FAISS = "1") install.packages("Rcpp") install.packages("faissR_0.99.47.tar.gz", repos = NULL, type = "source") ``` For nonstandard numerical libraries, set `FAISSR_NUMERICAL_LIBS` to the complete LP64 linker flags. A failed explicit selection is an error, not a silent fallback; inspect `config.log`. Without a compatible FAISS build, only the diagnostic profile is available unless strict mode rejects installation. The reproducible native Windows build recipe and test instructions are in `docs/package-testing.md` in the source repository. # Linux CUDA and cuVS installation The CUDA toolkit, driver, FAISS GPU build, cuVS, R, and C++ runtime must come from one compatible stack. `faissR` never installs or changes an NVIDIA driver. On Debian or Ubuntu, do not add a distribution CUDA metapackage to a server whose driver is managed separately. With NVIDIA's repository, a versioned `cuda-toolkit-X-Y` package installs development tools without the driver; the `cuda` and `cuda-runtime-X-Y` metapackages can include driver packages. Inspect a package-manager simulation before changing a shared machine. Several CUDA toolkits can coexist in separate prefixes. Select one explicitly with `CUDA_HOME`; FAISS GPU and cuVS must have been built for a compatible CUDA stack. After those providers have been installed, use strict switches so that a CPU-only build cannot be mistaken for the requested GPU build: ```{bash, eval=FALSE} CUDA_HOME=/usr/local/cuda \ FAISS_HOME=/opt/faiss-gpu \ CUVS_HOME=/opt/rapids \ FAISSR_REQUIRE_FAISS=1 \ FAISSR_REQUIRE_CUDA=1 \ FAISSR_REQUIRE_CUDA_RUNTIME=1 \ FAISSR_REQUIRE_CUVS=1 \ R CMD INSTALL faissR_0.99.47.tar.gz ``` Configuration compiles and links a small CUDA probe and records the toolkit, runtime, driver API, and device compute capability. A visible GPU is required at configuration only when `FAISSR_REQUIRE_CUDA_RUNTIME=1`; omit that switch for a build image that intentionally has no attached GPU. `FAISSR_CUDA_ARCH` accepts space-separated numeric capabilities such as `"80 90 120"`. The highest requested architecture is also retained as Parallel Thread Execution (PTX) code for forward compatibility; set `FAISSR_CUDA_PTX_ARCH` explicitly to choose another PTX target or to `none` to disable it. CUDA compatibility is reported per component. Native faissR kernels, FAISS GPU, and direct cuVS are separate capabilities, and availability of one does not establish compatibility of the others. The reproducible multi-toolkit test matrix is documented in `.github/package-check/CUDA.md`. Native RAPIDS builds are Linux-oriented; WSL2 is the documented Windows route for CUDA/cuVS. # Audit the installed capability Loading is not enough to establish a functional native installation. Inspect the provider table and run a small CPU search: ```{r capability-audit} library(faissR) backend_info() head(nn_capabilities(runtime = TRUE)) if (faiss_available()) { x <- matrix(seq_len(240), ncol = 6) ans <- nn(x, k = 3, method = "exact", backend = "cpu") stopifnot(identical(dim(ans$indices), c(nrow(x), 3L))) } else { message("Diagnostic-only build: native FAISS searches are unavailable.") } c( faiss_gpu = faiss_gpu_available(), cuda = cuda_available(), cuvs = cuvs_available() ) ``` Do not infer GPU support from `nvidia-smi` alone. The package must have been compiled against the provider and the runtime device must also be available. # Common failures * **FAISS headers or library not found:** no compatible prefix was discovered. Set `FAISS_HOME`, then verify `include/faiss/IndexFlat.h` and `lib/libfaiss.*`. * **`omp.h` not found on macOS:** FAISS headers require an OpenMP runtime that clang cannot see. Use the R-macos recipe/toolchain runtime or set `LIBOMP_HOME` to a compatible prefix. * **The package loads but `faiss_available()` is false:** this is a diagnostic-only artifact. Install from source with FAISS and set `FAISSR_REQUIRE_FAISS=1`. * **Loading reports an undefined BLAS symbol such as `ssyrk_`:** R's bundled libraries may lack single-precision FAISS dependencies. Install complete LP64 BLAS/LAPACK development libraries. The Linux compile/load probe records failures in `config.log`; use `FAISSR_NUMERICAL_LIBS` to select a custom provider. Adding R's link flags alone is not always sufficient. * **`libfaiss` or `GLIBCXX_*` load failure:** the runtime linker and compiler ABI do not match. Use one compiler/runtime stack and expose its library directory through the platform linker path. * **CUDA requested but `nvcc` is missing:** the CUDA toolkit was not found. Set `CUDA_HOME` or `NVCC`, then check `nvcc --version`. * **The CUDA compiler/linker probe fails:** the selected compiler, headers, runtime libraries, or architecture flags do not form a coherent toolkit. Inspect `config.log`; do not repair this by replacing the host driver. * **The CUDA runtime probe reports no device:** run `nvidia-smi`, then compare the compiled toolkit, runtime, driver API, and compute capability shown by `backend_info()`. A build-only host may omit `FAISSR_REQUIRE_CUDA_RUNTIME=1`. * **cuVS route unavailable:** cuVS was absent at compile time or cannot load at runtime. Set `CUVS_HOME`, use `FAISSR_REQUIRE_CUVS=1`, and repair the runtime library path. # Checks and licenses The source tarball should be checked in the same strict environment used for installation: ```{bash, eval=FALSE} R CMD build . FAISS_HOME=/opt/faiss FAISSR_REQUIRE_FAISS=1 \ R CMD check --as-cran faissR_0.99.47.tar.gz Rscript -e 'BiocCheck::BiocCheck("faissR_0.99.47.tar.gz", `new-package`=TRUE)' ``` `faissR` and FAISS use the Expat License. R package metadata records this license template as `MIT + file LICENSE`. cuVS is Apache-2.0-licensed, and CUDA is governed by the NVIDIA CUDA SDK EULA. These external components are supplied by the system and are not redistributed in the package. The installed `THIRD_PARTY_LICENSES.md` records links and the distribution boundary. # Session information ```{r session-info} sessionInfo() ```