diff options
author | Jerry Zhang <jerryzh@fb.com> | 2018-12-12 12:06:09 -0800 |
---|---|---|
committer | Facebook Github Bot <facebook-github-bot@users.noreply.github.com> | 2018-12-12 12:21:10 -0800 |
commit | 63e77ab6c46774e4c42c00f74ed2f83c71c6e6bd (patch) | |
tree | adcdb9d060572dbbca19684a461550f5e361be80 /c10 | |
parent | b34ab435efd9b4d839171d27bd6a0f321178d46b (diff) | |
download | pytorch-63e77ab6c46774e4c42c00f74ed2f83c71c6e6bd.tar.gz pytorch-63e77ab6c46774e4c42c00f74ed2f83c71c6e6bd.tar.bz2 pytorch-63e77ab6c46774e4c42c00f74ed2f83c71c6e6bd.zip |
Move numa.{h, cc} to c10/util (#15024)
Summary:
Pull Request resolved: https://github.com/pytorch/pytorch/pull/15024
Pull Request resolved: https://github.com/pytorch/pytorch/pull/14393
att
Reviewed By: dzhulgakov
Differential Revision: D13380559
fbshipit-source-id: abc3fc7321cf37323f756dfd614c7b41978734e4
Diffstat (limited to 'c10')
-rw-r--r-- | c10/CMakeLists.txt | 16 | ||||
-rw-r--r-- | c10/macros/cmake_macros.h.in | 1 | ||||
-rw-r--r-- | c10/util/numa.cpp | 143 | ||||
-rw-r--r-- | c10/util/numa.h | 40 |
4 files changed, 200 insertions, 0 deletions
diff --git a/c10/CMakeLists.txt b/c10/CMakeLists.txt index 8e5ddc4042..e80dd795c2 100644 --- a/c10/CMakeLists.txt +++ b/c10/CMakeLists.txt @@ -16,6 +16,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(C10_USE_GFLAGS ${USE_GFLAGS}) # used in cmake_macros.h.in set(C10_USE_GLOG ${USE_GLOG}) # used in cmake_macros.h.in set(C10_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) # used in cmake_macros.h.in +set(C10_USE_NUMA ${USE_NUMA}) +set(C10_DISABLE_NUMA ${CAFFE2_DISABLE_NUMA}) # used in cmake_macros.h.in configure_file( ${CMAKE_CURRENT_LIST_DIR}/macros/cmake_macros.h.in ${CMAKE_BINARY_DIR}/c10/macros/cmake_macros.h) @@ -50,6 +52,20 @@ if (${USE_GLOG}) target_link_libraries(c10 PUBLIC glog::glog) endif() +if (USE_NUMA) + if (NOT CAFFE2_DISABLE_NUMA) + message(STATUS "NUMA paths:") + message(STATUS ${Numa_INCLUDE_DIR}) + message(STATUS ${Numa_LIBRARIES}) + include_directories(SYSTEM ${Numa_INCLUDE_DIR}) + target_link_libraries(c10 PRIVATE ${Numa_LIBRARIES}) + else() + message(STATUS "NUMA is disabled") + endif() +else() + message(STATUS "don't use NUMA") +endif() + if (ANDROID) target_link_libraries(c10 PRIVATE log) endif() diff --git a/c10/macros/cmake_macros.h.in b/c10/macros/cmake_macros.h.in index 29f8705fa1..5b20360af5 100644 --- a/c10/macros/cmake_macros.h.in +++ b/c10/macros/cmake_macros.h.in @@ -7,5 +7,6 @@ #cmakedefine C10_BUILD_SHARED_LIBS #cmakedefine C10_USE_GLOG #cmakedefine C10_USE_GFLAGS +#cmakedefine C10_DISABLE_NUMA #endif // C10_MACROS_CMAKE_MACROS_H_ diff --git a/c10/util/numa.cpp b/c10/util/numa.cpp new file mode 100644 index 0000000000..4a5086ec7a --- /dev/null +++ b/c10/util/numa.cpp @@ -0,0 +1,143 @@ +#include "c10/util/numa.h" + +C10_DEFINE_bool(caffe2_cpu_numa_enabled, false, "Use NUMA whenever possible."); + +#if defined(__linux__) && !defined(C10_DISABLE_NUMA) && C10_MOBILE == 0 +#include <numa.h> +#include <numaif.h> +#include <unistd.h> +#define C10_ENABLE_NUMA +#endif + +namespace c10 { + +#ifdef C10_ENABLE_NUMA +bool IsNUMAEnabled() { + return FLAGS_caffe2_cpu_numa_enabled && numa_available() >= 0; +} + +void NUMABind(int numa_node_id) { + if (numa_node_id < 0) { + return; + } + if (!IsNUMAEnabled()) { + VLOG(1) << "NUMA is not enabled"; + return; + } + + AT_CHECK( + numa_node_id <= numa_max_node(), + "NUMA node id ", + numa_node_id, + " is unavailable"); + + auto bm = numa_allocate_nodemask(); + numa_bitmask_setbit(bm, numa_node_id); + numa_bind(bm); + numa_bitmask_free(bm); +} + +int GetNUMANode(const void* ptr) { + if (!IsNUMAEnabled()) { + VLOG(1) << "NUMA is not enabled"; + return -1; + } + AT_ASSERT(ptr); + + int numa_node = -1; + AT_CHECK( + get_mempolicy( + &numa_node, + NULL, + 0, + const_cast<void*>(ptr), + MPOL_F_NODE | MPOL_F_ADDR) == 0, + "Unable to get memory policy, errno:", + errno); + return numa_node; +} + +int GetNumNUMANodes() { + if (!IsNUMAEnabled()) { + VLOG(1) << "NUMA is not enabled"; + return -1; + } + + return numa_num_configured_nodes(); +} + +void NUMAMove(void* ptr, size_t size, int numa_node_id) { + if (numa_node_id < 0) { + return; + } + if (!IsNUMAEnabled()) { + VLOG(1) << "NUMA is not enabled"; + return; + } + AT_ASSERT(ptr); + + uintptr_t page_start_ptr = + ((reinterpret_cast<uintptr_t>(ptr)) & ~(getpagesize() - 1)); + ptrdiff_t offset = reinterpret_cast<uintptr_t>(ptr) - page_start_ptr; + // Avoid extra dynamic allocation and NUMA api calls + AT_ASSERT( + numa_node_id >= 0 && + static_cast<unsigned>(numa_node_id) < sizeof(unsigned long) * 8); + unsigned long mask = 1UL << numa_node_id; + AT_CHECK( + mbind( + reinterpret_cast<void*>(page_start_ptr), + size + offset, + MPOL_BIND, + &mask, + sizeof(mask) * 8, + MPOL_MF_MOVE | MPOL_MF_STRICT) == 0, + "Could not move memory to a NUMA node"); +} + +int GetCurrentNUMANode() { + if (!IsNUMAEnabled()) { + VLOG(1) << "NUMA is not enabled"; + return -1; + } + + auto n = numa_node_of_cpu(sched_getcpu()); + return n; +} + +#else // C10_ENABLE_NUMA + +bool IsNUMAEnabled() { + return false; +} + +void NUMABind(int numa_node_id) { + if (numa_node_id >= 0) { + VLOG(1) << "NUMA is not enabled"; + } +} + +int GetNUMANode(const void* ptr) { + VLOG(1) << "NUMA is not enabled"; + return -1; +} + +int GetNumNUMANodes() { + VLOG(1) << "NUMA is not enabled"; + return -1; +} + +void NUMAMove(void* ptr, size_t size, int numa_node_id) { + if (numa_node_id >= 0) { + VLOG(1) << "NUMA is not enabled"; + } +} + +int GetCurrentNUMANode() { + VLOG(1) << "NUMA is not enabled"; + return -1; +} + +#endif // C10_NUMA_ENABLED + +} // namespace c10 diff --git a/c10/util/numa.h b/c10/util/numa.h new file mode 100644 index 0000000000..aa5ae52332 --- /dev/null +++ b/c10/util/numa.h @@ -0,0 +1,40 @@ +#pragma once + +#include <c10/util/Logging.h> +#include <c10/util/Optional.h> + +C10_DECLARE_bool(caffe2_cpu_numa_enabled); + +namespace c10 { + +/** + * Check whether NUMA is enabled + */ +C10_API bool IsNUMAEnabled(); + +/** + * Bind to a given NUMA node + */ +C10_API void NUMABind(int numa_node_id); + +/** + * Get the NUMA id for a given pointer `ptr` + */ +C10_API int GetNUMANode(const void* ptr); + +/** + * Get number of NUMA nodes + */ +C10_API int GetNumNUMANodes(); + +/** + * Move the memory pointed to by `ptr` of a given size to another NUMA node + */ +C10_API void NUMAMove(void* ptr, size_t size, int numa_node_id); + +/** + * Get the current NUMA node id + */ +C10_API int GetCurrentNUMANode(); + +} // namespace c10 |