Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion .github/workflows/doc-generation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ jobs:
-DUSE_MPI=ON \
-DBUILD_TESTING=ON \
-DUSE_OPENMP=ON \
-DUSE_SMM=libxsmm \
-DMPI_EXECUTABLE_SUFFIX=.mpich \
..
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ jobs:
-DUSE_MPI=ON \
-DBUILD_TESTING=ON \
-DUSE_OPENMP=ON \
-DUSE_SMM=libxsmm \
-DMPI_EXECUTABLE_SUFFIX=.mpich \
..
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/testing-gcc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ jobs:
-DBUILD_TESTING=ON \
-DUSE_MPI=OFF \
-DUSE_OPENMP=ON \
-DUSE_SMM=blas \
-DUSE_MPI_F08=ON \
..

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/testing-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
matrix:
use_mpi: [MPI=ON, MPI=OFF]
use_openmp: [OPENMP=ON, OPENMP=OFF]
use_smm: [SMM=blas, SMM=libxsmm]
use_smm: [LIBXSMM=ON, LIBXSMM=OFF]
mpi_suffix: [openmpi, mpich]
exclude:
- use_mpi: MPI=OFF
Expand Down Expand Up @@ -82,7 +82,7 @@ jobs:

- name: Upload coverage data (generated files)
uses: actions/upload-artifact@v4
if: matrix.use_mpi == 'MPI=ON' && matrix.use_openmp == 'OPENMP=ON' && matrix.use_smm == 'SMM=blas' && matrix.mpi_suffix == 'openmpi'
if: matrix.use_mpi == 'MPI=ON' && matrix.use_openmp == 'OPENMP=ON' && matrix.use_smm == 'LIBXSMM=OFF' && matrix.mpi_suffix == 'openmpi'
with:
name: coverage-data-${{ matrix.use_mpi }}-${{ matrix.use_openmp }}-${{ matrix.use_smm }}-${{ matrix.mpi_suffix }}-generated-files
path: |
Expand Down Expand Up @@ -137,7 +137,7 @@ jobs:
strategy:
matrix:
use_openmp: [OPENMP=ON]
use_smm: [SMM=libxsmm]
use_smm: [LIBXSMM=ON]

steps:
- uses: actions/checkout@v4
Expand Down
233 changes: 189 additions & 44 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,6 @@ set(TEST_OMP_THREADS
2
CACHE STRING "Number of OpenMP threads for testing")

set(USE_SMM
"auto"
CACHE STRING
"Small Matrix Multiplication implementation to use (default: auto)")
set_property(CACHE USE_SMM PROPERTY STRINGS auto blas libxsmm)

set(USE_ACCEL
""
CACHE STRING "Build with acceleration support (default: none)")
Expand Down Expand Up @@ -149,44 +143,127 @@ if (USE_OPENMP)
find_package(OpenMP REQUIRED)
endif ()

