Skip to content

Commit

Permalink
CMake: Improving how CMake system handles targets.
Browse files Browse the repository at this point in the history
- Instead of putting the built libraries in  blis/bin directory, build them in the chosen build-cmake directory.
- Install headers in <prefix>/include instead of <prefix>/include/blis.
- Fix on some targets to match configure/make system.
- Update documentation.

AMD-Internal: [CPUPL-2748]
Change-Id: I15553948209345dbee350e89965b6a3c72a4e340
  • Loading branch information
Eleni Vlachopoulou committed Nov 24, 2023
1 parent 5a88182 commit 664a175
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 75 deletions.
82 changes: 38 additions & 44 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,19 @@ if(WIN32)
option(ENABLE_NO_UNDERSCORE_API "Export APIs without underscore." OFF)
option(ENABLE_UPPERCASE_API "Export APIs with uppercase." OFF)
# Setting path to OpenMP runtime.
set(OpenMP_libomp_LIBRARY "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/Llvm/x64/lib/libomp.lib" CACHE STRING "openmp library path")
set(OpenMP_libomp_LIBRARY "C:/Program Files/LLVM/lib/libomp.lib" CACHE STRING "openmp library path")
endif()
set(ENABLE_DEBUG "off" CACHE STRING "Enable debugging symbols in the library.")
set_property(CACHE ENABLE_DEBUG PROPERTY STRINGS "off" "noopt" "opt")
if( NOT ((ENABLE_DEBUG STREQUAL "off") OR (ENABLE_DEBUG STREQUAL "noopt") OR (ENABLE_DEBUG STREQUAL "opt")) )
message(FATAL_ERROR "ENABLE_DEBUG option '${ENABLE_DEBUG}' is not supported. Please use one of the following options \
during CMake invokation: off, noopt, opt")
endif()
# Check if user provided CMAKE_BUILD_TYPE. If that's the case, map it to the internal ENABLE_DEBUG type
# and clean cache from CMAKE_BUILD_TYPE. We do this because CMake will add some flags depending on the
# the build type and on Linux we want to have more control over what flags are being used.
# Debug & Release flags option setting is only available for Linux. On Windows the default flags are used.
if(NOT WIN32)
set(ENABLE_DEBUG "off" CACHE STRING "Enable debugging symbols in the library.")
set_property(CACHE ENABLE_DEBUG PROPERTY STRINGS "off" "noopt" "opt")
if( NOT ((ENABLE_DEBUG STREQUAL "off") OR (ENABLE_DEBUG STREQUAL "noopt") OR (ENABLE_DEBUG STREQUAL "opt")) )
message(FATAL_ERROR "ENABLE_DEBUG option '${ENABLE_DEBUG}' is not supported. Please use one of the following options \
during CMake invokation: off, noopt, opt")
endif()
# Check if user provided CMAKE_BUILD_TYPE. If that's the case, map it to the internal ENABLE_DEBUG type
# and clean cache from CMAKE_BUILD_TYPE. We do this because CMake will add some flags depending on the
# the build type and on Linux we want to have more control over what flags are being used.
if(CMAKE_BUILD_TYPE)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(ENABLE_DEBUG "noopt")
Expand Down Expand Up @@ -200,11 +201,14 @@ if( NOT ((THREAD_PART_JRIR STREQUAL "slab") OR (THREAD_PART_JRIR STREQUAL "rr"))
message(FATAL_ERROR "THREAD_PART_JRIR option '${THREAD_PART_JRIR}' is not supported. Please use one of the following options \
during CMake invokation: slab, rr")
endif()
set(EXPORT_SHARED "public" CACHE STRING "Specify the subset of library symbols that are exported within a shared library.")
set_property(CACHE EXPORT_SHARED PROPERTY STRINGS "public" "all")
if( NOT ((EXPORT_SHARED STREQUAL "public") OR (EXPORT_SHARED STREQUAL "all")) )
message(FATAL_ERROR "EXPORT_SHARED option '${EXPORT_SHARED}' is not supported. Please use one of the following options \
during CMake invokation: publis, all")
# Export symbols only for Linux.
if(NOT WIN32)
set(EXPORT_SHARED "public" CACHE STRING "Specify the subset of library symbols that are exported within a shared library.")
set_property(CACHE EXPORT_SHARED PROPERTY STRINGS "public" "all")
if( NOT ((EXPORT_SHARED STREQUAL "public") OR (EXPORT_SHARED STREQUAL "all")) )
message(FATAL_ERROR "EXPORT_SHARED option '${EXPORT_SHARED}' is not supported. Please use one of the following options \
during CMake invokation: public, all")
endif()
endif()
option(ENABLE_PBA_POOLS "Internal memory pools for packing blocks" ON)
option(ENABLE_SBA_POOLS "Internal memory pools for small blocks" ON)
Expand Down Expand Up @@ -343,16 +347,18 @@ else()
message(" Building BLIS as a static library.")
set(ENABLE_SHARED_01 0)
endif()
if(NOT WIN32)
cmake_print_variables(EXPORT_SHARED)
if(EXPORT_SHARED STREQUAL "all")
if(BUILD_SHARED_LIBS)
message(" Exporting all symbols within shared library.")
if(EXPORT_SHARED STREQUAL "all")
if(BUILD_SHARED_LIBS)
message(" Exporting all symbols within shared library.")
else()
message(" Ignoring request to export all symbols within shared library.")
endif()
else()
message(" Ignoring request to export all symbols within shared library.")
endif()
else()
if(BUILD_SHARED_LIBS)
message(" Exporting only public symbols within shared library.")
if(BUILD_SHARED_LIBS)
message(" Exporting only public symbols within shared library.")
endif()
endif()
endif()
cmake_print_variables(ENABLE_SYSTEM)
Expand Down Expand Up @@ -1059,20 +1065,12 @@ endif()
# Add headers as a property to the library.
set_target_properties(libblis PROPERTIES PUBLIC_HEADER "${BLIS_PUBLIC_HEADERS}")
set_target_properties(libblis PROPERTIES OUTPUT_NAME ${LIBBLIS})
if(WIN32)
set_target_properties(libblis
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin"
)
endif()

# Install targets.
install(TARGETS libblis LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/include/blis)
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/include)

