diff --git a/include/umf/memspace.h b/include/umf/memspace.h index 2d2d77728..10cf0417d 100644 --- a/include/umf/memspace.h +++ b/include/umf/memspace.h @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -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 diff --git a/src/libumf.def.in b/src/libumf.def.in index 8ee99e024..f62f4f6dc 100644 --- a/src/libumf.def.in +++ b/src/libumf.def.in @@ -41,6 +41,8 @@ EXPORTS umfMempolicySetCustomSplitPartitions umfMempolicySetInterleavePartSize umfMemspaceDestroy + umfMemspaceMemtargetNum + umfMemspaceMemtargetGet umfOpenIPCHandle umfOsMemoryProviderOps umfPoolAlignedMalloc diff --git a/src/libumf.map b/src/libumf.map index cb09cdb94..4f4df92ce 100644 --- a/src/libumf.map +++ b/src/libumf.map @@ -37,6 +37,8 @@ UMF_1.0 { umfMempolicySetInterleavePartSize; umfMemspaceCreateFromNumaArray; umfMemspaceDestroy; + umfMemspaceMemtargetNum; + umfMemspaceMemtargetGet; umfMemspaceHighestBandwidthGet; umfMemspaceHighestCapacityGet; umfMemspaceHostAllGet; diff --git a/src/memspace.c b/src/memspace.c index 0dfbfeae3..01e20e617 100644 --- a/src/memspace.c +++ b/src/memspace.c @@ -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]; +} diff --git a/test/memspaces/memspace_numa.cpp b/test/memspaces/memspace_numa.cpp index b50eceac9..c8485fadc 100644 --- a/test/memspaces/memspace_numa.cpp +++ b/test/memspaces/memspace_numa.cpp @@ -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 @@ -7,6 +7,7 @@ #include "memspace_helpers.hpp" #include "memspace_internal.h" +#include #include struct memspaceNumaTest : ::numaNodesTest { @@ -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); } @@ -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;