# Copyright 2025 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 EAPI=8 inherit cmake git-r3 multilib toolchain-funcs DESCRIPTION="A BLAS and LAPACK wrapper library with runtime exchangable backends" HOMEPAGE=" https://www.mpi-magdeburg.mpg.de/projects/flexiblas/ https://gitlab.mpi-magdeburg.mpg.de/software/flexiblas-release/ " EGIT_REPO_URI=" https://gitlab.mpi-magdeburg.mpg.de/software/flexiblas-release.git " # BSD for vendored cblas/lapacke LICENSE="LGPL-3+ BSD" SLOT="0" IUSE="blis index64 mkl openblas openmp system-blas tbb test" RESTRICT="!test? ( test )" # flexiblas only supports gnu-openmp using clang/gcc DEPEND=" sci-libs/lapack:=[deprecated,index64(-)?] blis? ( sci-libs/blis:=[-64bit-index(-),index64(-)?] ) mkl? ( sci-libs/mkl:=[tbb?] openmp? ( sci-libs/mkl[gnu-openmp] ) ) openblas? ( sci-libs/openblas:=[index64(-)?] ) system-blas? ( sci-libs/lapack[flexiblas(-)] ) " RDEPEND=" ${DEPEND} system-blas? ( !app-eselect/eselect-blas !app-eselect/eselect-cblas !app-eselect/eselect-lapack !sci-libs/lapack[-flexiblas(-)] !=sci-libs/blas-lapack-aux-wrapper-0-r0 ) " PDEPEND=" system-blas? ( >=sci-libs/blas-lapack-aux-wrapper-0-r1[index64?] ) " pkg_pretend() { if [[ ${MERGE_TYPE} != binary ]] && use openmp; then tc-check-openmp fi } pkg_setup() { if [[ ${MERGE_TYPE} != binary ]] && use openmp; then tc-check-openmp fi } src_prepare() { cmake_src_prepare # remove bundled netlib blas/lapack # (we still need vendored cblas/lapacke) rm -r contributed/lapack-* || die } src_configure() { BACKENDS=( $(usev blis) $(usev openblas) ) local extra=${BACKENDS[*]} local libdir="${ESYSROOT}/usr/$(get_libdir)" local mycmakeargs=( -DTESTS=$(usex test) -DCBLAS=ON -DINTEGER8=OFF -DLAPACK=ON -DLINK_OPENMP=$(usex openmp) -DEXAMPLES=OFF # prefer OpenBLAS if available -DFLEXIBLAS_DEFAULT=$(usex openblas openblas netlib) # we need to enable autodetection for mkl -DBLAS_AUTO_DETECT=ON # ...so we need to explicitly disable autodetecting other libraries # that would be pinned to their openmp/pthread/serial variants -DOpenBLASSerial=OFF -DOpenBLASPThread=OFF -DOpenBLASOpenMP=OFF -DOpenBLASSerial64=OFF -DOpenBLASPThread64=OFF -DOpenBLASOpenMP64=OFF -DBlisSerial=OFF -DBlisPThread=OFF -DBlisOpenMP=OFF -DBlisSerial64=OFF -DBlisPThread64=OFF -DBlisOpenMP64=OFF # variants we use autodetection for -DMklSerial=$(usex mkl ON OFF) -DMklOpenMP=$(usex mkl "$(usex openmp ON OFF)" OFF) -DMklTBB=$(usex mkl "$(usex tbb ON OFF)" OFF) # unsupported -DCMAKE_DISABLE_FIND_PACKAGE_nvpl=ON -DATLAS=OFF -DTATLAS=OFF # and then enable our custom names via EXTRA -DEXTRA="${extra// /;}" # respect CFLAGS -DLTO=OFF # these are used only with -DEXTRA -Dblis_LIBRARY="${libdir}/libblis.so" -Dopenblas_LIBRARY="${libdir}/libopenblas.so" ) # use system sci-libs/lapack if use system-blas; then # this is sci-libs/lapack[flexiblas] install mycmakeargs+=( -DSYS_BLAS_LIBRARY="${libdir}/libblas-reference.so" -DSYS_LAPACK_LIBRARY="${libdir}/liblapack-reference.so" ) else mycmakeargs+=( -DSYS_BLAS_LIBRARY="${libdir}/libblas.so" -DSYS_LAPACK_LIBRARY="${libdir}/liblapack.so" ) fi cmake_src_configure if use index64; then mycmakeargs+=( -DINTEGER8=ON -Dblis_LIBRARY="${libdir}/libblis64.so" -Dopenblas_LIBRARY="${libdir}/libopenblas64.so" ) if use system-blas; then # this is sci-libs/lapack[flexiblas] install mycmakeargs+=( -DSYS_BLAS_LIBRARY="${libdir}/libblas64-reference.so" -DSYS_LAPACK_LIBRARY="${libdir}/liblapack64-reference.so" ) else mycmakeargs+=( -DSYS_BLAS_LIBRARY="${libdir}/libblas64.so" -DSYS_LAPACK_LIBRARY="${libdir}/liblapack64.so" ) fi BUILD_DIR=${BUILD_DIR}-ilp64 cmake_src_configure fi BACKENDS+=( netlib ) BACKENDS_ILP64=( "${BACKENDS[@]}" ) if use mkl; then BACKENDS+=( MklSerial $(usev openmp MklOpenMP) $(usev tbb MklTBB) ) BACKENDS_ILP64+=( MklSerial64 $(usev openmp MklOpenMP64) $(usev tbb MklTBB64) ) fi } src_compile() { cmake_src_compile use index64 && BUILD_DIR=${BUILD_DIR}-ilp64 cmake_src_compile } my_test() { # We run tests in parallel, so avoid having n^2 threads. local -x BLIS_NUM_THREADS=1 local -x MKL_NUM_THREADS=1 local -x OMP_NUM_THREADS=1 local -x OPENBLAS_NUM_THREADS=1 local failures=() local backend for backend in "${@}"; do # TODO: remove this, and XFAIL them properly when cmake.eclass # is fixed to respect nonfatal, https://bugs.gentoo.org/961929 if [[ ${backend} == Mkl* ]]; then einfo "Skipping ${backend} tests, XFAIL" continue fi local -x FLEXIBLAS_TEST=${backend} local log=${BUILD_DIR}/Testing/Temporary/LastTest.log einfo "Testing backend ${backend}" if ! nonfatal cmake_src_test; then failures+=( "${backend}" ) fi if grep -q 'BLAS backend .* not found' "${log}"; then die "Backend ${backend} failed to load while testing, see ${log}" fi done if [[ ${failures[@]} ]]; then die "Test runs failed for backends: ${failures[*]}" fi } src_test() { my_test "${BACKENDS[@]}" use index64 && BUILD_DIR=${BUILD_DIR}-ilp64 my_test "${BACKENDS_ILP64[@]}" } verify_backends() { local lib=${1} shift cd "${ED}/usr/$(get_libdir)/${lib}" || die local missing=() local backend for backend in "${@}"; do if [[ ! -f libflexiblas_${backend,,}$(get_libname) ]]; then missing+=( "${backend}" ) fi done if [[ ${missing[@]} ]]; then die "Not all requested ${lib} backends built. Missing: ${missing[*]}" fi } src_install() { cmake_src_install use index64 && BUILD_DIR=${BUILD_DIR}-ilp64 cmake_src_install # Verify built backends. verify_backends flexiblas "${BACKENDS[@]}" use index64 && verify_backends flexiblas64 "${BACKENDS_ILP64[@]}" # Install symlinks for system BLAS / LAPACK use. if use system-blas; then local libdir="/usr/$(get_libdir)" local fn suffix for fn in cblas.h lapack.h lapacke{,_config,_mangling,_utils}.h; do dosym "flexiblas/${fn}" "/usr/include/${fn}" done for suffix in '' $(usev index64 64); do for fn in blas cblas lapack lapacke; do dosym "libflexiblas${suffix}.so.3" \ "${libdir}/lib${fn}${suffix}.so.3" done done fi } pkg_postinst() { if use system-blas; then # eselect-{blas,lapack} doesn't clean up its configs local prev_opt=$(shopt -p nullglob) shopt -s nullglob local files=( "${EROOT}"/etc/ld.so.conf.d/81-blas-*.conf "${EROOT}"/etc/ld.so.conf.d/82-lapack-*.conf ) ${prev_opt} if [[ ${files[@]} ]]; then rm -v "${files[@]}" fi fi }