spack/var/spack/repos/builtin/packages/faiss/package.py

190 lines
7.3 KiB
Python
Raw Normal View History

# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
from spack.package import *
class Faiss(AutotoolsPackage, CMakePackage, CudaPackage):
"""Faiss is a library for efficient similarity search and clustering of
dense vectors.
Faiss contains algorithms that search in sets of vectors of any size, up
to ones that possibly do not fit in RAM. It also contains supporting code
for evaluation and parameter tuning. Faiss is written in C++ with
complete wrappers for Python/numpy. Some of the most useful algorithms
are implemented on the GPU. It is developed by Facebook AI Research.
"""
homepage = "https://github.com/facebookresearch/faiss"
url = "https://github.com/facebookresearch/faiss/archive/v1.6.3.tar.gz"
maintainers("bhatiaharsh", "rblake-llnl", "lpottier")
build_system(
conditional("cmake", when="@1.7:"), conditional("autotools", when="@:1.6"), default="cmake"
)
2023-04-27 00:15:52 +08:00
version("1.7.4", sha256="d9a7b31bf7fd6eb32c10b7ea7ff918160eed5be04fe63bb7b4b4b5f2bbde01ad")
version("1.7.2", sha256="d49b4afd6a7a5b64f260a236ee9b2efb760edb08c33d5ea5610c2f078a5995ec")
version("1.6.3", sha256="e1a41c159f0b896975fbb133e0240a233af5c9286c09a28fde6aefff5336e542")
version("1.5.3", sha256="b24d347b0285d01c2ed663ccc7596cd0ea95071f3dd5ebb573ccfc28f15f043b")
variant("python", default=False, description="Build Python bindings")
variant("shared", default=False, description="Build shared library")
variant("tests", default=False, description="Build Tests")
conflicts("+tests", when="~python", msg="+tests must be accompanied by +python")
depends_on("cmake@3.17:", when="build_system=cmake", type="build")
extends("python", when="+python")
depends_on("python@3.7:", when="+python", type=("build", "run"))
depends_on("py-pip", when="+python", type="build")
depends_on("py-wheel", when="+python", type="build")
depends_on("py-setuptools", when="+python", type="build")
depends_on("py-numpy", when="+python", type=("build", "run"))
depends_on("swig@4", when="+python", type="build")
depends_on("py-scipy", when="+python+tests", type=("build", "run"))
depends_on("blas")
# patch for v1.5.3
# faiss assumes that the "source directory" will always
# be called "faiss" (not spack-src or faiss-1.5.3)
# so, we will have to create a symlink to self (faiss did that in 1.6.3)
# and add an include path
patch("fixes-in-v1.5.3.patch", when="@1.5.3")
# patch for v1.6.3
# for v1.6.3, GPU build has a bug (two files need to be deleted)
# https://github.com/facebookresearch/faiss/issues/1159
# also, some include paths in gpu/tests/Makefile are missing
patch("fixes-in-v1.6.3.patch", when="@1.6.3")
# patch for v1.7.2
# a shared object is missing in the python/setup.py
# https://github.com/facebookresearch/faiss/issues/2063
# https://github.com/facebookresearch/faiss/pull/2062
# a header is missing in a test file
# https://github.com/facebookresearch/faiss/issues/2300
patch("fixes-in-v1.7.2.patch", when="@1.7.2")
def setup_run_environment(self, env):
if "+python" in self.spec:
env.prepend_path("PYTHONPATH", python_platlib)
if self.spec.satisfies("platform=darwin"):
env.append_path(
"DYLD_FALLBACK_LIBRARY_PATH", os.path.join(python_platlib, "faiss")
)
else:
env.append_path("LD_LIBRARY_PATH", os.path.join(python_platlib, "faiss"))
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
def cmake_args(self):
spec = self.spec
args = [
self.define_from_variant("BUILD_SHARED_LIBS", "shared"),
self.define_from_variant("FAISS_ENABLE_PYTHON", "python"),
self.define_from_variant("FAISS_ENABLE_GPU", "cuda"),
self.define_from_variant("BUILD_TESTING", "tests"),
self.define("FAISS_OPT_LEVEL", "generic"),
]
if "+python" in spec:
pyexe = spec["python"].command.path
args.append(self.define("Python_EXECUTABLE", pyexe))
if "+cuda" in spec:
key = "CMAKE_CUDA_ARCHITECTURES"
args.append(self.define_from_variant(key, "cuda_arch"))
# args.append(self.define_from_variant(
# 'CMAKE_CUDA_STANDARD', 'cudastd'))
return args
def install(self, pkg, spec, prefix):
super().install(pkg, spec, prefix)
if "+python" in spec:
class CustomPythonPipBuilder(spack.build_systems.python.PythonPipBuilder):
def __init__(self, pkg, build_dirname):
spack.build_systems.python.PythonPipBuilder.__init__(self, pkg)
self.build_dirname = build_dirname
@property
def build_directory(self):
return os.path.join(self.pkg.stage.path, self.build_dirname, "faiss", "python")
customPip = CustomPythonPipBuilder(pkg, self.build_dirname)
customPip.install(pkg, spec, prefix)
class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder):
def configure_args(self):
args = []
args.extend(self.with_or_without("cuda", activation_value="prefix"))
return args
def build(self, pkg, spec, prefix):
make()
if "+python" in self.spec:
make("-C", "python")
# CPU tests
if "+tests" in self.spec:
with working_dir("tests"):
make("gtest")
make("tests")
# GPU tests
if "+tests+cuda" in self.spec:
with working_dir(os.path.join("gpu", "test")):
make("gtest")
make("build") # target added by the patch
make("demo_ivfpq_indexing_gpu")
def install(self, pkg, spec, prefix):
make("install")
if "+python" in self.spec:
with working_dir("python"):
args = std_pip_args + ["--prefix=" + prefix, "."]
PythonPackage: install packages with pip (#27798) * Use pip to bootstrap pip * Bootstrap wheel from source * Update PythonPackage to install using pip * Update several packages * Add wheel as base class dep * Build phase no longer exists * Add py-poetry package, fix py-flit-core bootstrapping * Fix isort build * Clean up many more packages * Remove unused import * Fix unit tests * Don't directly run setup.py * Typo fix * Remove unused imports * Fix issues caught by CI * Remove custom setup.py file handling * Use PythonPackage for installing wheels * Remove custom phases in PythonPackages * Remove <phase>_args methods * Remove unused import * Fix various packages * Try to test Python packages directly in CI * Actually run the pipeline * Fix more packages * Fix mappings, fix packages * Fix dep version * Work around bug in concretizer * Various concretization fixes * Fix gitlab yaml, packages * Fix typo in gitlab yaml * Skip more packages that fail to concretize * Fix? jupyter ecosystem concretization issues * Solve Jupyter concretization issues * Prevent duplicate entries in PYTHONPATH * Skip fenics-dolfinx * Build fewer Python packages * Fix missing npm dep * Specify image * More package fixes * Add backends for every from-source package * Fix version arg * Remove GitLab CI stuff, add py-installer package * Remove test deps, re-add install_options * Function declaration syntax fix * More build fixes * Update spack create template * Update PythonPackage documentation * Fix documentation build * Fix unit tests * Remove pip flag added only in newer pip * flux: add explicit dependency on jsonschema * Update packages that have been added since this was branched off of develop * Move Python 2 deprecation to a separate PR * py-neurolab: add build dep on py-setuptools * Use wheels for pip/wheel * Allow use of pre-installed pip for external Python * pip -> python -m pip * Use python -m pip for all packages * Fix py-wrapt * Add both platlib and purelib to PYTHONPATH * py-pyyaml: setuptools is needed for all versions * py-pyyaml: link flags aren't needed * Appease spack audit packages * Some build backend is required for all versions, distutils -> setuptools * Correctly handle different setup.py filename * Use wheels for py-tomli to avoid circular dep on py-flit-core * Fix busco installation procedure * Clarify things in spack create template * Test other Python build backends * Undo changes to busco * Various fixes * Don't test other backends
2022-01-15 02:37:57 +08:00
pip(*args)
if "+tests" not in self.spec:
return
if not os.path.isdir(self.prefix.bin):
os.makedirs(self.prefix.bin)
def _prefix_and_install(file):
os.rename(file, "faiss_" + file)
install("faiss_" + file, self.prefix.bin)
# CPU tests
with working_dir("tests"):
# rename the exec to keep consistent with gpu tests
os.rename("tests", "TestCpu")
_prefix_and_install("TestCpu")
# GPU tests
if "+cuda" in self.spec:
with working_dir(os.path.join("gpu", "test")):
_prefix_and_install("TestGpuIndexFlat")
_prefix_and_install("TestGpuIndexBinaryFlat")
_prefix_and_install("TestGpuIndexIVFFlat")
_prefix_and_install("TestGpuIndexIVFPQ")
_prefix_and_install("TestGpuMemoryException")
_prefix_and_install("TestGpuSelect")
_prefix_and_install("demo_ivfpq_indexing_gpu")
@run_after("configure")
def _fix_makefile(self):
# spack injects its own optimization flags
makefile = FileFilter("makefile.inc")
makefile.filter("CPUFLAGS = -mavx2 -mf16c", "#CPUFLAGS = -mavx2 -mf16c")