Skip to content

[WIP] Build MKL static #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
34 changes: 27 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ matrix:
- os: linux
env:
- BACKEND=Intel10_64lp_seq
- os: osx
- os: linux
env:
- BACKEND=Apple
- os: osx
- BACKEND=Intel10_64lp
- os: linux
env:
- BACKEND=Intel10_64lp_seq
- BUILD_STATIC=1
- os: linux
env:
- BACKEND=Intel10_64lp
- BUILD_STATIC=1

before_install:
# Dependencies required by the CI are installed in ${TRAVIS_BUILD_DIR}/deps/
Expand All @@ -58,6 +63,9 @@ before_install:
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
else
brew install cmake || brew upgrade cmake
if [[ "${BACKEND}" == "OpenBLAS" ]]; then
brew install openblas
fi
fi
- which cmake
- cmake --version
Expand All @@ -66,7 +74,7 @@ before_install:
# Install MKL
############################################################################
- |
if [[ "${BACKEND}" == "Intel10_64lp_seq" ]]; then
if [[ "${BACKEND}" == *"Intel"* ]]; then
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
export MKL_INSTALL_DIR=$(pwd)/intel
wget http://registrationcenter-download.intel.com/akdlm/irc_nas/tec/12070/l_mkl_2018.0.128.tgz
Expand All @@ -92,9 +100,17 @@ before_install:
script:
- cd ${TRAVIS_BUILD_DIR}
- mkdir -p build && cd build
- echo "cmake .. -DBLAS_VENDOR=$BACKEND"
- cmake .. -DCMAKE_CXX_STANDARD=11 -DBLA_VENDOR=$BACKEND
- cmake --build .
- export CMAKE_OPTIONS="-DCMAKE_CXX_STANDARD=11 -DBLA_VENDOR=$BACKEND"
- |
if [[ "${BUILD_STATIC}" == "1" ]]; then
export CMAKE_OPTIONS="${CMAKE_OPTIONS} -DBLA_STATIC=ON"
fi
- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then echo $LD_LIBRARY_PATH; fi
- if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then echo $DYLD_LIBRARY_PATH; fi
- echo "cmake .. ${CMAKE_OPTIONS}"
- cmake .. ${CMAKE_OPTIONS}
- make VERBOSE=1
# - cmake --build .
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
ldd ./CMakeHelloWorld
Expand All @@ -105,5 +121,9 @@ script:
after_success:
- ./CMakeHelloWorld

after_failure:
- cat CMakeFiles/CMakeOutput.log
- cat CMakeFiles/CMakeError.log

notifications:
email: false
18 changes: 7 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@ set (CMakeHelloWorld_VERSION_MAJOR 1)
set (CMakeHelloWorld_VERSION_MINOR 0)

# Find the BLAS stuff
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
find_package(BLAS REQUIRED)

message(STATUS "BLAS Libraries: ${BLAS_LIBRARIES}")

# find_path(BLAS_INCLUDE_DIRS NAMES cblas.h)
# message(STATUS "BLAS Include: ${BLAS_INCLUDE_DIRS}")
# include_directories(${BLAS_INCLUDE_DIRS})

set(BLA_DEFINITIONS)
if (BLA_VENDOR MATCHES Intel)
if ("$ENV{MKLROOT}" STREQUAL "")
Expand All @@ -29,17 +26,16 @@ elseif (BLA_VENDOR MATCHES ATLAS)
set(BLAS_LIBRARIES "${BLAS_LIBRARIES};${CBLAS_LIB}")
endif()

# include_directories(SYSTEM
# C:\\nuget_openblas\\OpenBLAS.0.2.14.1\\lib\\native\\include\\
# C:\\OpenBLAS.0.2.14.1\\lib\\native\\include\\)

#include the subdirectory containing our libs
# include the subdirectory containing our libs
add_subdirectory(Hello)
include_directories(Hello)
#indicate the entry point for the executable
# indicate the entry point for the executable
add_executable(CMakeHelloWorld Hello HelloWorld.cpp)

