summaryrefslogtreecommitdiff
path: root/c10
diff options
context:
space:
mode:
authorJerry Zhang <jerryzh@fb.com>2018-12-12 12:06:09 -0800
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>2018-12-12 12:21:10 -0800
commit63e77ab6c46774e4c42c00f74ed2f83c71c6e6bd (patch)
treeadcdb9d060572dbbca19684a461550f5e361be80 /c10
parentb34ab435efd9b4d839171d27bd6a0f321178d46b (diff)
downloadpytorch-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.txt16
-rw-r--r--c10/macros/cmake_macros.h.in1
-rw-r--r--c10/util/numa.cpp143
-rw-r--r--c10/util/numa.h40
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