Skip to content

Commit

Permalink
Print warning when too few logical cores are available
Browse files Browse the repository at this point in the history
  • Loading branch information
facuMH authored Feb 1, 2022
1 parent 30248fb commit 113e688
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ set(SOURCES
"${CMAKE_CURRENT_BINARY_DIR}/src/version.cc"
)

if(WIN32)
set(SOURCES ${SOURCES} src/platform_specific/affinity.win.cc)
elseif(UNIX)
set(SOURCES ${SOURCES} src/platform_specific/affinity.unix.cc)
endif()

add_library(
celerity_runtime
STATIC
Expand Down
15 changes: 15 additions & 0 deletions include/affinity.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <cstdint>

namespace celerity {
namespace detail {

uint32_t affinity_cores_available();

/* a priori we need 3 threads, plus 1 for parallel-task workers and at least one more for host-task.
This depends on the application invoking celerity. */
constexpr static uint64_t min_cores_needed = 5;

} // namespace detail
} // namespace celerity
23 changes: 23 additions & 0 deletions include/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <cstdint>
#include <type_traits>

namespace celerity {
namespace detail {
namespace utils {

template <typename BitMaskT>
constexpr inline uint32_t popcount(const BitMaskT bit_mask) noexcept {
static_assert(std::is_integral_v<BitMaskT> && std::is_unsigned_v<BitMaskT>, "popcount argument needs to be an unsigned integer type.");

uint32_t counter = 0;
for(auto b = bit_mask; b; b >>= 1) {
counter += b & 1;
}
return counter;
}

} // namespace utils
} // namespace detail
} // namespace celerity
21 changes: 21 additions & 0 deletions src/platform_specific/affinity.unix.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

#include <cassert>
#include <cstdint>

#include <pthread.h>
#include <sched.h>

#include "affinity.h"

namespace celerity {
namespace detail {

uint32_t affinity_cores_available() {
cpu_set_t available_cores;
const auto affinity_error = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &available_cores);
assert(affinity_error == 0 && "Error retrieving affinity mask.");
return CPU_COUNT(&available_cores);
}

} // namespace detail
} // namespace celerity
22 changes: 22 additions & 0 deletions src/platform_specific/affinity.win.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <cassert>

#include <Windows.h>

#include "affinity.h"
#include "utils.h"

namespace celerity {
namespace detail {

uint32_t affinity_cores_available() {
using native_cpu_set = DWORD_PTR;

native_cpu_set available_cores;
[[maybe_unused]] native_cpu_set sys_affinity_mask;
const auto affinity_error = GetProcessAffinityMask(GetCurrentProcess(), &available_cores, &sys_affinity_mask);
assert(affinity_error != FALSE && "Error retrieving affinity mask.");
return utils::popcount(available_cores);
}

} // namespace detail
} // namespace celerity
9 changes: 9 additions & 0 deletions src/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <mpi.h>

#include "affinity.h"
#include "buffer.h"
#include "buffer_manager.h"
#include "command_graph.h"
Expand All @@ -23,6 +24,7 @@
#include "scheduler.h"
#include "task_manager.h"
#include "user_bench.h"
#include "utils.h"
#include "version.h"

namespace celerity {
Expand Down Expand Up @@ -98,8 +100,15 @@ namespace detail {
cfg = std::make_unique<config>(argc, argv, *default_logger);
graph_logger->set_level(cfg->get_log_level());

if(const uint32_t cores = affinity_cores_available(); cores < min_cores_needed) {
default_logger->warn("Celerity has detected that only {} logical cores are available to this process. It is recommended to assign at least {} "
"logical cores. Performance may be negatively impacted.",
cores, min_cores_needed);
}

user_bench = std::make_unique<experimental::bench::detail::user_benchmarker>(*cfg, static_cast<node_id>(world_rank));


h_queue = std::make_unique<host_queue>(*default_logger);
d_queue = std::make_unique<device_queue>(*default_logger);

Expand Down
27 changes: 27 additions & 0 deletions test/runtime_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@
#include <memory>
#include <random>

#ifdef _WIN32
#include <Windows.h>
#else
#include <pthread.h>
#endif

#include <catch2/catch.hpp>

#include <celerity.h>

#include "affinity.h"
#include "ranges.h"
#include "region_map.h"

Expand Down Expand Up @@ -2305,5 +2312,25 @@ namespace detail {
}
}


TEST_CASE("affinity check", "[affinity]") {
#ifdef _WIN32
SECTION("in Windows") {
DWORD_PTR cpu_mask = 1;
SetProcessAffinityMask(GetCurrentProcess(), cpu_mask);
}
#else
SECTION("in Posix") {
cpu_set_t cpu_mask;
CPU_ZERO(&cpu_mask);
CPU_SET(0, &cpu_mask);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_mask), &cpu_mask);
}
#endif
const auto cores = affinity_cores_available();
REQUIRE(cores == 1);
}


} // namespace detail
} // namespace celerity

0 comments on commit 113e688

Please sign in to comment.