|  | # - 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) |