Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions include/umf/memspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <umf/memory_pool.h>
#include <umf/memory_provider.h>
#include <umf/mempolicy.h>
#include <umf/memtarget.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -84,6 +85,21 @@ umf_const_memspace_handle_t umfMemspaceHighestBandwidthGet(void);
///
umf_const_memspace_handle_t umfMemspaceLowestLatencyGet(void);

/// \brief Returns number of memory targets in memspace.
/// \param hMemspace handle to memspace
/// \return number of memory targets in memspace
///
size_t umfMemspaceMemtargetNum(umf_const_memspace_handle_t hMemspace);

/// \brief Returns memory target by index.
/// \param hMemspace handle to memspace
/// \param targetNum index of the memory target
/// \return memory target handle on success or NULL on invalid input.
///
umf_const_memtarget_handle_t
umfMemspaceMemtargetGet(umf_const_memspace_handle_t hMemspace,
unsigned targetNum);

#ifdef __cplusplus
}
#endif
Expand Down
14 changes: 14 additions & 0 deletions include/umf/memtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,27 @@
#ifndef UMF_MEMTARGET_H
#define UMF_MEMTARGET_H 1

#include <umf/base.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct umf_memtarget_t *umf_memtarget_handle_t;
typedef const struct umf_memtarget_t *umf_const_memtarget_handle_t;

typedef enum umf_memtarget_type_t {
UMF_MEMTARGET_TYPE_UNKNOWN = 0,
UMF_MEMTARGET_TYPE_NUMA = 1,
} umf_memtarget_type_t;

/// \brief Gets the type of the memory target.
/// \param hMemtarget handle to the memory target
/// \param type [out] type of the memory target
/// \return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
umf_result_t umfMemtargetGetType(umf_const_memtarget_handle_t hMemtarget,
umf_memtarget_type_t *type);

#ifdef __cplusplus
}
#endif
Expand Down
9 changes: 9 additions & 0 deletions scripts/docs_config/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ Mempolicy
.. doxygenfile:: mempolicy.h
:sections: define enum typedef func

Memtarget
==========================================

TODO: Add general information about memtarges.

Memtarget
------------------------------------------
.. doxygenfile:: memtarget.h
:sections: define enum typedef func

Inter-Process Communication
==========================================
Expand Down
3 changes: 3 additions & 0 deletions src/libumf.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ EXPORTS
umfMempolicySetCustomSplitPartitions
umfMempolicySetInterleavePartSize
umfMemspaceDestroy
umfMemspaceMemtargetNum
umfMemspaceMemtargetGet
umfMemtargetGetType
umfOpenIPCHandle
umfOsMemoryProviderOps
umfPoolAlignedMalloc
Expand Down
3 changes: 3 additions & 0 deletions src/libumf.map
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ UMF_1.0 {
umfMempolicySetInterleavePartSize;
umfMemspaceCreateFromNumaArray;
umfMemspaceDestroy;
umfMemspaceMemtargetNum;
umfMemspaceMemtargetGet;
umfMemspaceHighestBandwidthGet;
umfMemspaceHighestCapacityGet;
umfMemspaceHostAllGet;
umfMemspaceLowestLatencyGet;
umfMemtargetGetType;
umfOpenIPCHandle;
umfOsMemoryProviderOps;
umfPoolAlignedMalloc;
Expand Down
16 changes: 16 additions & 0 deletions src/memspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,19 @@ umf_result_t umfMemspaceFilter(umf_const_memspace_handle_t hMemspace,
umf_ba_global_free(uniqueBestNodes);
return ret;
}

size_t umfMemspaceMemtargetNum(umf_const_memspace_handle_t hMemspace) {
if (!hMemspace) {
return 0;
}
return hMemspace->size;
}

umf_const_memtarget_handle_t
umfMemspaceMemtargetGet(umf_const_memspace_handle_t hMemspace,
unsigned targetNum) {
if (!hMemspace || targetNum >= hMemspace->size) {
return NULL;
}
return hMemspace->nodes[targetNum];
}
9 changes: 9 additions & 0 deletions src/memtarget.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,12 @@ umf_result_t umfMemtargetGetLatency(umf_memtarget_handle_t srcMemoryTarget,
return srcMemoryTarget->ops->get_latency(srcMemoryTarget->priv,
dstMemoryTarget->priv, latency);
}

umf_result_t umfMemtargetGetType(umf_const_memtarget_handle_t memoryTarget,
umf_memtarget_type_t *type) {
if (!memoryTarget || !type) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

return memoryTarget->ops->get_type(memoryTarget->priv, type);
}
2 changes: 2 additions & 0 deletions src/memtarget_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ typedef struct umf_memtarget_ops_t {
size_t *bandwidth);
umf_result_t (*get_latency)(void *srcMemoryTarget, void *dstMemoryTarget,
size_t *latency);

umf_result_t (*get_type)(void *memoryTarget, umf_memtarget_type_t *type);
} umf_memtarget_ops_t;