# --- Primary targets ---
add_custom_target(libs DEPENDS libblis)
Expand All @@ -1088,20 +1086,16 @@ if(ENABLE_BLAS)
add_subdirectory(blastest EXCLUDE_FROM_ALL)
endif()

# Add generic testing target.
# Add generic testing target `test`.
set(available_testsuites checkblis)
if(ENABLE_BLAS)
list(APPEND available_testsuites checkblas)
endif()
add_custom_target(check DEPENDS ${available_testsuites})
add_custom_target(test DEPENDS ${available_testsuites})

#--------------------------------------------
# Clean-up
#--------------------------------------------
# Add distclean target
add_custom_target(distclean
COMMAND ${CMAKE_BUILD_TOOL} clean
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/build/distclean.cmake
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Remove cmake_generated files and executables"
)
# Add generic testing target `check`.
set(available_testsuites checkblis-fast)
if(ENABLE_BLAS)
list(APPEND available_testsuites checkblas)
endif()
add_custom_target(check DEPENDS ${available_testsuites})
18 changes: 10 additions & 8 deletions blastest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,32 +100,34 @@ foreach(source ${blastest_sources})
set_target_properties(${exec_name}.x PROPERTIES FOLDER blastest-targets)
# Add a target for running the tests. Rules are different for level-1 APIs, compared to levels 2 and 3.
if(${exec_name} MATCHES 1)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/out.${exec_name}
COMMAND ${exec_name}.x > ${CMAKE_BINARY_DIR}/out.${exec_name}
COMMENT "Running ${exec_name}.x with output redirected to ${CMAKE_BINARY_DIR}/out.${exec_name}"
add_custom_target(run-${exec_name}
COMMAND ${exec_name}.x > out.${exec_name}
COMMENT "Running ${exec_name}.x with output redirected to out.${exec_name}"
DEPENDS ${exec_name}.x
BYPRODUCTS ${CMAKE_BINARY_DIR}/out.${exec_name}
WORKING_DIRECTORY $<TARGET_FILE_DIR:libblis>
VERBATIM
)
else()# name has 2 or 3
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/out.${exec_name}
add_custom_target(run-${exec_name}
COMMAND ${exec_name}.x < ${CMAKE_CURRENT_SOURCE_DIR}/input/${exec_name}.in
COMMENT "Running ${exec_name}.x with output saved to ${CMAKE_BINARY_DIR}/out.${exec_name}"
COMMENT "Running ${exec_name}.x with input ${CMAKE_CURRENT_SOURCE_DIR}/input/${exec_name}.in and output saved to out.${exec_name}"
DEPENDS ${exec_name}.x
BYPRODUCTS ${CMAKE_BINARY_DIR}/out.${exec_name}
WORKING_DIRECTORY $<TARGET_FILE_DIR:libblis>
VERBATIM
)
endif()
add_custom_target(run-${exec_name} DEPENDS ${CMAKE_BINARY_DIR}/out.${exec_name})
# Put all those targets under blastest-targets-targets folder name so that they appear all together in IDE.
set_target_properties(run-${exec_name} PROPERTIES FOLDER blastest-targets)
list(APPEND test_executables "run-${exec_name}")
endforeach()

