Files
blis/gtestsuite/CMakeLists.txt
Edward Smyth 8d4881c4fd GTestSuite: add option to test blis_impl layer
Add BLAS_TEST_IMPL option for TEST_INTERFACE to test the
wrapper layer underneath BLAS and CBLAS interfaces. This is
particularly useful if building a BLIS library with these
interfaces disabled, e.g.

   ./configure --disable-blas amdzen
or
   cmake . -DENABLE_BLAS=OFF -DBLIS_CONFIG_FAMILY=amdzen

The ?_blis_impl wrappers should have the same arguments as the
BLAS interfaces, thus we define TEST_BLAS_LIKE as an additional
definition for convenience when selecting tests and options in
the C++ files.

AMD-Internal: [CPUPL-5650]
Change-Id: I0275a387563f3efc2b40029950c8569956f2df7b
2024-09-16 09:53:56 -04:00

366 lines
16 KiB
CMake

#[=[
BLIS
An object-based framework for developing high-performance BLAS-like
libraries.
Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name(s) of the copyright holder(s) nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
]=]
cmake_minimum_required(VERSION 3.22.0)
set(CMAKE_CXX_COMPILER ${CXX_COMPILER})
set(CMAKE_CXX_STANDARD 17)
project(BLIS_GtestSuite)
enable_testing()
# Set variable if the platform is Linux based.
if(UNIX AND NOT APPLE)
set(LINUX TRUE)
endif()
# Throw an error if the platform is Apple.
if(APPLE)
message(FATAL_ERROR "Build system does not support Apple platform.")
endif()
# Set the path to the BLIS installation.
set(BLIS_PATH $ENV{AOCL_BLAS_PATH} CACHE STRING "Setting the path to a BLIS installation that needs testing.")
if(BLIS_PATH STREQUAL "")
message(FATAL_ERROR "Need to provide a BLIS installation path during CMake invocation.\
Set environment variable \$AOCL_BLAS_PATH or set the cmake variable directly using\
$ cmake .. -DBLIS_PATH=/home/username/blis_installation")
endif()
# Set the path to BLIS include directory.
# Adding both paths so that testing works with installation using configure/Make or CMake.
set(BLIS_INCLUDE ${BLIS_PATH}/include/ ${BLIS_PATH}/include/blis CACHE STRING "Setting the path to the BLIS headers.")
set(BLIS_LIB_PATH ${BLIS_PATH}/lib CACHE STRING "Setting the path to the BLIS library.")
# Use REF_BLAS to set the library that will be used for reference results.
set(REF_CBLAS "Netlib" CACHE STRING "Library used to compute reference results.")
# Use REF_LIB to set the library that will be used for reference results.
set(REF_LIB $ENV{CBLAS_REF_LIB} CACHE STRING "Path to a shared library that will be used as a reference.")
# Set OpenMP as the default option
set(ENABLE_THREADING "openmp" CACHE STRING "the threading flag")
# Set the possible values of theading libraries for cmake-gui
if(WIN32)
set_property(CACHE ENABLE_THREADING PROPERTY STRINGS "openmp" "no")
if( NOT ((ENABLE_THREADING STREQUAL "openmp") OR (ENABLE_THREADING STREQUAL "no")) )
message(FATAL_ERROR "ENABLE_THREADING option '${ENABLE_THREADING}' is not supported. Please use one of the following options \
during CMake invokation: openmp, no")
endif()
else()
set_property(CACHE ENABLE_THREADING PROPERTY STRINGS "openmp" "pthreads" "no")
if( NOT ((ENABLE_THREADING STREQUAL "openmp") OR (ENABLE_THREADING STREQUAL "pthreads") OR (ENABLE_THREADING STREQUAL "no")) )
message(FATAL_ERROR "ENABLE_THREADING option '${ENABLE_THREADING}' is not supported. Please use one of the following options \
during CMake invokation: openmp, pthreads, no")
endif()
endif()
# Setting path to OpenMP runtime.
if(WIN32)
set(OpenMP_libomp_LIBRARY "C:/Program Files/LLVM/lib/libomp.lib" CACHE STRING "openmp library path")
endif()
# Set up OpenMP flags correctly if it's required.
if( (ENABLE_THREADING STREQUAL "openmp") OR (MKL_ENABLE_THREADING STREQUAL "openmp") )
find_package(OpenMP)
if(NOT OPENMP_FOUND)
message (FATAL_ERROR "Openmp Not Found, please provide an OpenMP library using -DOpenMP_libomp_LIBRARY=path_to_omp_lib.")
endif()
endif()
# If MKL is used as a reference set up the threading library options.
if(REF_CBLAS STREQUAL "MKL")
# MKL threading option is set up as BLIS threading option by default.
set(MKL_ENABLE_THREADING ${ENABLE_THREADING} CACHE STRING "Setting MKL threading option.")
endif()
# Set static BLIS as the default library we build against.
set(BLIS_LINKING_TYPE "static" CACHE STRING "Type of BLIS library (shared or static) that is being tested.")
# Set the possible values of BLIS linking type for cmake-gui
set_property(CACHE BLIS_LINKING_TYPE PROPERTY STRINGS "static" "shared")
if( NOT ((BLIS_LINKING_TYPE STREQUAL "static") OR (BLIS_LINKING_TYPE STREQUAL "shared")) )
message(FATAL_ERROR "BLIS_LINKING_TYPE option '${BLIS_LINKING_TYPE}' is not supported. Please use one of the following options \
during CMake invokation: static, shared")
endif()
# Set common libraries.
if(LINUX)
set(COMMON_LIBS pthread m dl)
option(ENABLE_ASAN "Run tests using Address Sanitizer" OFF)
option(ENABLE_COVERAGE "Run tests for Code Coverage" OFF)
endif()
# Use INT_SIZE to set the int type used for testing.
set(INT_SIZE "32" CACHE STRING "Integer size used in testing suite. Must match the integer size of BLIS.")
# Set the possible values of reference CBLAS for cmake-gui
set_property(CACHE INT_SIZE PROPERTY STRINGS "32" "64")
if( NOT ((INT_SIZE STREQUAL "32") OR (INT_SIZE STREQUAL "64")) )
message(FATAL_ERROR "INT_SIZE option '${INT_SIZE}' is not supported. Please use one of the following options \
during CMake invokation: 32, 64")
endif()
# Use TEST_INTERFACE to set which interface, supported by BLIS is meant to be tested.
set(TEST_INTERFACE "BLAS" CACHE STRING "Interface of BLIS that is being tested.")
# Set the possible values of interfaces for cmake-gui
set_property(CACHE TEST_INTERFACE PROPERTY STRINGS "BLAS" "BLAS_BLIS_IMPL" "CBLAS" "BLIS_TYPED")
if( NOT ((TEST_INTERFACE STREQUAL "BLAS") OR (TEST_INTERFACE STREQUAL "BLAS_BLIS_IMPL") OR (TEST_INTERFACE STREQUAL "CBLAS") OR (TEST_INTERFACE STREQUAL "BLIS_TYPED")) )
message(FATAL_ERROR "TEST_INTERFACE option ${TEST_INTERFACE} is not supported. Please use on of the following options \
during CMake invokation: BLAS, BLAS_BLIS_IMPL, CBLAS, BLIS_TYPED")
endif()
# Use BLIS_ELEMENT_TYPE to set whether the elements of any matrix/vector tested are integers or floating point values.
set(BLIS_ELEMENT_TYPE "f" CACHE STRING "Type of elements of matrices/vectors")
# Set the possible values of element types for cmake-gui
set_property(CACHE BLIS_ELEMENT_TYPE PROPERTY STRINGS "f" "i")
if( NOT ((BLIS_ELEMENT_TYPE STREQUAL "f") OR (BLIS_ELEMENT_TYPE STREQUAL "i")) )
message(FATAL_ERROR "BLIS_ELEMENT_TYPE option ${BLIS_ELEMENT_TYPE} is not supported. Please use on of the following options \
during CMake invokation: f, i")
endif()
# Option to enable testing with upper case character arguments in BLAS and BLIS calls.
option(TEST_UPPERCASE_ARGS "Test upper case character arguments" OFF)
# Option to enable testing with thresholds set to zero.
option(THRESHOLD_ZERO "Set thresholds to zero" OFF)
# Can we test the value of info stored within BLIS and returned by a call to
# bli_info_get_info_value (introduced at AMD BLAS 4.2).
option(CAN_TEST_INFO_VALUE "Can test value of info" ON)
# Use EXT_VAL to get the extreme value (NaN or Inf) used for testing data that shouldn't be read.
set(EXT_VAL "Inf" CACHE STRING "Extreme value (NaN or Inf) used for testing data that shouldn't be read")
# Set the possible values of reference CBLAS for cmake-gui
set_property(CACHE EXT_VAL PROPERTY STRINGS "NaN" "Inf")
if( NOT ((EXT_VAL STREQUAL "NaN") OR (EXT_VAL STREQUAL "Inf")) )
message(FATAL_ERROR "EXT_VAL option '${EXT_VAL}' is not supported. Please use one of the following options \
during CMake invokation: NaN, Inf")
endif()
# Option to enable testing of input arguments to BLAS APIs.
# Note: This imposes a significant runtime overhead.
option(TEST_INPUT_ARGS "Test input arguments" OFF)
if(REF_LIB)
get_filename_component(REFLIB_PATH ${REF_LIB}/.. ABSOLUTE)
get_filename_component(library ${REF_LIB} NAME)
find_library(reflib NAMES ${library} PATHS ${REFLIB_PATH} NO_DEFAULT_PATH)
if(${reflib} STREQUAL reflib-NOTFOUND)
message(FATAL_ERROR "Reference Library not found : " ${REF_LIB})
else()
message(STATUS "Found Reference Library : " ${reflib})
endif()
else()
# Set the possible values of theading libraries for cmake-gui
set_property(CACHE REF_CBLAS PROPERTY STRINGS "OpenBLAS" "Netlib" "MKL")
if(NOT ((REF_CBLAS STREQUAL "OpenBLAS") OR (REF_CBLAS STREQUAL "Netlib") OR(REF_CBLAS STREQUAL "MKL")))
message(FATAL_ERROR "REF_CBLAS option '${REF_CBLAS}' is not supported. Please, use one of the following options \
during CMake invokation: OpenBLAS, Netlib, MKL or modify CMakeLists.txt to include this option.")
endif()
if(LINUX)
set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so")
set(LIBOpenBLAS openblas)
set(LIBCLAS cblas)
set(LIBCLAS64 cblas64)
set(LIBMKL mkl_rt)
else()
set(CMAKE_FIND_LIBRARY_PREFIXES "")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll")
set(LIBOpenBLAS libopenblas)
set(LIBMKL mkl_rt.2)
endif()
if(REF_CBLAS STREQUAL "OpenBLAS")
if(NOT(OPENBLAS_PATH))
message(FATAL_ERROR "Need to provide an OpenBLAS installation path \
during CMake invokation when OpenBLAS is used for reference results. Please use \
$ cmake .. -DOPENBLAS_PATH=/home/username/openblas_installation")
endif()
find_library(reflib NAMES ${LIBOpenBLAS} PATHS ${OPENBLAS_PATH} NO_DEFAULT_PATH)
if(${reflib} STREQUAL reflib-NOTFOUND)
message(FATAL_ERROR "OpenBLAS Reference Library not found : " ${OPENBLAS_PATH})
else()
message(STATUS "Found OpenBLAS Reference Library : " ${reflib})
endif()
set(REF_LIB ${reflib})
elseif(REF_CBLAS STREQUAL "Netlib")
if(NOT(NETLIB_PATH))
message(FATAL_ERROR "Need to provide a Netlib installation path \
during CMake invokation when Netlib is used for reference results. Please use \
$ cmake .. -DNETLIB_PATH=/home/username/netlib_installation")
endif()
if(INT_SIZE STREQUAL "32")
find_library(netlib NAMES ${LIBCLAS} PATHS ${NETLIB_PATH} NO_DEFAULT_PATH)
else()
find_library(netlib NAMES ${LIBCLAS64} PATHS ${NETLIB_PATH} NO_DEFAULT_PATH)
endif()
if(${netlib} STREQUAL netlib-NOTFOUND)
message(FATAL_ERROR "Netlib Reference Library not found : " ${NETLIB_PATH})
else()
message(STATUS "Found Netlib Reference Library : " ${netlib})
endif()
set(REF_LIB ${netlib})
elseif(REF_CBLAS STREQUAL "MKL")
set(MKL_PATH $ENV{MKLROOT}/lib/intel64 CACHE STRING "The path to MKL.")
find_library(mkllib NAMES ${LIBMKL} PATHS ${MKL_PATH} NO_DEFAULT_PATH)
if(${mkllib} STREQUAL mkllib-NOTFOUND)
message(FATAL_ERROR "MKL Reference Library not found : " ${MKL_PATH})
else()
message(STATUS "Found MKL Reference Library : " ${mkllib})
endif()
set(REF_LIB ${mkllib})
else()
message(FATAL_ERROR "Need to set up a reference library. Please use on of the following options \
during CMake invokation: -DREF_CBLAS=Netlib or -DREF_CBLAS=OpenBLAS or -DREF_CBLAS=MKL")
endif()
endif()
# Set up the library name.
if(WIN32)
set(LIBBLIS AOCL-LibBlis-Win)
else()
set(LIBBLIS blis)
endif()
# Append if threading is required.
if(NOT (ENABLE_THREADING STREQUAL "no"))
if(WIN32)
string(APPEND LIBBLIS -MT)
else()
string(APPEND LIBBLIS -mt)
endif()
endif()
# Append for dll if necessary.
if(WIN32 AND (BLIS_LINKING_TYPE STREQUAL "shared"))
string(APPEND LIBBLIS -dll)
endif()
# Setting the suffix for find_library().
if(WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib)
else()
if(BLIS_LINKING_TYPE STREQUAL "shared")
set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif()
endif()
find_library(BLIS_LIBRARY NAMES ${LIBBLIS} PATHS ${BLIS_LIB_PATH} NO_DEFAULT_PATH)
if(${BLIS_LIBRARY} STREQUAL BLIS_LIBRARY-NOTFOUND)
message(FATAL_ERROR "Blis Library ${LIBBLIS} not found in BLIS_LIB_PATH=${BLIS_LIB_PATH}")
else()
message(STATUS "Found ${LIBBLIS} BLIS Library : " ${BLIS_LIBRARY})
endif()
# Set compiler options and BLIS library for Linux.
if(LINUX)
# Add compiler definition.
add_compile_options(-g -Wall -Wno-unused-function -Wfatal-errors -fPIC )
if(ENABLE_ASAN)
set(ASAN_FLAGS "-fsanitize=address")
list(APPEND CMAKE_C_FLAGS ${ASAN_FLAGS})
endif()
if(ENABLE_COVERAGE)
set(COVERAGE_FLAGS "-O0 --coverage")
list(APPEND CMAKE_C_FLAGS ${COVERAGE_FLAGS})
endif()
endif()
#Setting up the correct Windows Runtime Library.
if(WIN32)
cmake_policy(SET CMP0091 NEW)
if(BUILD_SHARED_LIBS)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
else()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
endif()
# The following part will be used to set up a list of defines that dictate
# which kernel tests can be build and run on the current architecture.
# Given that the symbols of kernel functions are not exported for shared libraries
# we only set up those defines for static libs.
# This way, kernel tests won't be compiled/run for shared versions of BLIS.
if(BLIS_LINKING_TYPE STREQUAL "static")
if(ENABLE_THREADING STREQUAL "openmp")
try_run(RUNRESULT COMPILERESULT "${CMAKE_BINARY_DIR}/temp" SOURCES ${CMAKE_SOURCE_DIR}/cmake/config_ukr_tests.cpp
COMPILE_DEFINITIONS -I${BLIS_PATH}/include/ -I${BLIS_PATH}/include/blis
LINK_LIBRARIES ${BLIS_LIBRARY} ${COMMON_LIBS} OpenMP::OpenMP_CXX ${ASAN_FLAGS} ${COVERAGE_FLAGS}
RUN_OUTPUT_VARIABLE UKR_CONFIG
COMPILE_OUTPUT_VARIABLE COMP_VAR
)
else()
try_run(RUNRESULT COMPILERESULT "${CMAKE_BINARY_DIR}/temp" SOURCES ${CMAKE_SOURCE_DIR}/cmake/config_ukr_tests.cpp
COMPILE_DEFINITIONS -I${BLIS_PATH}/include/ -I${BLIS_PATH}/include/blis
LINK_LIBRARIES ${BLIS_LIBRARY} ${COMMON_LIBS} ${ASAN_FLAGS} ${COVERAGE_FLAGS}
RUN_OUTPUT_VARIABLE UKR_CONFIG
COMPILE_OUTPUT_VARIABLE COMP_VAR
)
endif()
# Uncomment this to debug this snippet above, if necessary.
if(NOT COMPILERESULT)
message(FATAL_ERROR "Compiling config_ukr_tests.cpp failed with the following error ${COMP_VAR}.")
endif()
# Remove all empty items from the list.
list(REMOVE_ITEM UKR_CONFIG "")
# We iterate through the list returned from the snippet above.
# For example, UKR_CONFIG = AVX2FMA3 for zen3
# or UKR_CONFIG = AVX2FMA3;AVX512;AVX512VNNI;AVX512BF16 for zen4
# Depending on the values of this list we define corresponding macros
# -DGTEST_AVX2FMA3 on zen3
# or -DGTEST_AVX2FMA3;-DGTEST_AVX512;-DGTEST_AVX512VNNI;-DGTEST_AVX512BF16 on zen4
# Those macros are passed when compiling the tests in testsuite/CMakeLists.txt.
foreach(ukrconf ${UKR_CONFIG})
list(APPEND UKR_DEFINES "-DGTEST_${ukrconf}")
endforeach()
message(STATUS "Since BLIS GTestSuite is used to check the static version of blis, all kernel tests are enabled.")
else()
message(WARNING "Since BLIS GTestSuite is used to check the shared version of blis, all kernel tests are disabled.")
endif()
add_subdirectory(testinghelpers)
add_subdirectory(testsuite)
add_custom_target(distclean
COMMAND ${CMAKE_MAKE_PROGRAM} clean
COMMAND rm ${CMAKE_BINARY_DIR}/*.txt
COMMAND rm ${CMAKE_BINARY_DIR}/*.cmake
COMMAND rm ${CMAKE_BINARY_DIR}/Makefile
COMMAND rm -rf ${CMAKE_BINARY_DIR}/CMakeFiles
COMMAND rm -rf ${CMAKE_BINARY_DIR}/bin
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Remove cmake_generated files and executables"
)