Skip to content

Commit

Permalink
Merge pull request #96 from tud-zih-energy/marenz.hwloc-thread-affinity
Browse files Browse the repository at this point in the history
Refactor thread affinity
  • Loading branch information
marenz2569 authored Dec 19, 2024
2 parents 3434879 + 4ca8199 commit 96ca3f7
Show file tree
Hide file tree
Showing 46 changed files with 3,548 additions and 681 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/clang-tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Run CMake configure (default)
run: |
cd build
cmake ..
cmake -DFIRESTARTER_BUILD_TESTS=ON ..
- name: Build
run: |
Expand Down
22 changes: 11 additions & 11 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
export HIPToolkit_ROOT=${HIP_ROOT}
cd build
cmake -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_HIP" -DCMAKE_EXE_LINKER_FLAGS="-L${HIP_ROOT}/lib64/stubs/" ..
cmake -DFIRESTARTER_BUILD_TESTS=ON -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_HIP" -DCMAKE_EXE_LINKER_FLAGS="-L${HIP_ROOT}/lib64/stubs/" ..
- name: Build (HIP)
run: |
cd build
Expand Down Expand Up @@ -126,13 +126,13 @@ jobs:
run: |
. /opt/intel/oneapi/setvars.sh
cd build
cmake -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_ONEAPI" ..
cmake -DFIRESTARTER_BUILD_TESTS=ON -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_ONEAPI" ..
- name: Run CMake configure (OneAPI 2024.0)
if: matrix.ONEAPI == '2024.0'
run: |
. /opt/intel/oneapi/${{ matrix.ONEAPI }}/oneapi-vars.sh
cd build
cmake -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_ONEAPI" ..
cmake -DFIRESTARTER_BUILD_TESTS=ON -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_ONEAPI" ..
- name: Build (OneAPI 2023.2.0)
if: matrix.ONEAPI == '2023.2.0'
run: |
Expand Down Expand Up @@ -223,7 +223,7 @@ jobs:
export CUDAToolkit_ROOT=${CUDA_ROOT}
cd build
cmake -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_CUDA" -DCMAKE_EXE_LINKER_FLAGS="-L${CUDA_ROOT}/lib64/stubs/" ..
cmake -DFIRESTARTER_BUILD_TESTS=ON -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_CUDA" -DCMAKE_EXE_LINKER_FLAGS="-L${CUDA_ROOT}/lib64/stubs/" ..
- name: Run CMake configure (CUDA with NVHPC)
if: matrix.CUDA == 'NVHPC-22.5'
run: |
Expand All @@ -234,7 +234,7 @@ jobs:
LD_LIBRARY_PATH=$CUDA_ROOT/$NVARCH/22.5/cuda/11.7/lib64/stubs:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH
cd build
cmake -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_CUDA" -DCMAKE_EXE_LINKER_FLAGS=-L"$CUDA_ROOT/$NVARCH/22.5/cuda/11.7/lib64/stubs" -LA ..
cmake -DFIRESTARTER_BUILD_TESTS=ON -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_CUDA" -DCMAKE_EXE_LINKER_FLAGS=-L"$CUDA_ROOT/$NVARCH/22.5/cuda/11.7/lib64/stubs" -LA ..
- name: Build (CUDA)
run: |
cd build
Expand Down Expand Up @@ -299,12 +299,12 @@ jobs:
CXX: ${{ matrix.cxxcompiler }}
run: |
cd build
cmake ..
cmake -DFIRESTARTER_BUILD_TESTS=ON ..
- name: Run CMake configure
if: matrix.compiler == 'default'
run: |
cd build
cmake ..
cmake -DFIRESTARTER_BUILD_TESTS=ON ..
- name: Build (default)
run: |
cd build
Expand Down Expand Up @@ -371,21 +371,21 @@ jobs:
shell: pwsh
run: |
cd build
cmake -G "MinGW Makefiles" ..
cmake -DFIRESTARTER_BUILD_TESTS=ON -G "MinGW Makefiles" ..
- name: Run CMake configure
if: matrix.cfg.CUDA == '0' && matrix.cfg.MSVC == true
shell: pwsh
run: |
cd build
cmake -G "NMake Makefiles" ..
cmake -DFIRESTARTER_BUILD_TESTS=ON -G "NMake Makefiles" ..
- name: Run CMake configure
if: matrix.cfg.CUDA != '0'
shell: pwsh
run: |
cd build
ls
dir "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0"
cmake -G "NMake Makefiles" -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_CUDA" -DCUDAToolkit_ROOT="C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v11.0" ..
cmake -DFIRESTARTER_BUILD_TESTS=ON -G "NMake Makefiles" -DFIRESTARTER_BUILD_TYPE="FIRESTARTER_CUDA" -DCUDAToolkit_ROOT="C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v11.0" ..
- name: Build
shell: pwsh
run: |
Expand Down Expand Up @@ -444,7 +444,7 @@ jobs:
- name: Run CMake configure
run: |
cd build
cmake ..
cmake -DFIRESTARTER_BUILD_TESTS=ON ..
- name: Build
run: |
cd build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ctest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Run CMake configure (default)
run: |
cd build
cmake ..
cmake -DFIRESTARTER_BUILD_TESTS=ON ..
- name: Build
run: |
Expand Down
5 changes: 4 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
$$ TODO
$$ TODO Version 2.x
$$ TODO - add results verification
$$ TODO - add AMD GPUs
$$ TODO - add more processors
$$ TODO - support for AArch64 (64 Bit ARM)
$$ TODO - support Infiniband interconnects
$$ TODO
$$ TODO Version 2.2
$$ TODO - added support for AMD GPUs
$$ TODO - support for thread binding on all supported platforms
$$ TODO - bug fixes related to thread binding with cgroups

