Skip to content

Commit f072150

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

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-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: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
std::tuple<int, int> retrieve_numa_node_number(void *addr) {
32+
int numa_node;
33+
int ret =
34+
get_mempolicy(&numa_node, nullptr, 0, addr, MPOL_F_NODE | MPOL_F_ADDR);
35+
36+
return {ret, numa_node};
37+
}
38+
39+
struct testNumaNodes : public testing::TestWithParam<int> {
40+
void SetUp() override {
41+
if (numa_available() == -1 || numa_num_task_nodes() <= 1) {
42+
GTEST_SKIP();
43+
}
44+
45+
nodemask = numa_allocate_nodemask();
46+
ASSERT_NE(nodemask, nullptr);
47+
}
48+
49+
void
50+
initOsProvider(umf_os_memory_provider_params_t os_memory_provider_params) {
51+
umf_result_t umf_result;
52+
umf_result = umfMemoryProviderCreate(&UMF_OS_MEMORY_PROVIDER_OPS,
53+
&os_memory_provider_params,
54+
&os_memory_provider);
55+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
56+
ASSERT_NE(os_memory_provider, nullptr);
57+
}
58+
59+
void clear() {
60+
umf_result_t umf_result;
61+
memset(ptr, 0xFF, alloc_size);
62+
umf_result = umfMemoryProviderFree(os_memory_provider, ptr, alloc_size);
63+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
64+
umfMemoryProviderDestroy(os_memory_provider);
65+
66+
numa_bitmask_clearall(nodemask);
67+
numa_bitmask_free(nodemask);
68+
nodemask = nullptr;
69+
}
70+
71+
size_t alloc_size = 1024;
72+
void *ptr;
73+
bitmask *nodemask;
74+
umf_memory_provider_handle_t os_memory_provider;
75+
};
76+
77+
INSTANTIATE_TEST_SUITE_P(
78+
testNumaNodesAllocations, testNumaNodes,
79+
::testing::ValuesIn(get_available_numa_nodes_numbers()));
80+
81+
// Test for allocations on numa nodes. This test will be executed for all numa nodes
82+
// available on the system. The available nodes are returned in vector from the
83+
// get_available_numa_nodes_numbers() function and passed to test as parameters.
84+
TEST_P(testNumaNodes, checkNumaNodesAllocations) {
85+
int numa_node_number = GetParam();
86+
umf_os_memory_provider_params_t os_memory_provider_params =
87+
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
88+
os_memory_provider_params.maxnode = sizeof(unsigned long);
89+
numa_bitmask_setbit(nodemask, numa_node_number);
90+
os_memory_provider_params.nodemask = nodemask->maskp;
91+
os_memory_provider_params.numa_mode = UMF_NUMA_MODE_BIND;
92+
initOsProvider(os_memory_provider_params);
93+
94+
umf_result_t umf_result;
95+
umf_result =
96+
umfMemoryProviderAlloc(os_memory_provider, alloc_size, 0, &ptr);
97+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
98+
ASSERT_NE(ptr, nullptr);
99+
100+
// This pointer must point to an initialized value before retrieving a number of
101+
// the numa node that the pointer was allocated on (calling get_mempolicy).
102+
*((char *)ptr) = 0;
103+
auto [ret, retrieved_numa_node_number] = retrieve_numa_node_number(ptr);
104+
ASSERT_EQ(ret, 0);
105+
ASSERT_EQ(retrieved_numa_node_number, numa_node_number);
106+
107+
clear();
108+
}

0 commit comments

Comments
 (0)