# BLAS libraries compile dynamically against threads
LIST(APPEND CMAKE_THREAD_LIBS_INIT ${LM})
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${LM} is -llibm -llibdl (aka /usr/lib/x86_64-linux-gnu/libm.so and /usr/lib/x86_64-linux-gnu/libdl.so)
This is only needed by gcc compilers, so it should be inside an if statement like if (CMAKE_C_COMPILER MATCHES ".+gcc")

More over it should be discussed if this find_package should be done silently or not.

Advantages of doing it silently are that target_link_libraries(CMakeHelloWorld Hello ${BLAS_LIBRARIES}) is clear. However to make BLA work with static needs to properly compose the thread libs which makes target_link_libraries(CMakeHelloWorld Hello ${BLAS_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) look like a hack.

Maybe it would be better to just check that Threads is found at the begining of FindBLA.cmake and break if not found, like this is explicit what needs to be done with trheads, and allows for better control. ( In that case, ${LM} should be placed where it's due, and it would make sense Intel10_64lp appending what needs inside FindBLA.cmake)

cc: @agramfort, @aabadie, @kYc0o

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds a good way to clean it up indeed.


# Indicate which libraries to include during the link process.
target_link_libraries(CMakeHelloWorld Hello ${BLAS_LIBRARIES})
target_link_libraries(CMakeHelloWorld Hello ${BLAS_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})

# install (TARGETS CMakeHelloWorld DESTINATION bin)
86 changes: 86 additions & 0 deletions cmake/CMakePushCheckState.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#.rst:
# CMakePushCheckState
# -------------------
#
#
#
# This module defines three macros: CMAKE_PUSH_CHECK_STATE()
# CMAKE_POP_CHECK_STATE() and CMAKE_RESET_CHECK_STATE() These macros can
# be used to save, restore and reset (i.e., clear contents) the state of
# the variables CMAKE_REQUIRED_FLAGS, CMAKE_REQUIRED_DEFINITIONS,
# CMAKE_REQUIRED_LIBRARIES, CMAKE_REQUIRED_INCLUDES and CMAKE_EXTRA_INCLUDE_FILES
# used by the various Check-files coming with CMake, like e.g.
# check_function_exists() etc. The variable contents are pushed on a
# stack, pushing multiple times is supported. This is useful e.g. when
# executing such tests in a Find-module, where they have to be set, but
# after the Find-module has been executed they should have the same
# value as they had before.
#
# CMAKE_PUSH_CHECK_STATE() macro receives optional argument RESET.
# Whether it's specified, CMAKE_PUSH_CHECK_STATE() will set all
# CMAKE_REQUIRED_* variables to empty values, same as
# CMAKE_RESET_CHECK_STATE() call will do.
#
# Usage:
#
# ::
#
# cmake_push_check_state(RESET)
# set(CMAKE_REQUIRED_DEFINITIONS -DSOME_MORE_DEF)
# check_function_exists(...)
# cmake_reset_check_state()
# set(CMAKE_REQUIRED_DEFINITIONS -DANOTHER_DEF)
# check_function_exists(...)
# cmake_pop_check_state()

macro(CMAKE_RESET_CHECK_STATE)

set(CMAKE_EXTRA_INCLUDE_FILES)
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_DEFINITIONS)
set(CMAKE_REQUIRED_LIBRARIES)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_QUIET)

endmacro()

macro(CMAKE_PUSH_CHECK_STATE)

if(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER)
set(_CMAKE_PUSH_CHECK_STATE_COUNTER 0)
endif()

math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1")

set(_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_EXTRA_INCLUDE_FILES})
set(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_INCLUDES})
set(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS})
set(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LIBRARIES})
set(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_FLAGS})
set(_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_QUIET})