Version 2.1.1
- Removed MacOS 11
Expand Down
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

include(cmake/InstallHwloc.cmake)
include(cmake/InstallGoogleTest.cmake)

add_subdirectory(src)

add_subdirectory(test)
if(FIRESTARTER_BUILD_TESTS)
add_subdirectory(test)
endif()
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,11 @@ GCC (>=7) or Clang (>=9) is supported.

CMake option | Description
:---------------------------- | :----------------------------
`FIRESTARTER_BUILD_TYPE` | Can be any of `FIRESTARTER`, `FIRESTARTER_CUDA`, `FIRESTARTER_ONEAPI`, or `FIRESTARTER_HIP`. Default `FIRESTARTER`
`FIRESTARTER_LINK_STATIC` | Link FIRESTARTER as a static binary. Note, dlopen is not supported in static binaries. This option is not available on macOS or with CUDA or OneAPI enabled. Default `ON`
`FIRESTARTER_BUILD_HWLOC` | Build hwloc dependency. Default `ON`
`FIRESTARTER_THREAD_AFFINITY` | Enable FIRESTARTER to set affinity to hardware threads. Default `ON`
`FIRESTARTER_BUILD_TYPE` | Can be any of `FIRESTARTER`, `FIRESTARTER_CUDA`, `FIRESTARTER_ONEAPI`, or `FIRESTARTER_HIP`. Default: `FIRESTARTER`
`FIRESTARTER_LINK_STATIC` | Link FIRESTARTER as a static binary. Note, dlopen is not supported in static binaries. This option is not available on macOS or with CUDA or OneAPI enabled. Default: `ON`
`FIRESTARTER_BUILD_HWLOC` | Build hwloc dependency. Default: `ON`
`FIRESTARTER_BUILD_TESTS` | Enable the tests. Default: `OFF`
`FIRESTARTER_FETCH_GOOGLETEST`| Fetch the GoogleTest dependency. Default: `ON`

When building `FIRESTARTER_ONEAPI` make sure that the Intel Math Kernel
Library (MKL) and the compiler `icx` and `icpx` can be found. Please provide
Expand Down
8 changes: 4 additions & 4 deletions cmake/BuildOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ endif()
# We vendor hwloc per default.
option(FIRESTARTER_BUILD_HWLOC "Build hwloc dependency." ON)

# Should we compile the tests
option(FIRESTARTER_BUILD_TESTS "Enable the tests" OFF)

# Use of thread affinity is enabled on linux per default.
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(FIRESTARTER_THREAD_AFFINITY "Enable FIRESTARTER to set affinity to hardware threads." ON)
endif()
# We fetch google test per default
option(FIRESTARTER_FETCH_GOOGLETEST "Fetch the Google Test dependency." ON)


# Debug feature are enabled on linux per default.
Expand Down
4 changes: 0 additions & 4 deletions cmake/BuildSettings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ if (FIRESTARTER_DEBUG_FEATURES)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFIRESTARTER_DEBUG_FEATURES")
endif()

if (FIRESTARTER_THREAD_AFFINITY)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFIRESTARTER_THREAD_AFFINITY")
endif()


# Not MSVC
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
Expand Down
24 changes: 24 additions & 0 deletions cmake/InstallGoogleTest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This will install the Google Test dependency for FIRESTARTER

# configure build of googletest
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
set(BUILD_GMOCK OFF CACHE BOOL "" FORCE)

# Do not execute the google test executable during build.
set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE PRE_TEST)

if (FIRESTARTER_FETCH_GOOGLETEST)
include(FetchContent)

# GoogleTest should use the latest commit available
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/d122c0d435a6d305cdd50526127c84a98b77d87b.zip
)

FetchContent_MakeAvailable(googletest)
else()
find_package(GTest REQUIRED)
message(STATUS "GTEST_INCLUDE_DIR: ${GTEST_INCLUDE_DIR}")
message(STATUS "GTEST_LIBRARIES: ${GTEST_LIBRARIES}")
endif()
100 changes: 100 additions & 0 deletions include/firestarter/CPUTopology.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/******************************************************************************
* FIRESTARTER - A Processor Stress Test Utility
* Copyright (C) 2024 TU Dresden, Center for Information Services and High
* Performance Computing
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/\>.
*
* Contact: [email protected]
*****************************************************************************/