add_custom_target(testblas DEPENDS ${test_executables})
add_custom_target(checkblas
COMMAND ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/build/cmake/check-blastest.py ${CMAKE_BINARY_DIR}
COMMAND ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/build/cmake/check-blastest.py "."
DEPENDS testblas
WORKING_DIRECTORY $<TARGET_FILE_DIR:libblis>
)
# Put all those targets under blastest-targets-targets folder name so that they appear all together in IDE.
set_target_properties(testblas checkblas PROPERTIES FOLDER blastest-targets)
set_target_properties(testblas checkblas PROPERTIES FOLDER blastest-targets)
38 changes: 23 additions & 15 deletions docs/CMakeBuildSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ The BLIS CMake system is based on the [Make build system](BuildSystem.md) and is
* Python (3.4 or later for python3)
* GNU `make` (3.81 or later) on Linux
* Visual Studio 17 2022 on Windows
* a working C99 compiler (gcc or clang on Linux and clang-cl **only** on Windows)
* a working C99 compiler (gcc or clang on Linux and **only** clang-cl on Windows)

Note that, on Windows, BLIS implements basic pthreads functionality automatically, so a POSIX threads is not required. On Linux, the implementation is the same to the one of the Make system.
**_NOTE:_**
To get clang-cl on Visual Studio, one needs to choose "C++ Clang tools for Windows" when installing "Desktop development with C++" with Visual Studio.

CMake is used to build out of source so we need to start by creating a build directory from which we will do the configuration and build steps. Since there is a directory called blis/build, the build directory must have a different name. Here is an example on how to create the directory:
Note that, on Windows, BLIS implements basic pthreads functionality automatically, so a POSIX threads library is not required. On Linux, the implementation is the same to the one of the Make system.