if (ARGC GREATER 0 AND ARGV0 STREQUAL "RESET")
cmake_reset_check_state()
endif()

endmacro()

macro(CMAKE_POP_CHECK_STATE)

# don't pop more than we pushed
if("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0")

set(CMAKE_EXTRA_INCLUDE_FILES ${_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_QUIET ${_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})

math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1")
endif()

endmacro()
66 changes: 66 additions & 0 deletions cmake/CheckFortranFunctionExists.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#.rst:
# CheckFortranFunctionExists
# --------------------------
#
# macro which checks if the Fortran function exists
#
# CHECK_FORTRAN_FUNCTION_EXISTS(FUNCTION VARIABLE)
#
# ::
#
# FUNCTION - the name of the Fortran function
# VARIABLE - variable to store the result
# Will be created as an internal cache variable.
#
#
#
# The following variables may be set before calling this macro to modify
# the way the check is run:
#
# ::
#
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link

macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE)
if(NOT DEFINED ${VARIABLE})
message(STATUS "Looking for Fortran ${FUNCTION}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
else()
set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES)
endif()
file(WRITE
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
"
program TESTFortran
external ${FUNCTION}
call ${FUNCTION}()
end program TESTFortran
"
)
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
OUTPUT_VARIABLE OUTPUT
)
# message(STATUS "${OUTPUT}")
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have Fortran function ${FUNCTION}")
message(STATUS "Looking for Fortran ${FUNCTION} - found")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran ${FUNCTION} exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
message(STATUS "Looking for Fortran ${FUNCTION} - not found")
set(${VARIABLE} "" CACHE INTERNAL "Have Fortran function ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Fortran ${FUNCTION} exists failed with the following output:\n"
"${OUTPUT}\n\n")
endif()
endif()
endmacro()
98 changes: 98 additions & 0 deletions cmake/CheckFunctionExists.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#.rst:
# CheckFunctionExists
# -------------------
#
# Check if a C function can be linked::
#
# check_function_exists(<function> <variable>)
#
# Check that the ``<function>`` is provided by libraries on the system and store
# the result in a ``<variable>``. ``<variable>`` will be created as an internal
# cache variable.
#
# The following variables may be set before calling this macro to modify the
# way the check is run:
#
# ::
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
# CMAKE_REQUIRED_QUIET = execute quietly without messages
#
# .. note::
#
# Prefer using :Module:`CheckSymbolExists` instead of this module,
# for the following reasons:
#
# * ``check_function_exists()`` can't detect functions that are inlined
# in headers or specified as a macro.
#
# * ``check_function_exists()`` can't detect anything in the 32-bit
# versions of the Win32 API, because of a mismatch in calling conventions.
#
# * ``check_function_exists()`` only verifies linking, it does not verify
# that the function is declared in system headers.

macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${FUNCTION}")
endif()
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
else()
set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES)
endif()
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_FUNCTION_EXISTS_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else()
set(CHECK_FUNCTION_EXISTS_ADD_INCLUDES)
endif()

if(CMAKE_C_COMPILER_LOADED)
set(_cfe_source ${CMAKE_ROOT}/Modules/CheckFunctionExists.c)
elseif(CMAKE_CXX_COMPILER_LOADED)
set(_cfe_source ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckFunctionExists/CheckFunctionExists.cxx)
configure_file(${CMAKE_ROOT}/Modules/CheckFunctionExists.c "${_cfe_source}" COPYONLY)
else()
message(FATAL_ERROR "CHECK_FUNCTION_EXISTS needs either C or CXX language enabled")
endif()

try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
${_cfe_source}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CHECK_FUNCTION_EXISTS_ADD_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
unset(_cfe_source)

if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}")
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${FUNCTION} - found")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the function ${FUNCTION} exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${FUNCTION} - not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the function ${FUNCTION} exists failed with the following output:\n"
"${OUTPUT}\n\n")
endif()
endif()
endmacro()
Loading