Skip to content

Commit 5abf457

Browse files
committed
change os memory provider numa config
instead of bitmap, user will input ordered list of numanodes. This is needed to support upcoming patches, needed for openmp 6.0 Signed-off-by: Łukasz Plewa <lukasz.plewa@intel.com>
1 parent f24134d commit 5abf457

File tree

10 files changed

+76
-115
lines changed

10 files changed

+76
-115
lines changed

include/umf/providers/provider_os_memory.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ typedef struct umf_os_memory_provider_params_t {
6363
unsigned protection;
6464

6565
// NUMA config
66-
/// Points to a bit mask of nodes containing up to maxnode bits, depending on
67-
/// selected numa_mode newly allocated memory will be bound to those nodes
68-
unsigned long *nodemask;
69-
/// Max number of bits in nodemask
70-
unsigned long maxnode;
71-
/// Describes how nodemask is interpreted
66+
/// ordered list of numa nodes
67+
unsigned *numa_list;
68+
/// length of numa_list
69+
unsigned numa_list_len;
70+
71+
/// Describes how node list is interpreted
7272
umf_numa_mode_t numa_mode;
7373
} umf_os_memory_provider_params_t;
7474

@@ -91,8 +91,8 @@ static inline umf_os_memory_provider_params_t
9191
umfOsMemoryProviderParamsDefault(void) {
9292
umf_os_memory_provider_params_t params = {
9393
UMF_PROTECTION_READ | UMF_PROTECTION_WRITE, /* protection */
94-
NULL, /* nodemask */
95-
0, /* maxnode */
94+
NULL, /* numa_list */
95+
0, /* numa_list_len */
9696
UMF_NUMA_MODE_DEFAULT, /* numa_mode */
9797
};
9898

src/memory_targets/memory_target_numa.c

Lines changed: 21 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "topology.h"
2222

2323
struct numa_memory_target_t {
24-
size_t physical_id;
24+
unsigned physical_id;
2525
};
2626

2727
static umf_result_t numa_initialize(void *params, void **memTarget) {
@@ -45,77 +45,15 @@ static umf_result_t numa_initialize(void *params, void **memTarget) {
4545

4646
static void numa_finalize(void *memTarget) { umf_ba_global_free(memTarget); }
4747

48-
// sets maxnode and allocates and initializes mask based on provided memory targets
49-
static umf_result_t
50-
numa_targets_create_nodemask(struct numa_memory_target_t **targets,
51-
size_t numTargets, unsigned long **mask,
52-
unsigned *maxnode, size_t *mask_size) {
53-
assert(targets);
54-
assert(mask);
55-
assert(maxnode);
56-
57-
hwloc_bitmap_t bitmap = hwloc_bitmap_alloc();
58-
if (!bitmap) {
59-
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
60-
}
61-
62-
for (size_t i = 0; i < numTargets; i++) {
63-
if (hwloc_bitmap_set(bitmap, targets[i]->physical_id)) {
64-
hwloc_bitmap_free(bitmap);
65-
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
66-
}
67-
}
68-
69-
int lastBit = hwloc_bitmap_last(bitmap);
70-
if (lastBit == -1) {
71-
// no node is set
72-
hwloc_bitmap_free(bitmap);
73-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
74-
}
75-
76-
*maxnode = lastBit + 1;
77-
78-
// Do not use hwloc_bitmap_nr_ulongs due to:
79-
// https://github.com/open-mpi/hwloc/issues/429
80-
unsigned bits_per_long = sizeof(unsigned long) * 8;
81-
int nrUlongs = (lastBit + bits_per_long) / bits_per_long;
82-
83-
*mask_size = sizeof(unsigned long) * nrUlongs;
84-
85-
unsigned long *nodemask = umf_ba_global_alloc(*mask_size);
86-
if (!nodemask) {
87-
hwloc_bitmap_free(bitmap);
88-
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
89-
}
90-
91-
int ret = hwloc_bitmap_to_ulongs(bitmap, nrUlongs, nodemask);
92-
hwloc_bitmap_free(bitmap);
93-
94-
if (ret) {
95-
umf_ba_global_free(nodemask);
96-
return UMF_RESULT_ERROR_UNKNOWN;
97-
}
98-
99-
*mask = nodemask;
100-
101-
return UMF_RESULT_SUCCESS;
102-
}
103-
104-
static enum umf_result_t numa_memory_provider_create_from_memspace(
48+
static umf_result_t numa_memory_provider_create_from_memspace(
10549
umf_memspace_handle_t memspace, void **memTargets, size_t numTargets,
10650
umf_memspace_policy_handle_t policy,
10751
umf_memory_provider_handle_t *provider) {
108-
(void)memspace;
109-
(void)numTargets;
11052
// TODO: apply policy
11153
(void)policy;
112-
11354
struct numa_memory_target_t **numaTargets =
11455
(struct numa_memory_target_t **)memTargets;
11556

116-
unsigned long *nodemask;
117-
unsigned maxnode;
118-
size_t nodemask_size;
11957
size_t numNodesProvider;
12058

12159
if (memspace == umfMemspaceHighestCapacityGet()) {
@@ -126,21 +64,31 @@ static enum umf_result_t numa_memory_provider_create_from_memspace(
12664
numNodesProvider = numTargets;
12765
}
12866

129-
umf_result_t ret = numa_targets_create_nodemask(
130-
numaTargets, numNodesProvider, &nodemask, &maxnode, &nodemask_size);
131-
if (ret != UMF_RESULT_SUCCESS) {
132-
return ret;
67+
if (numNodesProvider == 0) {
68+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
13369
}
13470

13571
umf_os_memory_provider_params_t params = umfOsMemoryProviderParamsDefault();
136-
params.nodemask = nodemask;
137-
params.maxnode = maxnode;
72+
params.numa_list =
73+
umf_ba_global_alloc(sizeof(*params.numa_list) * numNodesProvider);
74+
75+
if (!params.numa_list) {
76+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
77+
}
78+
79+
for (size_t i = 0; i < numNodesProvider; i++) {
80+
params.numa_list[i] = numaTargets[i]->physical_id;
81+
}
82+
83+
params.numa_list_len = numNodesProvider;
13884
params.numa_mode = UMF_NUMA_MODE_BIND;
13985

14086
umf_memory_provider_handle_t numaProvider = NULL;
141-
ret = umfMemoryProviderCreate(umfOsMemoryProviderOps(), &params,
142-
&numaProvider);
143-
umf_ba_global_free(nodemask);
87+
int ret = umfMemoryProviderCreate(umfOsMemoryProviderOps(), &params,
88+
&numaProvider);
89+
90+
umf_ba_global_free(params.numa_list);
91+
14492
if (ret) {
14593
return ret;
14694
}

src/memspaces/memspace_host_all.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static umf_result_t umfMemspaceHostAllCreate(umf_memspace_handle_t *hMemspace) {
4040
goto err;
4141
}
4242

43-
size_t *nodeIds = umf_ba_global_alloc(nNodes * sizeof(size_t));
43+
unsigned *nodeIds = umf_ba_global_alloc(nNodes * sizeof(*nodeIds));
4444
if (!nodeIds) {
4545
umf_ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
4646
goto err;

src/memspaces/memspace_numa.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "memspace_numa.h"
1616

1717
enum umf_result_t
18-
umfMemspaceCreateFromNumaArray(size_t *nodeIds, size_t numIds,
18+
umfMemspaceCreateFromNumaArray(unsigned *nodeIds, size_t numIds,
1919
umf_memspace_handle_t *hMemspace) {
2020
if (!nodeIds || numIds == 0 || !hMemspace) {
2121
return UMF_RESULT_ERROR_INVALID_ARGUMENT;

src/memspaces/memspace_numa.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2023 Intel Corporation
3+
* Copyright (C) 2023-2024 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -24,7 +24,7 @@ extern "C" {
2424
/// \param hMemspace [out] handle to the newly created memspace
2525
/// \return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
2626
///
27-
umf_result_t umfMemspaceCreateFromNumaArray(size_t *nodeIds, size_t numIds,
27+
umf_result_t umfMemspaceCreateFromNumaArray(unsigned *nodeIds, size_t numIds,
2828
umf_memspace_handle_t *hMemspace);
2929

3030
#ifdef __cplusplus

src/provider/provider_os_memory.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,29 +81,28 @@ static void os_store_last_native_error(int32_t native_error, int errno_value) {
8181
TLS_last_native_error.errno_value = errno_value;
8282
}
8383

84-
static umf_result_t nodemask_to_hwloc_nodeset(const unsigned long *nodemask,
85-
unsigned long maxnode,
84+
static umf_result_t nodemask_to_hwloc_nodeset(const unsigned *nodelist,
85+
unsigned long listsize,
8686
hwloc_bitmap_t *out_nodeset) {
8787
if (out_nodeset == NULL) {
8888
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
8989
}
9090

91-
if (maxnode > UINT_MAX) {
92-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
93-
}
94-
9591
*out_nodeset = hwloc_bitmap_alloc();
9692
if (!*out_nodeset) {
9793
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
9894
}
9995

100-
if (maxnode == 0 || nodemask == NULL) {
96+
if (listsize == 0) {
10197
return UMF_RESULT_SUCCESS;
10298
}
10399

104-
unsigned bits_per_mask = sizeof(unsigned long) * 8;
105-
hwloc_bitmap_from_ulongs(
106-
*out_nodeset, (maxnode + bits_per_mask - 1) / bits_per_mask, nodemask);
100+
for (unsigned long i = 0; i < listsize; i++) {
101+
if (hwloc_bitmap_set(*out_nodeset, nodelist[i])) {
102+
hwloc_bitmap_free(*out_nodeset);
103+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
104+
}
105+
}
107106

108107
return UMF_RESULT_SUCCESS;
109108
}
@@ -193,7 +192,7 @@ static umf_result_t translate_params(umf_os_memory_provider_params_t *in_params,
193192
}
194193

195194
// NUMA config
196-
int emptyNodeset = (!in_params->maxnode || !in_params->nodemask);
195+
int emptyNodeset = in_params->numa_list_len == 0;
197196
result = translate_numa_mode(in_params->numa_mode, emptyNodeset,
198197
&provider->numa_policy);
199198
if (result != UMF_RESULT_SUCCESS) {
@@ -203,8 +202,8 @@ static umf_result_t translate_params(umf_os_memory_provider_params_t *in_params,
203202

204203
provider->numa_flags = getHwlocMembindFlags(in_params->numa_mode);
205204

206-
return nodemask_to_hwloc_nodeset(in_params->nodemask, in_params->maxnode,
207-
&provider->nodeset);
205+
return nodemask_to_hwloc_nodeset(
206+
in_params->numa_list, in_params->numa_list_len, &provider->nodeset);
208207
}
209208

210209
static umf_result_t os_initialize(void *params, void **provider) {

test/memspaces/memspace_helpers.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct numaNodesTest : ::umf_test::test {
3636
}
3737
}
3838

39-
std::vector<size_t> nodeIds;
39+
std::vector<unsigned> nodeIds;
4040
unsigned long maxNodeId = 0;
4141
};
4242

test/provider_os_memory.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,16 @@ static void test_alloc_failure(umf_memory_provider_handle_t provider,
128128
// negative tests for umfMemoryProviderCreate()
129129

130130
static umf_result_t create_os_provider_with_mode(umf_numa_mode_t mode,
131-
unsigned long *nodemask,
132-
unsigned long maxnode) {
131+
unsigned *node_list,
132+
unsigned node_list_size) {
133133
umf_result_t umf_result;
134134
umf_memory_provider_handle_t os_memory_provider = nullptr;
135135
umf_os_memory_provider_params_t os_memory_provider_params =
136136
umfOsMemoryProviderParamsDefault();
137137

138138
os_memory_provider_params.numa_mode = mode;
139-
os_memory_provider_params.nodemask = nodemask;
140-
os_memory_provider_params.maxnode = maxnode;
139+
os_memory_provider_params.numa_list = node_list;
140+
os_memory_provider_params.numa_list_len = node_list_size;
141141

142142
umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(),
143143
&os_memory_provider_params,
@@ -152,18 +152,18 @@ static umf_result_t create_os_provider_with_mode(umf_numa_mode_t mode,
152152
return umf_result;
153153
}
154154

155-
static unsigned long valid_nodemask = 0x1;
156-
static unsigned long valid_maxnode = 2;
155+
static unsigned valid_list = 0x1;
156+
static unsigned long valid_list_len = 1;
157157

158158
TEST_F(test, create_WRONG_NUMA_MODE_DEFAULT) {
159-
auto ret = create_os_provider_with_mode(UMF_NUMA_MODE_DEFAULT,
160-
&valid_nodemask, valid_maxnode);
159+
auto ret = create_os_provider_with_mode(UMF_NUMA_MODE_DEFAULT, &valid_list,
160+
valid_list_len);
161161
ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);
162162
}
163163

164164
TEST_F(test, create_WRONG_NUMA_MODE_LOCAL) {
165-
auto ret = create_os_provider_with_mode(UMF_NUMA_MODE_LOCAL,
166-
&valid_nodemask, valid_maxnode);
165+
auto ret = create_os_provider_with_mode(UMF_NUMA_MODE_LOCAL, &valid_list,
166+
valid_list_len);
167167
ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);
168168
}
169169

test/provider_os_memory_config.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,18 @@ TEST_P(providerConfigTestNumaMode, numa_modes) {
155155
if (params.numa_mode != UMF_NUMA_MODE_DEFAULT &&
156156
params.numa_mode != UMF_NUMA_MODE_LOCAL) {
157157
allowed_nodes = numa_get_mems_allowed();
158-
params.nodemask = allowed_nodes->maskp;
159-
params.maxnode = allowed_nodes->size;
158+
// convert bitmask to array of nodes
159+
params.numa_list_len = numa_bitmask_weight(allowed_nodes);
160+
params.numa_list = (unsigned *)malloc(params.numa_list_len *
161+
sizeof(*params.numa_list));
162+
ASSERT_NE(params.numa_list, nullptr);
163+
unsigned count = 0;
164+
for (unsigned i = 0; i < params.numa_list_len; i++) {
165+
if (numa_bitmask_isbitset(allowed_nodes, i)) {
166+
params.numa_list[count++] = i;
167+
}
168+
}
169+
ASSERT_EQ(count, params.numa_list_len);
160170
}
161171

162172
create_provider(&params);
@@ -182,9 +192,10 @@ TEST_P(providerConfigTestNumaMode, numa_modes) {
182192
// MPOL_PREFERRED_* is equivalent to MPOL_LOCAL if no node is set
183193
if (actual_mode == MPOL_PREFERRED ||
184194
actual_mode == MPOL_PREFERRED_MANY) {
185-
ASSERT_EQ(params.maxnode, 0);
195+
ASSERT_EQ(params.numa_list_len, 0);
186196
} else {
187197
ASSERT_EQ(actual_mode, MPOL_LOCAL);
188198
}
189199
}
200+
free(params.numa_list);
190201
}

test/provider_os_memory_multiple_numa_nodes.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,15 @@ INSTANTIATE_TEST_SUITE_P(
8383
// available on the system. The available nodes are returned in vector from the
8484
// get_available_numa_nodes_numbers() function and passed to test as parameters.
8585
TEST_P(testNumaNodes, checkNumaNodesAllocations) {
86-
int numa_node_number = GetParam();
86+
int param = GetParam();
87+
ASSERT_GE(param, 0);
88+
unsigned numa_node_number = param;
8789
umf_os_memory_provider_params_t os_memory_provider_params =
8890
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
89-
os_memory_provider_params.maxnode = numa_node_number + 1;
91+
92+
os_memory_provider_params.numa_list = &numa_node_number;
9093
numa_bitmask_setbit(nodemask, numa_node_number);
91-
os_memory_provider_params.nodemask = nodemask->maskp;
94+
os_memory_provider_params.numa_list_len = 1;
9295
os_memory_provider_params.numa_mode = UMF_NUMA_MODE_BIND;
9396
initOsProvider(os_memory_provider_params);
9497

0 commit comments

Comments
 (0)