CMake is used to build out of source, so we need to start by creating a build directory from which we will do the configuration and build. Since there is a directory called blis/build, the build directory must have a different name. Here is an example of creating the directory:
```
$ mkdir build_blis
$ cd build_blis
Expand All @@ -44,7 +47,7 @@ The first step is to choose the appropriate BLIS configuration. As on the Make b
* zen4
* generic

Instructions on how to add a configuration on the CMake system, are provided in a later section.
Instructions on how to add a configuration on the CMake system, are provided in [Adding configurations](CMakeBuildSystem.md#adding-configurations).

### Multithreading

Expand Down Expand Up @@ -91,9 +94,9 @@ We remind users that to specify the installation prefix in cmake, one needs to c
```
cmake .. -DBLIS_CONFIG_FAMILY=auto -DCMAKE_INSTALL_PREFIX=<prefix>
```
This will cause libraries to eventually be installed to `<prefix>/lib` and headers will be installed to `<prefix>/include/blis`.
This will cause libraries to eventually be installed to `<prefix>/lib` and headers will be installed to `<prefix>/include`.

Options to specify the library install and the header install separately, like in Make system, is not currently supported by the CMake equivalent.
Option to specify the library install and the header install separately, like in Make system, is not currently supported by the CMake equivalent.

## Step 3: Compilation

Expand Down Expand Up @@ -155,14 +158,21 @@ The BLIS CMake system aims to be combatible with the current `make` system. For
| `testblis-salt` | Run the BLIS testsuite while simulating application-level threading (runs for a few seconds). |
| `testsuite` | Same as `testblis`. |
| `testblas` | Run the BLAS test drivers with default parameters (runs for a few seconds). |
| `checkbliscpp` | Run the BLIS C++ tests (runs for a few seconds). |

**_NOTE:_**
Using those targets sets the environment appropriately, so copying the input files and/or the DLL in case of Windows builds is not required.

### Running the testsuites.
### Running the testsuites
* On Linux all targets can be build and run in `build_blis` directory.
* On Windows, when Visual Studio has been used as a generator, one can build and run the blis API related tests from testsuite directory and blas API tests from blastest directory.
* On Windows, when Visual Studio has been used as a generator, one can build and run the blis API related tests from `build_blis/testsuite` directory and blas API tests from `build_blis/blastest` directory. To build and run the BLIS C++ interface tests, execute the target `checkbliscpp` in `build_blis/vendor/testcpp` directory. The targets `check` and `test` can be used in `build_blis` directory.
* On Windows, if Visual Studio is used to build the library and tests, note that only the high level targets will appear. All targets are available to build from the command prompt.

## Adding configurations

ToDo
The CMake system is designed to closely relate to the BLIS Make system. Assuming that a user has followed the steps in [Configuration How To](ConfigurationHowTo.md), adding the new configuration on the CMake system requires the following steps:
* Add a `make_defs.cmake` file which is equivalent to `make_defs.mk`. One can see `blis/config/zen/make_defs.cmake` and `blis/config/zen/make_defs.mk` for an example.
* Update `blis/CMakeLists.txt` to remove the error for the particular new configuration and to add the option in `set_property()` so that it appears in cmake-gui.

## Some examples

Expand Down Expand Up @@ -197,6 +207,9 @@ cmake .. -G "Visual Studio 17 2022" -TClangCl -DENABLE_THREADING=openmp -DINT_SI

### Example 2: single-threaded ILP64 libraries for amdzen configuration with aocl_gemm addon enabled and default compiler

**_NOTE:_**
Addon functionality is currently available only on Linux.

* With configure script:
```
./configure --enable-threading=no --int-size=64 --blas-int-size=64 --enable-addon=aocl_gemm amdzen
Expand All @@ -207,11 +220,6 @@ cmake .. -G "Visual Studio 17 2022" -TClangCl -DENABLE_THREADING=openmp -DINT_SI
cmake .. -DENABLE_THREADING=no -DINT_SIZE=64 -DBLAS_INT_SIZE=64 -DENABLE_ADDON=aocl_gemm -DBLIS_CONFIG_FAMILY=amdzen
```

* With CMake on Windows:
```
cmake .. -G "Visual Studio 17 2022" -TClangCl -DENABLE_THREADING=no -DINT_SIZE=64 -DBLAS_INT_SIZE=64 -DENABLE_ADDON=aocl_gemm -DBLIS_CONFIG_FAMILY=amdzen
```

## Conclusion

The BLIS CMake system is developed and maintained by AMD. You can contact us on the email-id toolchainsupport@amd.com. You can also raise any issue/suggestion on the git-hub repository at https://github.com/amd/blis/issues.
The BLIS CMake system is developed and maintained by AMD. You can contact us on the email-id toolchainsupport@amd.com. You can also raise any issue/suggestion on the git-hub repository at https://github.com/amd/blis/issues.
15 changes: 7 additions & 8 deletions testsuite/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +74,20 @@ function(add_testblis flavour)
set(dashflavour -${flavour})
set(printflavour "(${flavour})")
endif()
# A rule to run the testsuite using the input.*${dotflavour} files, which
# run a set of tests designed to finish much more quickly.
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.testsuite${dotflavour}
# A rule to run the testsuite using the input.*${dotflavour} files.
add_custom_target(testblis${dashflavour}
COMMAND test_libblis.x -g ${CMAKE_CURRENT_SOURCE_DIR}/input.general${dotflavour} -o ${CMAKE_CURRENT_SOURCE_DIR}/input.operations${dotflavour} > ${CMAKE_CURRENT_BINARY_DIR}/output.testsuite${dotflavour}
COMMENT "Running test_libblis.x ${printflavour} with output redirected to ${CMAKE_CURRENT_BINARY_DIR}/output.testsuite${dotflavour}"
DEPENDS test_libblis.x ${CMAKE_CURRENT_SOURCE_DIR}/input.general${dotflavour} ${CMAKE_CURRENT_SOURCE_DIR}/input.operations${dotflavour}
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/output.testsuite${dotflavour}
WORKING_DIRECTORY $<TARGET_FILE_DIR:libblis>
VERBATIM
)
add_custom_target(testblis${dashflavour} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/output.testsuite${dotflavour})
)
# Check the results of the BLIS testsuite.
add_custom_target(checkblis${dashflavour}
COMMAND ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/build/cmake/check-blistest.py ${CMAKE_CURRENT_BINARY_DIR}/output.testsuite${dotflavour}
DEPENDS testblis${dashflavour}
)
COMMAND ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/build/cmake/check-blistest.py ${CMAKE_CURRENT_BINARY_DIR}/output.testsuite${dotflavour}
DEPENDS testblis${dashflavour}
)
endfunction()

# Add testing targets using functions above for all input file options.
Expand Down

0 comments on commit 664a175

Please sign in to comment.