Skip to content

Commit 87f9cdc

Browse files
authored
Merge pull request #694 from lplewa/add-remove-new
add umfMemspace[New|TargetRemove|TargetAdd]
2 parents 2334fd8 + b9f5778 commit 87f9cdc

File tree

13 files changed

+604
-55
lines changed

13 files changed

+604
-55
lines changed

include/umf/memspace.h

Lines changed: 32 additions & 1 deletion
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
@@ -85,6 +85,12 @@ umf_const_memspace_handle_t umfMemspaceHighestBandwidthGet(void);
8585
///
8686
umf_const_memspace_handle_t umfMemspaceLowestLatencyGet(void);
8787

88+
/// \brief Creates new empty memspace, which can be populated with umfMemspaceMemtargetAdd()
89+
/// \param hMemspace [out] handle to the newly created memspace
90+
/// \return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
91+
///
92+
umf_result_t umfMemspaceNew(umf_memspace_handle_t *hMemspace);
93+
8894
/// \brief Returns number of memory targets in memspace.
8995
/// \param hMemspace handle to memspace
9096
/// \return number of memory targets in memspace
@@ -100,6 +106,31 @@ umf_const_memtarget_handle_t
100106
umfMemspaceMemtargetGet(umf_const_memspace_handle_t hMemspace,
101107
unsigned targetNum);
102108

109+
/// \brief Adds memory target to memspace.
110+
///
111+
/// \details
112+
/// This function duplicates the memory target and then adds it to the memspace.
113+
/// This means that original memtarget handle and the handle of the duplicated memtarget are different
114+
/// and you cannot use it interchangeably.
115+
/// You can use `umfMemspaceMemtargetGet()` to retrieve new handle.
116+
///
117+
/// \param hMemspace handle to memspace
118+
/// \param hMemtarget handle to memory target
119+
/// \return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
120+
///
121+
umf_result_t umfMemspaceMemtargetAdd(umf_memspace_handle_t hMemspace,
122+
umf_const_memtarget_handle_t hMemtarget);
123+
124+
/// \brief Removes memory target from memspace.
125+
///
126+
/// \param hMemspace handle to memspace
127+
/// \param hMemtarget handle to memory target
128+
/// \return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
129+
///
130+
umf_result_t
131+
umfMemspaceMemtargetRemove(umf_memspace_handle_t hMemspace,
132+
umf_const_memtarget_handle_t hMemtarget);
133+
103134
#ifdef __cplusplus
104135
}
105136
#endif

src/libumf.def.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,13 @@ EXPORTS
4040
umfMempolicyDestroy
4141
umfMempolicySetCustomSplitPartitions
4242
umfMempolicySetInterleavePartSize
43+
umfMemspaceNew
4344
umfMemspaceDestroy
4445
umfMemspaceMemtargetNum
4546
umfMemspaceMemtargetGet
4647
umfMemtargetGetCapacity
48+
umfMemspaceMemtargetAdd
49+
umfMemspaceMemtargetRemove
4750
umfMemtargetGetType
4851
umfOpenIPCHandle
4952
umfPoolAlignedMalloc

