Skip to content
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

Fix BLAS++ and LAPACK++ build #903

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 81 additions & 1 deletion .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,84 @@ jobs:
fi
done
exit 0
fi
fi

test-blaspp-flag:
runs-on: ubuntu-latest

env:
BUILD_TYPE: Release
FFLAGS: "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all"

strategy:
fail-fast: false
matrix:
sharedlib: [ OFF, ON ]
lapackpp: [ OFF ]
optblas: [ OFF, ON ]
optlapack: [ OFF, ON ]
exclude:
- optblas: ON
optlapack: ON

steps:

- name: Checkout LAPACK
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2

- name: Install ninja-build tool
uses: seanmiddleditch/gha-setup-ninja@16b940825621068d98711680b6c3ff92201f8fc0 # v3

- name: Install the Basics
run: |
sudo apt update
sudo apt install -y cmake gfortran libopenblas-dev

- name: Configure CMake
run: >
cmake -B build -G Ninja
-D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
-D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install
-D CBLAS:BOOL=OFF
-D LAPACKE:BOOL=OFF
-D BUILD_TESTING:BOOL=OFF
-D BUILD_SHARED_LIBS:BOOL=${{ matrix.sharedlib }}
-D BLAS++:BOOL=ON
-D LAPACK++:BOOL=${{ matrix.lapackpp }}
-D USE_OPTIMIZED_BLAS:BOOL=${{ matrix.optblas }}
-D USE_OPTIMIZED_LAPACK:BOOL=${{ matrix.optlapack }}

- name: Build
run: cmake --build build --config ${{env.BUILD_TYPE}}

- name: Check dependencies of BLAS++ on BLAS and LAPACK
working-directory: ${{github.workspace}}/build
run: |
configFile="lib/cmake/blaspp/blasppConfig.cmake"
if [[ ${{ matrix.optblas }} == 'ON' || ${{ matrix.optlapack }} == 'ON' ]]; then
if grep -q "openblas" $configFile; then
echo "BLAS++ dependency to openblas is correct."
else
echo "CMake could not find openblas in $configFile:"
cat $configFile
exit 1
fi
else
if grep -q "${{github.workspace}}/build/lib/libblas" $configFile; then
echo "BLAS++ dependency to BLAS is correct."
else
echo "CMake could not find ${{github.workspace}}/build/lib/libblas in $configFile:"
cat $configFile
exit 1
fi
if grep -q "${{github.workspace}}/build/lib/liblapack" $configFile; then
echo "BLAS++ dependency to LAPACK is correct."
else
echo "CMake could not find ${{github.workspace}}/build/lib/liblapack in $configFile:"
cat $configFile
exit 1
fi
fi

- name: Install
run: cmake --build build --target install -j2
202 changes: 130 additions & 72 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.6)
cmake_minimum_required(VERSION 3.11)
# VERSION 3.11: FetchContent

project(LAPACK)

Expand All @@ -10,6 +11,19 @@ set(
${LAPACK_MAJOR_VERSION}.${LAPACK_MINOR_VERSION}.${LAPACK_PATCH_VERSION}
)

# Dependencies on other projects
include(FetchContent)
FetchContent_Declare(
blaspp
GIT_REPOSITORY https://github.com/icl-utk-edu/blaspp
GIT_TAG 3c47832f5162b5215b2164c21c4132544c65563d # v2023.11.05
)
FetchContent_Declare(
lapackpp
GIT_REPOSITORY https://github.com/icl-utk-edu/lapackpp
GIT_TAG e3aa0156b873d1e1349d083d7e5b66cfbdf9fb08 # v2023.11.05
)

Copy link
Contributor

Choose a reason for hiding this comment

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

May want blaspp 91dd418fa910498cc03dee397826099914cc3185
and lapackpp 88088c33cd9467475e8f139f42d158620f11e64d
which have the fixes for Fortran strlen.

We will likely do a SLATE / BLAS++ / LAPACK++ bug fix release this month, but perhaps for that just update LAPACK right before the SC23 release.

# Allow setting a prefix for the library names
set(CMAKE_STATIC_LIBRARY_PREFIX "lib${LIBRARY_PREFIX}")
set(CMAKE_SHARED_LIBRARY_PREFIX "lib${LIBRARY_PREFIX}")
Expand Down Expand Up @@ -402,48 +416,113 @@ endif()
option(BLAS++ "Build BLAS++" OFF)
option(LAPACK++ "Build LAPACK++" OFF)

