Skip to content

Commit 7df0dff

Browse files
authored
Merge pull request #437 from lplewa/numa_list
change os memory provider numa config
2 parents d06ed88 + 5abf457 commit 7df0dff

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)