src/libumf.map.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ UMF_1.0 {
3434
umfMempolicyDestroy;
3535
umfMempolicySetCustomSplitPartitions;
3636
umfMempolicySetInterleavePartSize;
37+
umfMemspaceNew;
38+
umfMemspaceCreateFromNumaArray;
3739
umfMemspaceDestroy;
40+
umfMemspaceMemtargetAdd;
41+
umfMemspaceMemtargetRemove;
3842
umfMemspaceMemtargetNum;
3943
umfMemspaceMemtargetGet;
4044
umfMemtargetGetCapacity;

src/memspace.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "memspace_internal.h"
1717
#include "memtarget_internal.h"
1818
#include "memtarget_ops.h"
19+
#include "utils_log.h"
1920

2021
#ifndef NDEBUG
2122
static umf_result_t
@@ -60,6 +61,10 @@ umf_result_t umfPoolCreateFromMemspace(umf_const_memspace_handle_t memspace,
6061
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
6162
}
6263

64+
if (memspace->size == 0) {
65+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
66+
}
67+
6368
void **privs = NULL;
6469
umf_result_t ret = memoryTargetHandlesToPriv(memspace, &privs);
6570
if (ret != UMF_RESULT_SUCCESS) {
@@ -85,6 +90,10 @@ umfMemoryProviderCreateFromMemspace(umf_const_memspace_handle_t memspace,
8590
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
8691
}
8792

93+
if (memspace->size == 0) {
94+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
95+
}
96+
8897
void **privs = NULL;
8998
umf_result_t ret = memoryTargetHandlesToPriv(memspace, &privs);
9099
if (ret != UMF_RESULT_SUCCESS) {
@@ -102,6 +111,25 @@ umfMemoryProviderCreateFromMemspace(umf_const_memspace_handle_t memspace,
102111
return ret;
103112
}
104113

114+
umf_result_t umfMemspaceNew(umf_memspace_handle_t *hMemspace) {
115+
if (!hMemspace) {
116+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
117+
}
118+
119+
umf_memspace_handle_t memspace =
120+
umf_ba_global_alloc(sizeof(struct umf_memspace_t));
121+
if (!memspace) {
122+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
123+
}
124+
125+
memspace->size = 0;
126+
memspace->nodes = NULL;
127+
128+
*hMemspace = memspace;
129+
130+
return UMF_RESULT_SUCCESS;
131+
}
132+
105133
void umfMemspaceDestroy(umf_memspace_handle_t memspace) {
106134
assert(memspace);
107135
for (size_t i = 0; i < memspace->size; i++) {
@@ -306,3 +334,95 @@ umfMemspaceMemtargetGet(umf_const_memspace_handle_t hMemspace,
306334
}
307335
return hMemspace->nodes[targetNum];
308336
}
337+
338+
umf_result_t umfMemspaceMemtargetAdd(umf_memspace_handle_t hMemspace,
339+
umf_const_memtarget_handle_t hMemtarget) {
340+
if (!hMemspace || !hMemtarget) {
341+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
342+
}
343+
344+
for (size_t i = 0; i < hMemspace->size; i++) {
345+
int cmp;
346+
umf_result_t ret =
347+
umfMemtargetCompare(hMemspace->nodes[i], hMemtarget, &cmp);
348+
if (ret != UMF_RESULT_SUCCESS) {
349+
return ret;
350+
}
351+
352+
if (cmp == 0) {
353+
LOG_ERR("Memory target already exists in the memspace");
354+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
355+
} else if (cmp < 0) {
356+
LOG_ERR("You can't mix different memory target types in the same "
357+
"memspace");
358+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
359+
}
360+
}
361+
362+
umf_memtarget_handle_t *newNodes =
363+
umf_ba_global_alloc(sizeof(*newNodes) * (hMemspace->size + 1));
364+
if (!newNodes) {
365+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
366+
}
367+
368+
for (size_t i = 0; i < hMemspace->size; i++) {
369+
newNodes[i] = hMemspace->nodes[i];
370+
}
371+
umf_memtarget_t *hMemtargetClone;
372+
373+
umf_result_t ret = umfMemtargetClone(hMemtarget, &hMemtargetClone);
374+
if (ret != UMF_RESULT_SUCCESS) {
375+
umf_ba_global_free(newNodes);
376+
return ret;
377+
}
378+
newNodes[hMemspace->size++] = hMemtargetClone;
379+
380+
umf_ba_global_free(hMemspace->nodes);
381+
hMemspace->nodes = newNodes;
382+
return UMF_RESULT_SUCCESS;
383+
}
384+
385+
umf_result_t
386+
umfMemspaceMemtargetRemove(umf_memspace_handle_t hMemspace,
387+
umf_const_memtarget_handle_t hMemtarget) {
388+
if (!hMemspace || !hMemtarget) {
389+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
390+
}
391+
unsigned i;
392+
for (i = 0; i < hMemspace->size; i++) {
393+
int cmp;
394+
umf_result_t ret =
395+
umfMemtargetCompare(hMemspace->nodes[i], hMemtarget, &cmp);
396+
397+
if (ret != UMF_RESULT_SUCCESS) {
398+
return ret;
399+
}
400+
401+
if (cmp == 0) {
402+
break;
403+
}
404+
}
405+
406+
if (i == hMemspace->size) {
407+
LOG_ERR("Memory target not found in the memspace");
408+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
409+
}
410+
411+
umf_memtarget_handle_t *newNodes =
412+
umf_ba_global_alloc(sizeof(*newNodes) * (hMemspace->size - 1));
413+
if (!newNodes) {
414+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
415+
}
416+
417+
for (unsigned j = 0, z = 0; j < hMemspace->size; j++) {
418+
if (j != i) {
419+
newNodes[z++] = hMemspace->nodes[j];
420+
}
421+
}
422+
423+
umfMemtargetDestroy(hMemspace->nodes[i]);
424+
umf_ba_global_free(hMemspace->nodes);
425+
hMemspace->nodes = newNodes;
426+
hMemspace->size--;
427+
return UMF_RESULT_SUCCESS;
428+
}

src/memtarget.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void umfMemtargetDestroy(umf_memtarget_handle_t memoryTarget) {
5353
umf_ba_global_free(memoryTarget);
5454
}
5555

56-
umf_result_t umfMemtargetClone(umf_memtarget_handle_t memoryTarget,
56+
umf_result_t umfMemtargetClone(umf_const_memtarget_handle_t memoryTarget,
5757
umf_memtarget_handle_t *outHandle) {
5858
assert(memoryTarget);
5959
assert(outHandle);
@@ -115,3 +115,33 @@ umf_result_t umfMemtargetGetType(umf_const_memtarget_handle_t memoryTarget,
115115

116116
return memoryTarget->ops->get_type(memoryTarget->priv, type);
117117
}
118+
119+
umf_result_t umfMemtargetCompare(umf_const_memtarget_handle_t a,
120+
umf_const_memtarget_handle_t b, int *result) {
121+
umf_memtarget_type_t typeA, typeB;
122+
umf_result_t ret = umfMemtargetGetType(a, &typeA);
123+
if (ret != UMF_RESULT_SUCCESS) {
124+
return ret;
125+
}
126+
127+
ret = umfMemtargetGetType(b, &typeB);
128+
if (ret != UMF_RESULT_SUCCESS) {
129+
return ret;
130+
}
131+
132+
if (typeA != typeB) {
133+
*result = -1;
134+
return UMF_RESULT_SUCCESS;
135+
}
136+
137+
ret = a->ops->compare(a->priv, b->priv, result);
138+
if (ret != UMF_RESULT_SUCCESS) {
139+
return ret;
140+
}
141+
142+
if (*result) {
143+
*result = 1;
144+
}
145+
146+
return UMF_RESULT_SUCCESS;
147+
}

src/memtarget_internal.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ umf_result_t umfMemtargetCreate(const umf_memtarget_ops_t *ops, void *params,
2828
umf_memtarget_handle_t *memoryTarget);
2929
void umfMemtargetDestroy(umf_memtarget_handle_t memoryTarget);
3030

31-
umf_result_t umfMemtargetClone(umf_memtarget_handle_t memoryTarget,
31+
umf_result_t umfMemtargetClone(umf_const_memtarget_handle_t memoryTarget,
3232
umf_memtarget_handle_t *outHandle);
3333

3434
umf_result_t umfMemtargetGetBandwidth(umf_memtarget_handle_t srcMemoryTarget,
@@ -38,6 +38,10 @@ umf_result_t umfMemtargetGetLatency(umf_memtarget_handle_t srcMemoryTarget,
3838
umf_memtarget_handle_t dstMemoryTarget,
3939
size_t *latency);
4040

41+
/// return 0 if memtargets are equal, -1 if they are of different types,
42+
/// and 1 if they are different targets of the same type
43+
umf_result_t umfMemtargetCompare(umf_const_memtarget_handle_t a,
44+
umf_const_memtarget_handle_t b, int *result);
4145
#ifdef __cplusplus
4246
}
4347
#endif

src/memtarget_ops.h

Lines changed: 3 additions & 1 deletion
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
@@ -45,6 +45,8 @@ typedef struct umf_memtarget_ops_t {
4545
size_t *latency);
4646

4747
umf_result_t (*get_type)(void *memoryTarget, umf_memtarget_type_t *type);
48+
umf_result_t (*compare)(void *memTarget, void *otherMemTarget, int *result);
49+
4850
} umf_memtarget_ops_t;
4951

5052
#ifdef __cplusplus

src/memtargets/memtarget_numa.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,20 @@ static umf_result_t numa_get_type(void *memTarget, umf_memtarget_type_t *type) {
326326
return UMF_RESULT_SUCCESS;
327327
}
328328

329+
static umf_result_t numa_compare(void *memTarget, void *otherMemTarget,
330+
int *result) {
331+
if (!memTarget || !otherMemTarget || !result) {
332+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
333+
}
334+
335+
struct numa_memtarget_t *numaTarget = (struct numa_memtarget_t *)memTarget;
336+
struct numa_memtarget_t *otherNumaTarget =
337+
(struct numa_memtarget_t *)otherMemTarget;
338+
339+
*result = numaTarget->physical_id != otherNumaTarget->physical_id;
340+
return UMF_RESULT_SUCCESS;
341+
}
342+
329343
struct umf_memtarget_ops_t UMF_MEMTARGET_NUMA_OPS = {
330344
.version = UMF_VERSION_CURRENT,
331345
.initialize = numa_initialize,
@@ -336,5 +350,6 @@ struct umf_memtarget_ops_t UMF_MEMTARGET_NUMA_OPS = {
336350
.get_bandwidth = numa_get_bandwidth,
337351
.get_latency = numa_get_latency,
338352
.get_type = numa_get_type,
353+
.compare = numa_compare,
339354
.memory_provider_create_from_memspace =
340355
numa_memory_provider_create_from_memspace};

test/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ if(LINUX AND (NOT UMF_DISABLE_HWLOC)) # OS-specific functions are implemented
224224
NAME mempolicy
225225
SRCS memspaces/mempolicy.cpp
226226
LIBS ${LIBNUMA_LIBRARIES})
227+
add_umf_test(
228+
NAME memspace
229+
SRCS memspaces/memspace.cpp
230+
LIBS ${LIBNUMA_LIBRARIES})
227231
add_umf_test(
228232
NAME memtarget
229233
SRCS memspaces/memtarget.cpp

0 commit comments

Comments
 (0)