if (BLAS++ OR LAPACK++)
message( STATUS "BLAS++ enabled; for support, email [email protected]" )

function(_display_cpp_implementation_msg name)
string(TOLOWER ${name} name_lc)
message(STATUS "${name}++ enable")
message(STATUS "----------------")
message(STATUS "Thank you for your interest in ${name}++, a newly developed C++ API for ${name} library")
message(STATUS "The objective of ${name}++ is to provide a convenient, performance oriented API for development in the C++ language, that, for the most part, preserves established conventions, while, at the same time, takes advantages of modern C++ features, such as: namespaces, templates, exceptions, etc.")
message(STATUS "For support ${name}++ related question, please email: [email protected]")
message(STATUS "----------------")
endfunction()
if (BLAS++)
_display_cpp_implementation_msg("BLAS")
include(ExternalProject)
ExternalProject_Add(blaspp
URL https://bitbucket.org/icl/blaspp/downloads/blaspp-2020.10.02.tar.gz
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env LIBRARY_PATH=$ENV{LIBRARY_PATH}:${CMAKE_BINARY_DIR}/lib LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}:${PROJECT_BINARY_DIR}/lib ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR} -DCMAKE_INSTALL_LIBDIR=lib -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ${PROJECT_BINARY_DIR}/blaspp-prefix/src/blaspp
BUILD_COMMAND ${CMAKE_COMMAND} -E env LIBRARY_PATH=$ENV{LIBRARY_PATH}:${PROJECT_BINARY_DIR}/lib LIB_SUFFIX="" ${CMAKE_COMMAND} --build .
INSTALL_COMMAND ${CMAKE_COMMAND} -E env PREFIX=${PROJECT_BINARY_DIR} LIB_SUFFIX="" ${CMAKE_COMMAND} --install .
)
ExternalProject_Add_StepDependencies(blaspp build ${BLAS_LIBRARIES})
# Check if population has already been performed
FetchContent_GetProperties(blaspp)
if(NOT blaspp_POPULATED)
# Fetch the content using previously declared details
FetchContent_Populate(blaspp)
endif()

# Determine Fortran runtime library.
# todo: CMake ought to know this already -- how to access?
set( Fortran_LIB "" )
if (NOT BUILD_SHARED_LIBS)
if (CMAKE_Fortran_COMPILER_ID MATCHES GNU)
set( Fortran_LIB ";-lgfortran" )
else()
# TODO: This is incomplete. Fill in the other cases.
endif()
endif()
message( DEBUG "Fortran_LIB '${Fortran_LIB}'" )
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this when using Reference BLAS, is that why it checks NOT BLAS_FOUND?

When I tried to compile, linking with liblapack.a also needed -lgfortran, but since I used optimized BLAS, BLAS_FOUND was true and BLAS_Fortran_LIB was empty.

BTW, setting it to empty in the else case is redundant with set above if.


if (NOT BLAS_FOUND)
# Link with Reference BLAS.
set( BLAS_LIBS "$<TARGET_FILE:${BLASLIB}>${Fortran_LIB}" )
else()
# Link with optimized BLAS.
set( BLAS_LIBS "${BLAS_LIBRARIES}" )
endif()
message( DEBUG "BLAS_LIBS '${BLAS_LIBS}'" )

if (NOT LATESTLAPACK_FOUND)
# Link with Reference LAPACK.
set( LAPACK_LIBS "$<TARGET_FILE:${LAPACKLIB}>${Fortran_LIB}" )
else()
# Link with optimized BLAS.
set( LAPACK_LIBS "${LAPACK_LIBRARIES}" )
endif()
message( DEBUG "LAPACK_LIBS '${LAPACK_LIBS}'" )

# Adds target blaspp
add_custom_target( blaspp ALL DEPENDS blaspp-cmd )
add_custom_command( OUTPUT blaspp-cmd
WORKING_DIRECTORY "${blaspp_SOURCE_DIR}"
COMMENT "Building BLAS++" )