#pragma once

#include <optional>
#include <ostream>
#include <set>

extern "C" {
#include <hwloc.h>
}

namespace firestarter {

/// This struct describes properties of the threads which are used in the Environment class to assign a specific number
/// of threads and/or use it for cpu binding.
struct HardwareThreadsInfo {
HardwareThreadsInfo() = default;

/// The number of hardware threads on this system.
unsigned MaxNumThreads = 0;
/// The highest physical index on a hardware thread in the system.
unsigned MaxPhysicalIndex = 0;
/// The list of os indices which are available on the system.
std::set<unsigned> OsIndices;
/// The optional number of different cpu kinds.
std::optional<unsigned> CpuKindCount;
};

/// Given that the processor is homogenous. I.e. all cores/packages are of the same type and the are equally
/// distributed, this struct define the numbers of packages, core and threads per core.
struct HomogenousResourceCount {
/// The number of packages available
unsigned NumPackagesTotal;
/// The number of cores available
unsigned NumCoresTotal;
/// Assuming we have a consistent number of threads per core. The number of thread per core.
unsigned NumThreadsPerCore;
};

/// This class models the topology of the processor and its associated packages, cores, threads and caches.
class CPUTopology {
public:
CPUTopology();
virtual ~CPUTopology();

/// Print information about the number of packages, cores and threads.
void printSystemSummary(std::ostream& Stream) const;

/// Print information about the cache hierarchy.
void printCacheSummary(std::ostream& Stream) const;

/// Get the size of the first instruction cache.
[[nodiscard]] auto instructionCacheSize() const -> std::optional<unsigned>;

/// Given that the processor is homogenous we give back meaningful numbers for the available resouces.
[[nodiscard]] auto homogenousResourceCount() const -> HomogenousResourceCount;

/// Get the properties about the hardware threads.
[[nodiscard]] auto hardwareThreadsInfo() const -> HardwareThreadsInfo;

/// Get the logical index of the core that housed the PU which is described by the os index.
/// \arg Pu The os index of the thread.
/// \returns Optionally the logical index of the CPU that houses this hardware thread.
[[nodiscard]] auto getCoreIdFromPU(unsigned Pu) const -> std::optional<unsigned>;

/// Get the logical index of the package that housed the PU which is described by the os index.
/// \arg Pu The os index of the thread.
/// \returns Optionally the logical index of the package that houses this hardware thread.
[[nodiscard]] auto getPkgIdFromPU(unsigned Pu) const -> std::optional<unsigned>;

/// Set the CPU affinity of the calling thread to the os index in the argument.
/// \arg OsIndex The os index to which the calling thread should be bound.
void bindCallerToOsIndex(unsigned OsIndex) const;

private:
/// The hwloc topology that is used to query information about the processor.
hwloc_topology_t Topology{};
};

} // namespace firestarter
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#pragma once

#include <chrono>
#include <cstdint>
#include <optional>
#include <set>
#include <string>
#include <vector>

Expand Down Expand Up @@ -65,7 +68,7 @@ struct Config {
std::vector<std::string> OptimizationMetrics;

/// The optional cpu bind that allow pinning to specific cpus.
std::string CpuBind;
std::optional<std::set<uint64_t>> CpuBinding;
/// The optional selected instruction groups. If this is empty the default will be choosen.
std::string InstructionGroups;
/// The file where the dump register feature will safe its output to.
Expand All @@ -78,7 +81,7 @@ struct Config {
/// The argument count from the command line.
int Argc;
/// The requested number of threads firestarter should run with. 0 means all threads.
unsigned RequestedNumThreads;
std::optional<unsigned> RequestedNumThreads;
/// The selected function id. 0 means automatic selection.
unsigned FunctionId;
/// The line count of the payload. 0 means default.
Expand Down
39 changes: 39 additions & 0 deletions include/firestarter/Config/CpuBind.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/******************************************************************************
* FIRESTARTER - A Processor Stress Test Utility
* Copyright (C) 2024 TU Dresden, Center for Information Services and High
* Performance Computing
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/\>.
*
* Contact: [email protected]
*****************************************************************************/

#pragma once

#include <cstdint>
#include <set>
#include <string>

namespace firestarter {

/// Struct to parse the CPU binding list from a string. The format is "x,y,z", "x-y", "x-y/step", and any combination.
struct CpuBind {
/// Parse the cpu bind string and return a vector containing the parsed number of all selected cpus.
/// \arg CpuBindString The string containing the cpu binding in the format "x,y,z", "x-y", "x-y/step", and any
/// combination.
/// \returns The set of parsed CPUs.
static auto fromString(const std::string& CpuBindString) -> std::set<uint64_t>;
};

} // namespace firestarter
Loading

0 comments on commit 96ca3f7

Please sign in to comment.