Skip to content

Commit c759919

Browse files
author
Damian Duy
committed
Add test for multiple NUMA nodes
1 parent 8064716 commit c759919

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

test/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ if(UMF_BUILD_OS_MEMORY_PROVIDER AND LINUX) # OS-specific functions are implement
103103
add_umf_test(NAME provider_os_memory
104104
SRCS provider_os_memory.cpp
105105
LIBS umf_utils)
106+
add_umf_test(NAME provider_os_memory_multiple_numa_nodes
107+
SRCS provider_os_memory_multiple_numa_nodes.cpp
108+
LIBS umf_utils numa)
106109
add_umf_test(NAME memspace_numa
107110
SRCS memspace_numa.cpp
108111
LIBS numa)
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright (C) 2024 Intel Corporation
2+
// Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
#include "base.hpp"
6+
7+
#include <numa.h>
8+
#include <numaif.h>
9+
10+
#include <umf/providers/provider_os_memory.h>
11+
12+
static umf_os_memory_provider_params_t UMF_OS_MEMORY_PROVIDER_PARAMS_TEST =
13+
umfOsMemoryProviderParamsDefault();
14+
15+
std::vector<int> get_available_numa_nodes_numbers() {
16+
if (numa_available() == -1 || numa_all_nodes_ptr == nullptr) {
17+
return {-1};
18+
}
19+
20+
std::vector<int> available_numa_nodes_numbers;
21+
// Get all available NUMA nodes numbers.
22+
for (size_t i = 0; i < (size_t)numa_max_node() + 1; ++i) {
23+
if (numa_bitmask_isbitset(numa_all_nodes_ptr, i) == 1) {
24+
available_numa_nodes_numbers.emplace_back(i);
25+
}
26+
}
27+
28+
return available_numa_nodes_numbers;
29+
}
30+
31+
struct testNumaNodes : public testing::TestWithParam<int> {
32+
void SetUp() override {
33+
if (numa_available() == -1) {
34+
GTEST_SKIP() << "Test skipped, NUMA not available";
35+
}
36+
if (numa_num_task_nodes() <= 1) {
37+
GTEST_SKIP()
38+
<< "Test skipped, the number of NUMA nodes is less than two";
39+
}
40+
41+
nodemask = numa_allocate_nodemask();
42+
ASSERT_NE(nodemask, nullptr);
43+
}
44+
45+
void
46+
initOsProvider(umf_os_memory_provider_params_t os_memory_provider_params) {
47+
umf_result_t umf_result;
48+
umf_result = umfMemoryProviderCreate(&UMF_OS_MEMORY_PROVIDER_OPS,
49+
&os_memory_provider_params,
50+
&os_memory_provider);
51+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
52+
ASSERT_NE(os_memory_provider, nullptr);
53+
}
54+
55+
int retrieve_numa_node_number(void *addr) {
56+
int numa_node;
57+
int ret = get_mempolicy(&numa_node, nullptr, 0, addr,
58+
MPOL_F_NODE | MPOL_F_ADDR);
59+
EXPECT_EQ(ret, 0);
60+
return numa_node;
61+
}
62+
63+
void TearDown() override {
64+
umf_result_t umf_result;
65+
if (ptr) {
66+
umf_result =
67+
umfMemoryProviderFree(os_memory_provider, ptr, alloc_size);
68+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
69+
}
70+
if (os_memory_provider) {
71+
umfMemoryProviderDestroy(os_memory_provider);
72+
}
73+
if (nodemask) {
74+
numa_bitmask_clearall(nodemask);
75+
numa_bitmask_free(nodemask);
76+
}
77+
}
78+
79+
size_t alloc_size = 1024;
80+
void *ptr = nullptr;
81+
bitmask *nodemask = nullptr;
82+
umf_memory_provider_handle_t os_memory_provider = nullptr;
83+
};
84+
85+
INSTANTIATE_TEST_SUITE_P(
86+
testNumaNodesAllocations, testNumaNodes,
87+
::testing::ValuesIn(get_available_numa_nodes_numbers()));
88+
89+
// Test for allocations on numa nodes. This test will be executed for all numa nodes
90+
// available on the system. The available nodes are returned in vector from the
91+
// get_available_numa_nodes_numbers() function and passed to test as parameters.
92+
TEST_P(testNumaNodes, checkNumaNodesAllocations) {
93+
int numa_node_number = GetParam();
94+
umf_os_memory_provider_params_t os_memory_provider_params =
95+
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
96+
os_memory_provider_params.maxnode = numa_node_number + 1;
97+
numa_bitmask_setbit(nodemask, numa_node_number);
98+
os_memory_provider_params.nodemask = nodemask->maskp;
99+
os_memory_provider_params.numa_mode = UMF_NUMA_MODE_BIND;
100+
initOsProvider(os_memory_provider_params);
101+
102+
umf_result_t umf_result;
103+
umf_result =
104+
umfMemoryProviderAlloc(os_memory_provider, alloc_size, 0, &ptr);
105+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
106+
ASSERT_NE(ptr, nullptr);
107+
108+
// This pointer must point to an initialized value before retrieving a number of
109+
// the numa node that the pointer was allocated on (calling get_mempolicy).
110+
memset(ptr, 0xFF, alloc_size);
111+
int retrieved_numa_node_number = retrieve_numa_node_number(ptr);
112+
ASSERT_EQ(retrieved_numa_node_number, numa_node_number);
113+
}

0 commit comments

Comments
 (0)