# Set up information about the BLAS and LAPACK libraries
add_custom_command( OUTPUT blaspp-cmd APPEND
COMMAND ${CMAKE_COMMAND}
-B "${blaspp_BINARY_DIR}"
-D CMAKE_INSTALL_PREFIX="${LAPACK_BINARY_DIR}"
-D BLAS_LIBRARIES="${BLAS_LIBS}"
-D LAPACK_LIBRARIES="${LAPACK_LIBS}"
-D build_tests=OFF
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-D BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}

COMMAND ${CMAKE_COMMAND}
--build "${blaspp_BINARY_DIR}"
--config ${CMAKE_BUILD_TYPE}
--target install
)

# Set up dependencies
if(NOT BLAS_FOUND)
add_dependencies(blaspp ${BLASLIB})
endif()
if(NOT LATESTLAPACK_FOUND)
add_dependencies(blaspp ${LAPACKLIB})
endif()
endif()

if (LAPACK++)
message (STATUS "linking lapack++ against ${LAPACK_LIBRARIES}")
_display_cpp_implementation_msg("LAPACK")
include(ExternalProject)
if (BUILD_SHARED_LIBS)
ExternalProject_Add(lapackpp
URL https://bitbucket.org/icl/lapackpp/downloads/lapackpp-2020.10.02.tar.gz
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env LIBRARY_PATH=$ENV{LIBRARY_PATH}:${CMAKE_BINARY_DIR}/lib LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}:${PROJECT_BINARY_DIR}/lib ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR} -DCMAKE_INSTALL_LIBDIR=lib -DLAPACK_LIBRARIES=${LAPACK_LIBRARIES} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ${PROJECT_BINARY_DIR}/lapackpp-prefix/src/lapackpp
BUILD_COMMAND ${CMAKE_COMMAND} -E env LIBRARY_PATH=$ENV{LIBRARY_PATH}:${PROJECT_BINARY_DIR}/lib LIB_SUFFIX="" ${CMAKE_COMMAND} --build .
INSTALL_COMMAND ${CMAKE_COMMAND} -E env PREFIX=${PROJECT_BINARY_DIR} LIB_SUFFIX="" ${CMAKE_COMMAND} --install .
)
else ()
# FIXME this does not really work as the libraries list gets converted to a semicolon-separated list somewhere in the lapack++ build files
ExternalProject_Add(lapackpp
URL https://bitbucket.org/icl/lapackpp/downloads/lapackpp-2020.10.02.tar.gz
CONFIGURE_COMMAND env LIBRARY_PATH=$ENV{LIBRARY_PATH}:${CMAKE_BINARY_DIR}/lib LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}:${PROJECT_BINARY_DIR}/lib ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR} -DCMAKE_INSTALL_LIBDIR=lib -DLAPACK_LIBRARIES="${PROJECT_BINARY_DIR}/lib/liblapack.a -lgfortran" -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ${PROJECT_BINARY_DIR}/lapackpp-prefix/src/lapackpp
BUILD_COMMAND env LIBRARY_PATH=$ENV{LIBRARY_PATH}:${PROJECT_BINARY_DIR}/lib LIB_SUFFIX="" ${CMAKE_COMMAND} --build .
INSTALL_COMMAND ${CMAKE_COMMAND} -E env PREFIX=${PROJECT_BINARY_DIR} LIB_SUFFIX="" ${CMAKE_COMMAND} --install .
)
message( STATUS "LAPACK++ enabled; for support, email [email protected]" )

# Check if population has already been performed
FetchContent_GetProperties(lapackpp)
if(NOT lapackpp_POPULATED)
# Fetch the content using previously declared details
FetchContent_Populate(lapackpp)
endif()
ExternalProject_Add_StepDependencies(lapackpp build blaspp ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})

# Adds target lapackpp
add_custom_target( lapackpp ALL DEPENDS lapackpp-cmd )
add_custom_command( OUTPUT lapackpp-cmd
WORKING_DIRECTORY "${lapackpp_SOURCE_DIR}"
COMMENT "Building LAPACK++" )