#ifdef __cplusplus
Expand Down
10 changes: 10 additions & 0 deletions src/memtargets/memtarget_numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,15 @@ static umf_result_t numa_get_latency(void *srcMemoryTarget,
return UMF_RESULT_SUCCESS;
}

static umf_result_t numa_get_type(void *memTarget, umf_memtarget_type_t *type) {
if (!memTarget || !type) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

*type = UMF_MEMTARGET_TYPE_NUMA;
return UMF_RESULT_SUCCESS;
}

struct umf_memtarget_ops_t UMF_MEMTARGET_NUMA_OPS = {
.version = UMF_VERSION_CURRENT,
.initialize = numa_initialize,
Expand All @@ -326,5 +335,6 @@ struct umf_memtarget_ops_t UMF_MEMTARGET_NUMA_OPS = {
.get_capacity = numa_get_capacity,
.get_bandwidth = numa_get_bandwidth,
.get_latency = numa_get_latency,
.get_type = numa_get_type,
.memory_provider_create_from_memspace =
numa_memory_provider_create_from_memspace};
4 changes: 4 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ if(LINUX) # OS-specific functions are implemented only for Linux now
NAME mempolicy
SRCS memspaces/mempolicy.cpp
LIBS ${LIBNUMA_LIBRARIES})
add_umf_test(
NAME memtarget
SRCS memspaces/memtarget.cpp
LIBS ${LIBNUMA_LIBRARIES})
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND UMF_BUILD_FUZZTESTS)
add_subdirectory(fuzz)
endif()
Expand Down
23 changes: 22 additions & 1 deletion test/memspaces/memspace_numa.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2023 Intel Corporation
// Copyright (C) 2023-2024 Intel Corporation
// Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

Expand All @@ -7,6 +7,7 @@
#include "memspace_helpers.hpp"
#include "memspace_internal.h"

#include <umf/memspace.h>
#include <umf/providers/provider_os_memory.h>

struct memspaceNumaTest : ::numaNodesTest {
Expand Down Expand Up @@ -56,6 +57,10 @@ TEST_F(numaNodesTest, createDestroy) {
nodeIds.data(), nodeIds.size(), &hMemspace);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
ASSERT_NE(hMemspace, nullptr);
EXPECT_EQ(umfMemspaceMemtargetNum(hMemspace), nodeIds.size());
for (size_t i = 0; i < umfMemspaceMemtargetNum(hMemspace); ++i) {
EXPECT_NE(umfMemspaceMemtargetGet(hMemspace, i), nullptr);
}

umfMemspaceDestroy(hMemspace);
}
Expand Down Expand Up @@ -91,6 +96,22 @@ TEST_F(memspaceNumaTest, providerFromNumaMemspace) {
umfMemoryProviderDestroy(hProvider);
}

TEST_F(numaNodesTest, memtargetsInvalid) {
umf_memspace_handle_t hMemspace = nullptr;
EXPECT_EQ(umfMemspaceMemtargetNum(nullptr), 0);
EXPECT_EQ(umfMemspaceMemtargetGet(nullptr, 0), nullptr);

umf_result_t ret = umfMemspaceCreateFromNumaArray(
nodeIds.data(), nodeIds.size(), &hMemspace);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
ASSERT_NE(hMemspace, nullptr);

ASSERT_EQ(umfMemspaceMemtargetNum(hMemspace), nodeIds.size());
EXPECT_EQ(umfMemspaceMemtargetGet(hMemspace, nodeIds.size()), nullptr);

umfMemspaceDestroy(hMemspace);
}

TEST_F(memspaceNumaProviderTest, allocFree) {
void *ptr = nullptr;
size_t size = SIZE_4K;
Expand Down
39 changes: 39 additions & 0 deletions test/memspaces/memtarget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2024 Intel Corporation
// Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "memspace_helpers.hpp"

#include <umf/base.h>
#include <umf/memspace.h>
#include <umf/memtarget.h>

using umf_test::test;

TEST_F(test, memTargetNuma) {
auto memspace = umfMemspaceHostAllGet();
ASSERT_NE(memspace, nullptr);

for (size_t i = 0; i < umfMemspaceMemtargetNum(memspace); i++) {
auto hTarget = umfMemspaceMemtargetGet(memspace, i);
ASSERT_NE(hTarget, nullptr);
umf_memtarget_type_t type;
auto ret = umfMemtargetGetType(hTarget, &type);
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
EXPECT_EQ(type, UMF_MEMTARGET_TYPE_NUMA);
}
}

TEST_F(test, memTargetInvalid) {
auto memspace = umfMemspaceHostAllGet();
ASSERT_NE(memspace, nullptr);
umf_memtarget_type_t type;
auto ret = umfMemtargetGetType(NULL, &type);
EXPECT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);
ret = umfMemtargetGetType(NULL, NULL);
EXPECT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);
auto hTarget = umfMemspaceMemtargetGet(memspace, 0);
ASSERT_NE(hTarget, nullptr);
ret = umfMemtargetGetType(hTarget, NULL);
EXPECT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);
}
Loading