# =================================== LIBXSMM (rely on pkg-config)
if (USE_SMM MATCHES "libxsmm|auto")
if (USE_SMM MATCHES "libxsmm")
set(LIBXSMM_REQUIRED "REQUIRED")
# =================================== SMM (Small Matrix-Matrix multiplication)
# LIBXS provides host-side batched GEMM for all backends. LIBXSMM provides JIT
# kernels within LIBXS (optional, auto-detected). Set LIBXSROOT to use a
# prebuilt installation, or let FetchContent download it. Set USE_LIBXS=OFF to
# disable entirely.
include(FetchContent)
include(cmake/dependencies.cmake)
option(USE_LIBXS "Use LIBXS for host-side Small Matrix Multiplication" ON)
find_package(PkgConfig QUIET)
set(LIBXSROOT
""
CACHE PATH "Root directory of a prebuilt LIBXS (skips FetchContent)")
if (USE_LIBXS)
# Try prebuilt: pkg-config > explicit root > path probing
if (NOT LIBXSROOT AND PkgConfig_FOUND)
pkg_check_modules(_LIBXS QUIET libxs)
if (_LIBXS_FOUND)
pkg_get_variable(LIBXSROOT libxs prefix)
endif ()
endif ()
if (NOT LIBXSROOT)
foreach (_dir "${CMAKE_SOURCE_DIR}/../libxs" "$ENV{HOME}/libxs"
"/opt/libxs")
if (EXISTS "${_dir}/include/libxs.f")
set(LIBXSROOT "${_dir}")
break()
endif ()
endforeach ()
endif ()
find_package(PkgConfig ${LIBXSMM_REQUIRED})
if (USE_OPENMP)
if (BUILD_SHARED_LIBS OR USE_SMM MATCHES "libxsmm-shared")
pkg_check_modules(LIBXSMMEXT IMPORTED_TARGET GLOBAL libxsmmext-shared)
if (LIBXSROOT AND EXISTS "${LIBXSROOT}/include/libxs.f")
find_library(
LIBXS_LIBRARY
NAMES xs
PATHS "${LIBXSROOT}/lib"
NO_DEFAULT_PATH)
if (LIBXS_LIBRARY)
message(STATUS "Using prebuilt LIBXS from ${LIBXSROOT}")
else ()
pkg_check_modules(LIBXSMMEXT IMPORTED_TARGET GLOBAL libxsmmext-static)
endif ()
if (NOT LIBXSMMEXT_FOUND)
pkg_check_modules(LIBXSMMEXT ${LIBXSMM_REQUIRED} IMPORTED_TARGET GLOBAL
libxsmmext)
message(
STATUS "LIBXS source found at ${LIBXSROOT} -- building as subdirectory")
set(LIBXS_FORTRAN
ON
CACHE BOOL "" FORCE)
set(LIBXS_SHARED
${BUILD_SHARED_LIBS}
CACHE BOOL "" FORCE)
add_subdirectory("${LIBXSROOT}" "${CMAKE_BINARY_DIR}/_deps/libxs-build")
set(LIBXS_FETCHED TRUE)
endif ()
endif ()
if (BUILD_SHARED_LIBS OR USE_SMM MATCHES "libxsmm-shared")
pkg_check_modules(LIBXSMM IMPORTED_TARGET GLOBAL libxsmmf-shared)
else ()
pkg_check_modules(LIBXSMM IMPORTED_TARGET GLOBAL libxsmmf-static)
endif ()
if (NOT LIBXSMM_FOUND)
pkg_check_modules(LIBXSMM ${LIBXSMM_REQUIRED} IMPORTED_TARGET GLOBAL
libxsmmf)
message(STATUS "LIBXS not found locally -- downloading via FetchContent")
FetchContent_Declare(
libxs
GIT_REPOSITORY ${LIBXS_GIT_REPOSITORY}
GIT_TAG ${LIBXS_GIT_TAG})
set(LIBXS_FORTRAN
ON
CACHE BOOL "" FORCE)
set(LIBXS_SHARED
${BUILD_SHARED_LIBS}
CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(libxs)
set(LIBXS_FETCHED TRUE)
set(LIBXSROOT "${libxs_SOURCE_DIR}")
endif ()
endif ()

# =================================== SMM (Small Matrix-Matrix multiplication)
if (USE_SMM MATCHES "blas" OR (USE_SMM MATCHES "auto" AND NOT LIBXSMM_FOUND))
if (USE_ACCEL MATCHES "opencl")
message(FATAL_ERROR "OpenCL requires USE_SMM=libxsmm")
# Optional LIBXSMM for JIT-compiled GEMM kernels
option(USE_LIBXSMM "Use LIBXSMM for JIT-compiled GEMM kernels" ON)
if (USE_LIBXSMM)
set(LIBXSMMROOT
""
CACHE PATH "Root directory of LIBXSMM (optional)")
if (NOT LIBXSMMROOT)
foreach (_dir "${LIBXSROOT}/../libxsmm" "$ENV{HOME}/libxsmm")
if (EXISTS "${_dir}/include/libxsmm.h")
set(LIBXSMMROOT "${_dir}")
break()
endif ()
endforeach ()
endif ()
if (LIBXSMMROOT AND EXISTS "${LIBXSMMROOT}/include/libxsmm.h")
find_library(
LIBXSMM_LIBRARY
NAMES xsmm
PATHS "${LIBXSMMROOT}/lib"
NO_DEFAULT_PATH)
if (LIBXSMM_LIBRARY)
message(STATUS "Using prebuilt LIBXSMM from ${LIBXSMMROOT}")
else ()
message(
STATUS
"LIBXSMM source found at ${LIBXSMMROOT} -- building as subdirectory"
)
set(XSMM_STATIC
ON
CACHE BOOL "" FORCE)
add_subdirectory("${LIBXSMMROOT}"
"${CMAKE_BINARY_DIR}/_deps/libxsmm-build")
set(LIBXSMM_FETCHED TRUE)
get_target_property(_xsmm_srcs xsmm SOURCES)
list(FILTER _xsmm_srcs EXCLUDE REGEX "binaryexport_generator")
set_target_properties(xsmm PROPERTIES SOURCES "${_xsmm_srcs}")
endif ()
else ()
message(
STATUS "LIBXSMM not found locally -- downloading via FetchContent")
FetchContent_Declare(
libxsmm
GIT_REPOSITORY "https://github.com/libxsmm/libxsmm.git"
GIT_TAG ${LIBXSMM_GIT_TAG})
set(XSMM_STATIC
ON
CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(libxsmm)
set(LIBXSMMROOT "${libxsmm_SOURCE_DIR}")
set(LIBXSMM_FETCHED TRUE)
get_target_property(_xsmm_srcs xsmm SOURCES)
list(FILTER _xsmm_srcs EXCLUDE REGEX
"(binaryexport_generator|gemm_driver)")
set_target_properties(xsmm PROPERTIES SOURCES "${_xsmm_srcs}")
endif ()
endif ()
message(STATUS "Using BLAS for Small Matrix Multiplication")
elseif (USE_SMM MATCHES "libxsmm" OR USE_SMM MATCHES "auto")
message(STATUS "Using libxsmm for Small Matrix Multiplication")
else ()
message(FATAL_ERROR "Unknown SMM library specified")
endif ()

# =================================== BLAS & LAPACK, PkgConfig
Expand Down Expand Up @@ -251,13 +328,81 @@ if (NOT USE_ACCEL MATCHES "none")
endif ()

if (USE_ACCEL MATCHES "opencl")
# Hint additional OpenCL locations (Intel oneAPI, CUDA toolkit)
if (DEFINED ENV{CMPLR_ROOT})
list(APPEND CMAKE_PREFIX_PATH "$ENV{CMPLR_ROOT}")
endif ()
if (DEFINED ENV{CUDA_PATH})
list(APPEND CMAKE_PREFIX_PATH "$ENV{CUDA_PATH}")
endif ()
find_package(OpenCL REQUIRED)

set(DBCSR_OPENCL_SCRIPT ${DBCSR_SOURCE_DIR}/acc/opencl/acc_opencl.sh)
set(DBCSR_OPENCL_COMMON acc/opencl/common/opencl_atomics.h
acc/opencl/common/opencl_common.h)
list(APPEND DBCSR_ACC_HEADER acc/opencl/smm/opencl_libsmm.h
acc/opencl/acc_opencl.h)
# LIBXS is required for the OpenCL backend
if (NOT LIBXS_LIBRARY AND NOT LIBXS_FETCHED)
message(
FATAL_ERROR
"LIBXS not found. OpenCL backend requires LIBXS (USE_LIBXS=ON).")
endif ()
# Locate LIBXSTREAM: prebuilt > pkg-config > path probing > FetchContent
set(LIBXSTREAMROOT
""
CACHE PATH "Root directory of a prebuilt LIBXSTREAM (skips FetchContent)")
if (NOT LIBXSTREAMROOT AND PkgConfig_FOUND)
pkg_check_modules(_LIBXSTREAM QUIET libxstream)
if (_LIBXSTREAM_FOUND)
pkg_get_variable(LIBXSTREAMROOT libxstream prefix)
endif ()
endif ()
if (NOT LIBXSTREAMROOT)
foreach (_dir "${CMAKE_SOURCE_DIR}/../libxstream" "$ENV{HOME}/libxstream"
"/opt/libxstream")
if (EXISTS "${_dir}/include/libxstream.h")
set(LIBXSTREAMROOT "${_dir}")
break()
endif ()
endforeach ()
endif ()
if (LIBXSTREAMROOT AND EXISTS "${LIBXSTREAMROOT}/include/libxstream.h")
find_library(
LIBXSTREAM_LIBRARY xstream
PATHS "${LIBXSTREAMROOT}/lib"
NO_DEFAULT_PATH)
if (LIBXSTREAM_LIBRARY)
message(STATUS "Using prebuilt LIBXSTREAM from ${LIBXSTREAMROOT}")
else ()
message(
STATUS
"LIBXSTREAM source found at ${LIBXSTREAMROOT} -- building as subdirectory"
)
set(LIBXSROOT
"${LIBXSROOT}"
CACHE PATH "" FORCE)
set(LIBXSTREAM_SHARED
${BUILD_SHARED_LIBS}
CACHE BOOL "" FORCE)
add_subdirectory("${LIBXSTREAMROOT}"
"${CMAKE_BINARY_DIR}/_deps/libxstream-build")
set(LIBXSTREAM_FETCHED TRUE)
endif ()
else ()
message(
STATUS "LIBXSTREAM not found locally -- downloading via FetchContent")
FetchContent_Declare(
libxstream
GIT_REPOSITORY ${LIBXSTREAM_GIT_REPOSITORY}
GIT_TAG ${LIBXSTREAM_GIT_TAG})
set(LIBXSROOT
"${LIBXSROOT}"
CACHE PATH "" FORCE)
set(LIBXSTREAM_SHARED
${BUILD_SHARED_LIBS}
CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(libxstream)
set(LIBXSTREAMROOT "${libxstream_SOURCE_DIR}")
set(LIBXSTREAM_FETCHED TRUE)
endif ()
message(STATUS "Using LIBXSTREAM from ${LIBXSTREAMROOT}")
# Kernel build script and common OpenCL headers
set(DBCSR_OPENCL_SCRIPT "${LIBXSTREAMROOT}/scripts/tool_opencl.sh")
endif ()

if (USE_ACCEL MATCHES "cuda|hip")
Expand Down
7 changes: 4 additions & 3 deletions cmake/CompilerConfiguration.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13) # comparison against CXX version rather than GFortran version
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wno-error=uninitialized") # false positive (allocatable array)
endif ()
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wno-function-elimination")
include(CheckFortranCompilerFlag)
check_fortran_compiler_flag("-Wno-error=deprecated-openmp" _fc_has_deprecated_openmp)
check_fortran_compiler_flag("-Wdeprecated-openmp" _fc_has_deprecated_openmp)
if (_fc_has_deprecated_openmp)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wno-error=deprecated-openmp")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wno-deprecated-openmp")
endif ()
set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -g -funroll-loops")
set(CMAKE_Fortran_FLAGS_COVERAGE "-O0 -g --coverage -fno-omit-frame-pointer -fcheck=all,no-array-temps -ffpe-trap=invalid,zero,overflow -fbacktrace -finit-real=snan -finit-integer=-42 -finit-derived -Werror=realloc-lhs -finline-matmul-limit=0 -Werror")
set(CMAKE_Fortran_FLAGS_DEBUG "-O2 -ggdb -fno-omit-frame-pointer -fcheck=all -ffpe-trap=invalid,zero,overflow -fbacktrace -finit-real=snan -finit-integer=-42 -finit-derived -finline-matmul-limit=0 -fsanitize=undefined -fsanitize=address -fsanitize-recover=all -Wall -Wextra -Werror -Werror=realloc-lhs -Wno-error=array-temporaries -Wno-error=compare-reals -Wno-error=function-elimination -Wno-error=surprising")
set(CMAKE_Fortran_FLAGS_DEBUG "-O2 -ggdb -fno-omit-frame-pointer -fcheck=all -ffpe-trap=invalid,zero,overflow -fbacktrace -finit-real=snan -finit-integer=-42 -finit-derived -finline-matmul-limit=0 -fsanitize=undefined -fsanitize=address -fsanitize-recover=all -Wall -Wextra -Werror -Werror=realloc-lhs -Wno-error=array-temporaries -Wno-error=compare-reals -Wno-error=surprising")
if ((NOT (USE_MPI)) OR (NOT ("${MPI_Fortran_LIBRARY_VERSION_STRING}" MATCHES "Open MPI")))
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fsanitize=leak")
endif ()
Expand Down
7 changes: 7 additions & 0 deletions cmake/dependencies.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
set(LIBXS_GIT_REPOSITORY "https://github.com/hfp/libxs.git")
set(LIBXS_GIT_TAG "1d776c091fb41d4aa7bc92335f6387878e1a9db6")

set(LIBXSTREAM_GIT_REPOSITORY "https://github.com/hfp/libxstream.git")
set(LIBXSTREAM_GIT_TAG "87bbd69f0cdf6ca23801923ee201f960fb37860f")

set(LIBXSMM_GIT_TAG "0cea22fdc34ec54bc59ffb47a43cb3e28b26d3e0")
Loading
Loading