mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-20 21:14:14 +08:00
When we use pytorch with unregistered blas, spack set BLAS=Generic. pytorch is searched only libblas. If the blas package's blas library name is not libblas, spack install py-torch is failed. This PR set blas lirary names to GENERIC_BLAS_LIBRARIES environment variable, and py-torch is found blas library. Pull Request resolved: https://github.com/pytorch/pytorch/pull/74269 Approved by: https://github.com/kit1980
419 lines
11 KiB
CMake
419 lines
11 KiB
CMake
# - Find BLAS library
|
|
# This module finds an installed fortran library that implements the BLAS
|
|
# linear-algebra interface (see http://www.netlib.org/blas/).
|
|
# The list of libraries searched for is taken
|
|
# from the autoconf macro file, acx_blas.m4 (distributed at
|
|
# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
|
|
#
|
|
# This module sets the following variables:
|
|
# BLAS_FOUND - set to true if a library implementing the BLAS interface is found.
|
|
# BLAS_INFO - name of the detected BLAS library.
|
|
# BLAS_F2C - set to true if following the f2c return convention
|
|
# BLAS_LIBRARIES - list of libraries to link against to use BLAS
|
|
# BLAS_INCLUDE_DIR - include directory
|
|
|
|
# Do nothing if BLAS was found before
|
|
IF(NOT BLAS_FOUND)
|
|
|
|
SET(BLAS_LIBRARIES)
|
|
SET(BLAS_INCLUDE_DIR)
|
|
SET(BLAS_INFO)
|
|
SET(BLAS_F2C)
|
|
|
|
SET(WITH_BLAS "" CACHE STRING "Blas type [accelerate/acml/atlas/blis/generic/goto/mkl/open/veclib]")
|
|
|
|
# Old FindBlas
|
|
INCLUDE(CheckCSourceRuns)
|
|
INCLUDE(CheckFortranFunctionExists)
|
|
|
|
MACRO(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list)
|
|
# This macro checks for the existence of the combination of fortran libraries
|
|
# given by _list. If the combination is found, this macro checks (using the
|
|
# Check_Fortran_Function_Exists macro) whether can link against that library
|
|
# combination using the name of a routine given by _name using the linker
|
|
# flags given by _flags. If the combination of libraries is found and passes
|
|
# the link test, LIBRARIES is set to the list of complete library paths that
|
|
# have been found. Otherwise, LIBRARIES is set to NOTFOUND.
|
|
# N.B. _prefix is the prefix applied to the names of all cached variables that
|
|
# are generated internally and marked advanced by this macro.
|
|
|
|
set(__list)
|
|
foreach(_elem ${_list})
|
|
if(__list)
|
|
set(__list "${__list} - ${_elem}")
|
|
else(__list)
|
|
set(__list "${_elem}")
|
|
endif(__list)
|
|
endforeach(_elem)
|
|
message(STATUS "Checking for [${__list}]")
|
|
|
|
set(_libraries_work TRUE)
|
|
set(${LIBRARIES})
|
|
set(_combined_name)
|
|
foreach(_library ${_list})
|
|
set(_combined_name ${_combined_name}_${_library})
|
|
if(_libraries_work)
|
|
if ( WIN32 )
|
|
find_library(${_prefix}_${_library}_LIBRARY
|
|
NAMES ${_library}
|
|
PATHS ENV LIB
|
|
PATHS ENV PATH )
|
|
endif ( WIN32 )
|
|
if ( APPLE )
|
|
find_library(${_prefix}_${_library}_LIBRARY
|
|
NAMES ${_library}
|
|
PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 /opt/OpenBLAS/lib /usr/lib/aarch64-linux-gnu
|
|
ENV DYLD_LIBRARY_PATH )
|
|
else ( APPLE )
|
|
find_library(${_prefix}_${_library}_LIBRARY
|
|
NAMES ${_library}
|
|
PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 /opt/OpenBLAS/lib /usr/lib/aarch64-linux-gnu ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}
|
|
ENV LD_LIBRARY_PATH )
|
|
endif( APPLE )
|
|
mark_as_advanced(${_prefix}_${_library}_LIBRARY)
|
|
set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
|
|
set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
|
|
MESSAGE(STATUS " Library ${_library}: ${${_prefix}_${_library}_LIBRARY}")
|
|
endif(_libraries_work)
|
|
endforeach(_library ${_list})
|
|
if(_libraries_work)
|
|
# Test this combination of libraries.
|
|
set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}})
|
|
if (CMAKE_Fortran_COMPILER_WORKS)
|
|
check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS)
|
|
else (CMAKE_Fortran_COMPILER_WORKS)
|
|
check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
|
|
endif(CMAKE_Fortran_COMPILER_WORKS)
|
|
set(CMAKE_REQUIRED_LIBRARIES)
|
|
mark_as_advanced(${_prefix}${_combined_name}_WORKS)
|
|
set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
|
|
endif(_libraries_work)
|
|
if(NOT _libraries_work)
|
|
set(${LIBRARIES} NOTFOUND)
|
|
endif(NOT _libraries_work)
|
|
endmacro(Check_Fortran_Libraries)
|
|
|
|
# Intel MKL?
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "mkl")))
|
|
FIND_PACKAGE(MKL)
|
|
IF(MKL_FOUND)
|
|
SET(BLAS_INFO "mkl")
|
|
SET(BLAS_LIBRARIES ${MKL_LIBRARIES})
|
|
SET(BLAS_INCLUDE_DIR ${MKL_INCLUDE_DIR})
|
|
SET(BLAS_VERSION ${MKL_VERSION})
|
|
ENDIF(MKL_FOUND)
|
|
endif()
|
|
|
|
#BLIS?
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "blis")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"blis")
|
|
if(BLAS_LIBRARIES)
|
|
set(BLAS_INFO "blis")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
# Apple BLAS library?
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "accelerate")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"Accelerate")
|
|
if (BLAS_LIBRARIES)
|
|
set(BLAS_INFO "accelerate")
|
|
set(BLAS_IS_ACCELERATE 1)
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "veclib")))
|
|
FIND_PACKAGE(vecLib)
|
|
if(vecLib_FOUND)
|
|
SET(BLAS_INFO "veclib")
|
|
else()
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"vecLib")
|
|
if (BLAS_LIBRARIES)
|
|
set(BLAS_INFO "veclib")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "flexi")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"flexiblas")
|
|
if(BLAS_LIBRARIES)
|
|
set(BLAS_INFO "flexi")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "open")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"openblas")
|
|
if(BLAS_LIBRARIES)
|
|
set(BLAS_INFO "open")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "open")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"openblas;pthread;m")
|
|
if(BLAS_LIBRARIES)
|
|
set(BLAS_INFO "open")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "open")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"openblas;pthread;m;gomp")
|
|
if(BLAS_LIBRARIES)
|
|
set(BLAS_INFO "open")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES) AND (WIN32)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "open")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"libopenblas")
|
|
if(BLAS_LIBRARIES)
|
|
set(BLAS_INFO "open")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "goto")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"goto2;gfortran")
|
|
if (BLAS_LIBRARIES)
|
|
set(BLAS_INFO "goto")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "goto")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"goto2;gfortran;pthread")
|
|
if (BLAS_LIBRARIES)
|
|
set(BLAS_INFO "goto")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "acml")))
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"acml;gfortran")
|
|
if (BLAS_LIBRARIES)
|
|
set(BLAS_INFO "acml")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "FLAME")))
|
|
# FLAME's blis library (https://github.com/flame/blis)
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"blis")
|
|
if (BLAS_LIBRARIES)
|
|
set(BLAS_INFO "FLAME")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "atlas")))
|
|
FIND_PACKAGE(Atlas)
|
|
if(Atlas_FOUND)
|
|
SET(BLAS_INFO "atlas")
|
|
else()
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"ptf77blas;atlas;gfortran")
|
|
if (BLAS_LIBRARIES)
|
|
set(BLAS_INFO "atlas")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
endif()
|
|
|
|
# Generic BLAS library?
|
|
if((NOT BLAS_LIBRARIES)
|
|
AND ((NOT WITH_BLAS) OR (WITH_BLAS STREQUAL "generic")))
|
|
if(ENV{GENERIC_BLAS_LIBRARIES} STREQUAL "")
|
|
set(GENERIC_BLAS "blas")
|
|
else()
|
|
set(GENERIC_BLAS $ENV{GENERIC_BLAS_LIBRARIES})
|
|
endif()
|
|
check_fortran_libraries(
|
|
BLAS_LIBRARIES
|
|
BLAS
|
|
sgemm
|
|
""
|
|
"${GENERIC_BLAS}")
|
|
if (BLAS_LIBRARIES)
|
|
set(BLAS_INFO "generic")
|
|
endif(BLAS_LIBRARIES)
|
|
endif()
|
|
|
|
# Determine if blas was compiled with the f2c conventions
|
|
IF (BLAS_LIBRARIES)
|
|
# Push host architecture when cross-compiling otherwise check would fail
|
|
# when cross-compiling for arm64 on x86_64
|
|
cmake_push_check_state(RESET)
|
|
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_ARCHITECTURES MATCHES "^(x86_64|arm64)$")
|
|
list(APPEND CMAKE_REQUIRED_FLAGS "-arch ${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
|
endif()
|
|
|
|
# Set values through env variables if cross compiling
|
|
IF (CMAKE_CROSSCOMPILING)
|
|
IF("$ENV{PYTORCH_BLAS_F2C}" STREQUAL "ON")
|
|
SET(BLAS_F2C TRUE)
|
|
ELSE()
|
|
SET(BLAS_F2C FALSE)
|
|
ENDIF()
|
|
|
|
IF("$ENV{PYTORCH_BLAS_USE_CBLAS_DOT}" STREQUAL "ON")
|
|
SET(BLAS_USE_CBLAS_DOT TRUE)
|
|
ELSE()
|
|
SET(BLAS_USE_CBLAS_DOT FALSE)
|
|
ENDIF()
|
|
ELSE ()
|
|
SET(CMAKE_REQUIRED_LIBRARIES ${BLAS_LIBRARIES})
|
|
CHECK_C_SOURCE_RUNS("
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
float x[4] = { 1, 2, 3, 4 };
|
|
float y[4] = { .1, .01, .001, .0001 };
|
|
int four = 4;
|
|
int one = 1;
|
|
extern double sdot_();
|
|
int main() {
|
|
int i;
|
|
double r = sdot_(&four, x, &one, y, &one);
|
|
exit((float)r != (float).1234);
|
|
}" BLAS_F2C_DOUBLE_WORKS )
|
|
CHECK_C_SOURCE_RUNS("
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
float x[4] = { 1, 2, 3, 4 };
|
|
float y[4] = { .1, .01, .001, .0001 };
|
|
int four = 4;
|
|
int one = 1;
|
|
extern float sdot_();
|
|
int main() {
|
|
int i;
|
|
double r = sdot_(&four, x, &one, y, &one);
|
|
exit((float)r != (float).1234);
|
|
}" BLAS_F2C_FLOAT_WORKS )
|
|
IF (BLAS_F2C_DOUBLE_WORKS AND NOT BLAS_F2C_FLOAT_WORKS)
|
|
MESSAGE(STATUS "This BLAS uses the F2C return conventions")
|
|
SET(BLAS_F2C TRUE)
|
|
ELSE (BLAS_F2C_DOUBLE_WORKS AND NOT BLAS_F2C_FLOAT_WORKS)
|
|
SET(BLAS_F2C FALSE)
|
|
ENDIF(BLAS_F2C_DOUBLE_WORKS AND NOT BLAS_F2C_FLOAT_WORKS)
|
|
CHECK_C_SOURCE_RUNS("
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
float x[4] = { 1, 2, 3, 4 };
|
|
float y[4] = { .1, .01, .001, .0001 };
|
|
extern float cblas_sdot();
|
|
int main() {
|
|
int i;
|
|
double r = cblas_sdot(4, x, 1, y, 1);
|
|
exit((float)r != (float).1234);
|
|
}" BLAS_USE_CBLAS_DOT )
|
|
IF (BLAS_USE_CBLAS_DOT)
|
|
SET(BLAS_USE_CBLAS_DOT TRUE)
|
|
ELSE (BLAS_USE_CBLAS_DOT)
|
|
SET(BLAS_USE_CBLAS_DOT FALSE)
|
|
ENDIF(BLAS_USE_CBLAS_DOT)
|
|
SET(CMAKE_REQUIRED_LIBRARIES)
|
|
ENDIF(CMAKE_CROSSCOMPILING)
|
|
cmake_pop_check_state()
|
|
ENDIF(BLAS_LIBRARIES)
|
|
|
|
# Blas has bfloat16 support?
|
|
IF(BLAS_LIBRARIES)
|
|
SET(CMAKE_REQUIRED_LIBRARIES ${BLAS_LIBRARIES})
|
|
check_function_exists("sbgemm_" BLAS_HAS_SBGEMM)
|
|
set(CMAKE_REQUIRED_LIBRARIES)
|
|
IF(BLAS_HAS_SBGEMM)
|
|
add_compile_options(-DBLAS_HAS_SBGEMM)
|
|
ENDIF(BLAS_HAS_SBGEMM)
|
|
ENDIF(BLAS_LIBRARIES)
|
|
|
|
# epilogue
|
|
|
|
if(BLAS_LIBRARIES)
|
|
set(BLAS_FOUND TRUE)
|
|
else(BLAS_LIBRARIES)
|
|
set(BLAS_FOUND FALSE)
|
|
endif(BLAS_LIBRARIES)
|
|
|
|
IF (NOT BLAS_FOUND AND BLAS_FIND_REQUIRED)
|
|
message(FATAL_ERROR "Cannot find a library with BLAS API. Please specify library location.")
|
|
ENDIF(NOT BLAS_FOUND AND BLAS_FIND_REQUIRED)
|
|
IF(NOT BLAS_FIND_QUIETLY)
|
|
IF(BLAS_FOUND)
|
|
MESSAGE(STATUS "Found a library with BLAS API (${BLAS_INFO}). Full path: (${BLAS_LIBRARIES})")
|
|
ELSE(BLAS_FOUND)
|
|
MESSAGE(STATUS "Cannot find a library with BLAS API. Not using BLAS.")
|
|
ENDIF(BLAS_FOUND)
|
|
ENDIF(NOT BLAS_FIND_QUIETLY)
|
|
|
|
# Do nothing is BLAS was found before
|
|
ENDIF(NOT BLAS_FOUND)
|