-
Notifications
You must be signed in to change notification settings - Fork 35
Initial memspace and memory_target APIs #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c6a13e6
e946061
895d918
285e557
9c4e3da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* | ||
* Copyright (C) 2023 Intel Corporation | ||
* | ||
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
* | ||
*/ | ||
|
||
#ifndef UMF_MEMSPACE_H | ||
#define UMF_MEMSPACE_H 1 | ||
|
||
#include <umf/base.h> | ||
#include <umf/memory_pool.h> | ||
#include <umf/memory_provider.h> | ||
#include <umf/memspace_policy.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef struct umf_memspace_t *umf_memspace_handle_t; | ||
|
||
/// | ||
/// \brief Creates new memory pool from memspace and policy. | ||
/// \param hMemspace handle to memspace | ||
/// \param hPolicy handle to policy | ||
/// \param hPool [out] handle to the newly created memory pool | ||
/// \return UMF_RESULT_SUCCESS on success or appropriate error code on failure. | ||
/// | ||
umf_result_t umfPoolCreateFromMemspace(umf_memspace_handle_t hMemspace, | ||
umf_memspace_policy_handle_t hPolicy, | ||
umf_memory_pool_handle_t *hPool); | ||
|
||
/// | ||
/// \brief Creates new memory provider from memspace and policy. | ||
/// \param hMemspace handle to memspace | ||
/// \param hPolicy handle to policy | ||
/// \param hProvider [out] handle to the newly created memory provider | ||
/// \return UMF_RESULT_SUCCESS on success or appropriate error code on failure. | ||
/// | ||
umf_result_t | ||
umfMemoryProviderCreateFromMemspace(umf_memspace_handle_t hMemspace, | ||
umf_memspace_policy_handle_t hPolicy, | ||
umf_memory_provider_handle_t *hProvider); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* UMF_MEMSPACE_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* | ||
* Copyright (C) 2023 Intel Corporation | ||
* | ||
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
* | ||
*/ | ||
|
||
#ifndef UMF_MEMSPACE_POLICY_H | ||
#define UMF_MEMSPACE_POLICY_H 1 | ||
|
||
#include <umf/base.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef struct umf_memspace_policy_t *umf_memspace_policy_handle_t; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* UMF_MEMSPACE_POLICY_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* | ||
* Copyright (C) 2023 Intel Corporation | ||
* | ||
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
* | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <stdlib.h> | ||
|
||
#include "memory_target.h" | ||
#include "memory_target_ops.h" | ||
|
||
umf_result_t umfMemoryTargetCreate(const umf_memory_target_ops_t *ops, | ||
void *params, | ||
umf_memory_target_handle_t *memoryTarget) { | ||
if (!ops || !memoryTarget) { | ||
return UMF_RESULT_ERROR_INVALID_ARGUMENT; | ||
} | ||
|
||
umf_memory_target_handle_t target = | ||
(umf_memory_target_t *)malloc(sizeof(umf_memory_target_t)); | ||
if (!target) { | ||
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; | ||
} | ||
|
||
assert(ops->version == UMF_VERSION_CURRENT); | ||
|
||
target->ops = ops; | ||
|
||
void *target_priv; | ||
umf_result_t ret = ops->initialize(params, &target_priv); | ||
if (ret != UMF_RESULT_SUCCESS) { | ||
free(target); | ||
return ret; | ||
} | ||
|
||
target->priv = target_priv; | ||
|
||
*memoryTarget = target; | ||
|
||
return UMF_RESULT_SUCCESS; | ||
} | ||
|
||
void umfMemoryTargetDestroy(umf_memory_target_handle_t memoryTarget) { | ||
assert(memoryTarget); | ||
memoryTarget->ops->finalize(memoryTarget->priv); | ||
free(memoryTarget); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* | ||
* Copyright (C) 2023 Intel Corporation | ||
* | ||
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
* | ||
*/ | ||
|
||
#ifndef UMF_MEMORY_TARGET_H | ||
#define UMF_MEMORY_TARGET_H 1 | ||
|
||
#include <umf/base.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
struct umf_memory_target_ops_t; | ||
typedef struct umf_memory_target_ops_t umf_memory_target_ops_t; | ||
|
||
typedef struct umf_memory_target_t { | ||
const umf_memory_target_ops_t *ops; | ||
void *priv; | ||
} umf_memory_target_t; | ||
|
||
typedef umf_memory_target_t *umf_memory_target_handle_t; | ||
|
||
umf_result_t umfMemoryTargetCreate(const umf_memory_target_ops_t *ops, | ||
void *params, | ||
umf_memory_target_handle_t *memoryTarget); | ||
|
||
void umfMemoryTargetDestroy(umf_memory_target_handle_t memoryTarget); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* UMF_MEMORY_TARGET_H */ |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,46 @@ | ||||
/* | ||||
* | ||||
* Copyright (C) 2023 Intel Corporation | ||||
* | ||||
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. | ||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
* | ||||
*/ | ||||
|
||||
#ifndef UMF_MEMORY_TARGET_OPS_H | ||||
#define UMF_MEMORY_TARGET_OPS_H 1 | ||||
|
||||
#include <stdbool.h> | ||||
|
||||
#include <umf/base.h> | ||||
#include <umf/memspace.h> | ||||
|
||||
#ifdef __cplusplus | ||||
extern "C" { | ||||
#endif | ||||
|
||||
typedef struct umf_memory_target_t *umf_memory_target_handle_t; | ||||
|
||||
typedef struct umf_memory_target_ops_t { | ||||
/// Version of the ops structure. | ||||
/// Should be initialized using UMF_VERSION_CURRENT | ||||
uint32_t version; | ||||
|
||||
umf_result_t (*initialize)(void *params, void **memoryTarget); | ||||
void (*finalize)(void *memoryTarget); | ||||
|
||||
umf_result_t (*pool_create_from_memspace)( | ||||
umf_memspace_handle_t memspace, void **memoryTargets, size_t numTargets, | ||||
umf_memspace_policy_handle_t policy, umf_memory_pool_handle_t *pool); | ||||
|
||||
umf_result_t (*memory_provider_create_from_memspace)( | ||||
umf_memspace_handle_t memspace, void **memoryTargets, size_t numTargets, | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's why we only support memory targets of the same type for now. See here: unified-memory-framework/src/memspace.c Line 68 in 9c4e3da
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand that today we support only memory targets of the same type (same ops structure). My question is mostly about the architecture/design, not the current implementation. if we are creating pool/provider from memspace perhaps the current design is wrong and memspace should be responsible for pool/provider creation? In the future I can imagine memspace which consists of GPU memory target and numa memory target - in that case I expect that we will choose GPU memory provider (L0 or cuda) and create USM shared pool. What do you think? |
||||
umf_memspace_policy_handle_t policy, | ||||
umf_memory_provider_handle_t *provider); | ||||
} umf_memory_target_ops_t; | ||||
|
||||
#ifdef __cplusplus | ||||
} | ||||
#endif | ||||
|
||||
#endif /* #ifndef UMF_MEMORY_TARGET_OPS_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
* | ||
* Copyright (C) 2023 Intel Corporation | ||
* | ||
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
* | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <numa.h> | ||
#include <stdlib.h> | ||
|
||
#include "../memory_pool_internal.h" | ||
#include "memory_target_numa.h" | ||
#include <umf/pools/pool_disjoint.h> | ||
#include <umf/providers/provider_os_memory.h> | ||
|
||
struct numa_memory_target_t { | ||
size_t id; | ||
}; | ||
|
||
static umf_result_t numa_initialize(void *params, void **memTarget) { | ||
if (params == NULL || memTarget == NULL) { | ||
return UMF_RESULT_ERROR_INVALID_ARGUMENT; | ||
} | ||
|
||
struct umf_numa_memory_target_config_t *config = | ||
(struct umf_numa_memory_target_config_t *)params; | ||
|
||
struct numa_memory_target_t *numaTarget = | ||
malloc(sizeof(struct numa_memory_target_t)); | ||
if (!numaTarget) { | ||
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; | ||
} | ||
|
||
numaTarget->id = config->id; | ||
*memTarget = numaTarget; | ||
return UMF_RESULT_SUCCESS; | ||
} | ||
|
||
static void numa_finalize(void *memTarget) { free(memTarget); } | ||
|
||
static const umf_os_memory_provider_params_t | ||
UMF_OS_MEMORY_PROVIDER_PARAMS_DEFAULT = { | ||
// Visibility & protection | ||
.protection = UMF_PROTECTION_READ | UMF_PROTECTION_WRITE, | ||
.visibility = UMF_VISIBILITY_PRIVATE, | ||
|
||
// NUMA config | ||
.nodemask = NULL, | ||
.maxnode = 0, // TODO: numa_max_node/GetNumaHighestNodeNumber | ||
.numa_mode = UMF_NUMA_MODE_DEFAULT, | ||
.numa_flags = UMF_NUMA_FLAGS_STRICT, // TODO: determine default behavior | ||
|
||
// Logging | ||
.traces = 0, // TODO: parse env variable for log level? | ||
}; | ||
|
||
static size_t numa_targets_get_maxnode(struct numa_memory_target_t **targets, | ||
size_t numTargets) { | ||
size_t maxNode = 0; | ||
for (size_t i = 0; i < numTargets; i++) { | ||
maxNode = maxNode > targets[i]->id ? maxNode : targets[i]->id; | ||
} | ||
return maxNode; | ||
} | ||
|
||
static struct bitmask * | ||
numa_targets_create_nodemask(struct numa_memory_target_t **targets, | ||
size_t numTargets) { | ||
assert(targets); | ||
size_t maxNode = numa_targets_get_maxnode(targets, numTargets); | ||
struct bitmask *mask = numa_bitmask_alloc(maxNode + 1); | ||
if (!mask) { | ||
return NULL; | ||
} | ||
|
||
for (size_t i = 0; i < numTargets; i++) { | ||
numa_bitmask_setbit(mask, targets[i]->id); | ||
} | ||
|
||
return mask; | ||
} | ||
|
||
static enum umf_result_t numa_memory_provider_create_from_memspace( | ||
umf_memspace_handle_t memspace, void **memTargets, size_t numTargets, | ||
umf_memspace_policy_handle_t policy, | ||
umf_memory_provider_handle_t *provider) { | ||
(void)memspace; | ||
// TODO: apply policy | ||
(void)policy; | ||
|
||
struct numa_memory_target_t **numaTargets = | ||
(struct numa_memory_target_t **)memTargets; | ||
|
||
// Create node mask from IDs | ||
struct bitmask *nodemask = | ||
numa_targets_create_nodemask(numaTargets, numTargets); | ||
|
||
umf_os_memory_provider_params_t params = | ||
UMF_OS_MEMORY_PROVIDER_PARAMS_DEFAULT; | ||
params.nodemask = nodemask->maskp; | ||
params.maxnode = nodemask->size; | ||
|
||
umf_memory_provider_handle_t numaProvider = NULL; | ||
enum umf_result_t ret = umfMemoryProviderCreate(&UMF_OS_MEMORY_PROVIDER_OPS, | ||
¶ms, &numaProvider); | ||
numa_bitmask_free(nodemask); | ||
if (ret) { | ||
return ret; | ||
} | ||
|
||
*provider = numaProvider; | ||
|
||
return UMF_RESULT_SUCCESS; | ||
} | ||
|
||
static umf_result_t numa_pool_create_from_memspace( | ||
umf_memspace_handle_t memspace, void **memTargets, size_t numTargets, | ||
umf_memspace_policy_handle_t policy, umf_memory_pool_handle_t *pool) { | ||
(void)memspace; | ||
(void)memTargets; | ||
(void)numTargets; | ||
(void)policy; | ||
(void)pool; | ||
return UMF_RESULT_ERROR_NOT_SUPPORTED; | ||
} | ||
|
||
struct umf_memory_target_ops_t UMF_MEMORY_TARGET_NUMA_OPS = { | ||
.version = UMF_VERSION_CURRENT, | ||
.initialize = numa_initialize, | ||
.finalize = numa_finalize, | ||
.pool_create_from_memspace = numa_pool_create_from_memspace, | ||
.memory_provider_create_from_memspace = | ||
numa_memory_provider_create_from_memspace}; |
Uh oh!
There was an error while loading. Please reload this page.