# Setup remaining configuration options and installation
add_custom_command( OUTPUT lapackpp-cmd APPEND
COMMAND ${CMAKE_COMMAND}
-B "${lapackpp_BINARY_DIR}"
-D CMAKE_INSTALL_PREFIX="${LAPACK_BINARY_DIR}"
-D blaspp_DIR="${PROJECT_BINARY_DIR}/lib/cmake/blaspp"
-D LAPACK_LIBRARIES="${LAPACK_LIBS}"
-D build_tests=OFF
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-D BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}

COMMAND ${CMAKE_COMMAND}
--build "${lapackpp_BINARY_DIR}"
--config ${CMAKE_BUILD_TYPE}
--target install
)

# Set up dependencies
add_dependencies(lapackpp blaspp)
endif()

# --------------------------------------------------
Expand Down Expand Up @@ -551,47 +630,26 @@ install(FILES
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${LAPACKLIB}-${LAPACK_VERSION}
COMPONENT Development
)

if (LAPACK++)
install(
DIRECTORY "${LAPACK_BINARY_DIR}/lib/"
DESTINATION ${CMAKE_INSTALL_LIBDIR}
FILES_MATCHING REGEX "liblapackpp.(a|so)$"
)
install(
DIRECTORY "${PROJECT_BINARY_DIR}/lapackpp-prefix/src/lapackpp/include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
FILES_MATCHING REGEX "\\.(h|hh)$"
)
write_basic_package_version_file(
"lapackppConfigVersion.cmake"
VERSION 2020.10.02
COMPATIBILITY AnyNewerVersion
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/lib/lapackpp/lapackppConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/lib/lapackpp/lapackppConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/"
DIRECTORY "${LAPACK_BINARY_DIR}/lib/"
DESTINATION ${CMAKE_INSTALL_LIBDIR}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same issue as below; use ${CMAKE_INSTALL_LIBDIR}.

FILES_MATCHING REGEX "lapackpp"
)

endif()

if (BLAS++)
write_basic_package_version_file(
Copy link
Contributor

Choose a reason for hiding this comment

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

LAPACK++ requires BLAS++, so as above, I think this should be if (BLAS++ OR LAPACK++).

Copy link
Contributor

Choose a reason for hiding this comment

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

With cmake -D LAPACK++=on .., this will build BLAS++ and LAPACK++, but doesn't install libblaspp.a. Changing to if (BLAS++ or LAPACK++) fixes the issue. Can be merged with if block below (line 650).

"blasppConfigVersion.cmake"
VERSION 2020.10.02
COMPATIBILITY AnyNewerVersion
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/lib/blaspp/blasppConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/lib/blaspp/blasppConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/"
)
install(
DIRECTORY "${LAPACK_BINARY_DIR}/lib/"
DESTINATION ${CMAKE_INSTALL_LIBDIR}
FILES_MATCHING REGEX "libblaspp.(a|so)$"
DIRECTORY "${LAPACK_BINARY_DIR}/lib/"
DESTINATION ${CMAKE_INSTALL_LIBDIR}
Copy link
Contributor

Choose a reason for hiding this comment

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

On Linux, it put them in ${LAPACK_BINARY_DIR}/lib64, so it find libblaspp.a and liblapackpp.a to install:

sh leconte build2> pwd
/home/mgates/repos/lapack/build2

sh leconte build2> ls lib lib64
lib:
liblapack.a

lib64:
cmake  libblaspp.a  liblapackpp.a

sh leconte build2> ls ~/install-test/lib64/
cmake  liblapack.a  pkgconfig

On macOS, it put them in ${LAPACK_BINARY_DIR}/lib, and everything worked (with previously mentioned fix about if (BLAS++ or LAPACK++)):

pangolin lapack/build3> pwd
/Users/mgates/Documents/lapack/build3

pangolin lapack/build3> ls lib
cmake/  libblaspp.a  liblapack.a  liblapackpp.a

pangolin lapack/build3> ls ~/install-test/lib/
cmake/  libblaspp.a  liblapack.a  liblapackpp.a  pkgconfig/

FILES_MATCHING REGEX "blaspp"
)
endif()

if (BLAS++ OR LAPACK++)
install(
DIRECTORY "${PROJECT_BINARY_DIR}/blaspp-prefix/src/blaspp/include/"
DIRECTORY "${LAPACK_BINARY_DIR}/include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
FILES_MATCHING REGEX "\\.(h|hh)$"
)
Expand Down
Loading