Skip to content

Commit 20e0751

Browse files
committed
Introduce UMF_MEMSPACE_HIGHEST_BANDWIDTH env var
This environment variable is used to forcefully assign NUMA nodes to the memspace "highest bandwidth". The ordering of memory targets within this memspace will correspond to the sequence of NUMA nodes specified in the environment variable.
1 parent 8a4d1bb commit 20e0751

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed

src/memspaces/memspace_highest_bandwidth.c

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include <assert.h>
11+
#include <ctype.h>
1112
#include <hwloc.h>
1213
#include <stdlib.h>
1314

@@ -16,22 +17,84 @@
1617
#include "memspace_internal.h"
1718
#include "memspace_numa.h"
1819
#include "topology.h"
20+
#include "utils_common.h"
1921
#include "utils_concurrency.h"
2022

23+
#define MAX_NODES 512
24+
25+
static bool is_number_str(const char *token) {
26+
if (*token == '\0') {
27+
return false;
28+
}
29+
30+
while (*token != '\0') {
31+
if (*token < '0' || *token > '9') {
32+
return false;
33+
}
34+
35+
token++;
36+
}
37+
38+
return true;
39+
}
40+
41+
static umf_result_t getenv_to_nodes_array(char *envStr, size_t *arr,
42+
size_t arrSize, size_t *outSize) {
43+
if (envStr == NULL || arr == NULL || arrSize == 0 || outSize == NULL) {
44+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
45+
}
46+
47+
char *value = getenv(envStr);
48+
if (!value) {
49+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
50+
}
51+
52+
size_t nNodes = 0;
53+
char *token = strtok(value, " ,");
54+
while (token != NULL) {
55+
if (!is_number_str(token)) {
56+
fprintf(stderr, "Error: Parsing env variable %s\n", envStr);
57+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
58+
}
59+
60+
if (arrSize > nNodes) {
61+
size_t node = (size_t)strtoul(token, NULL, 10);
62+
arr[nNodes] = node;
63+
}
64+
65+
nNodes++;
66+
token = strtok(NULL, " ,");
67+
}
68+
69+
*outSize = nNodes;
70+
71+
return UMF_RESULT_SUCCESS;
72+
}
73+
2174
static umf_result_t
2275
umfMemspaceHighestBandwidthCreate(umf_memspace_handle_t *hMemspace) {
2376
if (!hMemspace) {
2477
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
2578
}
2679

80+
// Check env var 'UMF_MEMSPACE_HIGHEST_BANDWIDTH' for the nodes assigned
81+
// by the user.
82+
size_t nodeIds[MAX_NODES];
83+
size_t nNodes = 0;
84+
umf_result_t ret = getenv_to_nodes_array("UMF_MEMSPACE_HIGHEST_BANDWIDTH",
85+
nodeIds, MAX_NODES, &nNodes);
86+
if (ret == UMF_RESULT_SUCCESS) {
87+
assert(nNodes > 0 && nNodes <= MAX_NODES);
88+
return umfMemspaceCreateFromNumaArray(nodeIds, nNodes, hMemspace);
89+
}
90+
2791
umf_memspace_handle_t hostAllMemspace = umfMemspaceHostAllGet();
2892
if (!hostAllMemspace) {
2993
return UMF_RESULT_ERROR_UNKNOWN;
3094
}
3195

3296
umf_memspace_handle_t highBandwidthMemspace = NULL;
33-
umf_result_t ret =
34-
umfMemspaceClone(hostAllMemspace, &highBandwidthMemspace);
97+
ret = umfMemspaceClone(hostAllMemspace, &highBandwidthMemspace);
3598
if (ret != UMF_RESULT_SUCCESS) {
3699
return ret;
37100
}

0 commit comments

Comments
 (0)