Skip to content
Draft
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
76 changes: 1 addition & 75 deletions .github/workflows/pr_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,82 +19,8 @@ permissions:
jobs:
CodeChecks:
uses: ./.github/workflows/reusable_checks.yml
FastBuild:
name: Fast builds
needs: [CodeChecks]
uses: ./.github/workflows/reusable_fast.yml
Build:
name: Basic builds
needs: [FastBuild]
uses: ./.github/workflows/reusable_basic.yml
DevDax:
needs: [FastBuild]
uses: ./.github/workflows/reusable_dax.yml
MultiNuma:
needs: [FastBuild]
uses: ./.github/workflows/reusable_multi_numa.yml
L0:
needs: [Build]
uses: ./.github/workflows/reusable_gpu.yml
with:
provider: "LEVEL_ZERO"
runner: "L0"
shared_lib: "['ON']"
L0-BMG:
needs: [Build]
uses: ./.github/workflows/reusable_gpu.yml
with:
provider: "LEVEL_ZERO"
runner: "L0-BMG"
shared_lib: "['ON']"
CUDA:
needs: [Build]
uses: ./.github/workflows/reusable_gpu.yml
with:
provider: "CUDA"
runner: "CUDA"
shared_lib: "['ON']"
Sanitizers:
needs: [FastBuild]
uses: ./.github/workflows/reusable_sanitizers.yml
QEMU:
needs: [FastBuild]
uses: ./.github/workflows/reusable_qemu.yml
with:
short_run: true
ProxyLib:
needs: [Build]
uses: ./.github/workflows/reusable_proxy_lib.yml
Valgrind:
needs: [Build]
uses: ./.github/workflows/reusable_valgrind.yml
Coverage:
# total coverage (on upstream only)
if: github.repository == 'oneapi-src/unified-memory-framework'
needs: [Build, DevDax, L0, CUDA, MultiNuma, QEMU, ProxyLib]
uses: ./.github/workflows/reusable_coverage.yml
secrets: inherit
with:
trigger: "${{github.event_name}}"
Coverage_partial:
# partial coverage (on forks)
if: github.repository != 'oneapi-src/unified-memory-framework'
needs: [Build, QEMU, ProxyLib]
uses: ./.github/workflows/reusable_coverage.yml
CodeQL:
needs: [Build]
permissions:
contents: read
security-events: write
uses: ./.github/workflows/reusable_codeql.yml
Trivy:
needs: [Build]
permissions:
contents: read
security-events: write
uses: ./.github/workflows/reusable_trivy.yml
Compatibility:
needs: [Build]
#needs: [Build]
uses: ./.github/workflows/reusable_compatibility.yml
strategy:
matrix:
Expand Down
15 changes: 12 additions & 3 deletions .github/workflows/reusable_compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ jobs:
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
run: |
ctest --verbose -E "test_memoryProvider|test_disjoint_pool"
ctest --verbose -E "test_memoryProvider|test_disjoint_pool|test_provider_tracking_fixture_tests"

- name: Run disabled tests individually with latest UMF libs (warnings enabled)
working-directory: ${{github.workspace}}/tag_version/build
Expand All @@ -112,6 +112,9 @@ jobs:
run: |
test/test_memoryProvider --gtest_filter="-*Trace"
test/test_disjoint_pool --gtest_filter="-test.internals"
if [[ -x test/test_provider_tracking_fixture_tests ]]; then
test/test_provider_tracking_fixture_tests --gtest_filter="-*memoryTracking*"
fi

# Browse all folders in the examples directory, build them using the
# latest UMF version, and run them, excluding those in the exclude list.
Expand Down Expand Up @@ -245,10 +248,13 @@ jobs:
run: |
$env:UMF_LOG="level:warning;flush:debug;output:stderr;pid:no"
cp ${{github.workspace}}/latest_version/build/bin/Debug/umf.dll ${{github.workspace}}/tag_version/build/bin/Debug/umf.dll
ctest -C Debug --verbose -E "test_memoryProvider|test_disjoint_pool"
ctest -C Debug --verbose -E "test_memoryProvider|test_disjoint_pool|test_provider_tracking_fixture_tests"
$env:Path = "${{github.workspace}}/tag_version/build/bin/Debug;${{env.VCPKG_BIN_PATH}};$env:Path"
test/Debug/test_memoryProvider.exe --gtest_filter="-*Trace"
test/Debug/test_disjoint_pool.exe --gtest_filter="-test.internals"
if (Test-Path test/Debug/test_provider_tracking_fixture_tests.exe) {
test/Debug/test_provider_tracking_fixture_tests.exe --gtest_filter="-*memoryTracking*"
}

# Browse all folders in the examples directory, build them using the
# latest UMF version, and run them, excluding those in the exclude list.
Expand Down Expand Up @@ -390,7 +396,7 @@ jobs:
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
run: |
ctest --verbose -E "test_memoryProvider|test_disjoint_pool|test_provider_level_zero|test_provider_level_zero_dlopen_global|test_provider_level_zero_dlopen_local"
ctest --verbose -E "test_memoryProvider|test_disjoint_pool|test_provider_tracking_fixture_tests|test_provider_level_zero|test_provider_level_zero_dlopen_global|test_provider_level_zero_dlopen_local"

- name: Run disabled tests individually with latest UMF libs (warnings enabled)
working-directory: ${{github.workspace}}/tag_version/build
Expand All @@ -401,6 +407,9 @@ jobs:
run: |
test/test_memoryProvider --gtest_filter="-*Trace"
test/test_disjoint_pool --gtest_filter="-test.internals"
if [[ -x test/test_provider_tracking_fixture_tests ]]; then
test/test_provider_tracking_fixture_tests --gtest_filter="-*memoryTracking*"
fi
if [[ "$MATRIX_PROVIDER" == "LEVEL_ZERO" ]]; then
test/test_provider_level_zero --gtest_filter="-*allocInvalidSize/2"
test/test_provider_level_zero_dlopen_global --gtest_filter="-*allocInvalidSize/2"
Expand Down
39 changes: 38 additions & 1 deletion docs/config/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,44 @@ Custom memory provider
You can find the full examples code in the `examples/custom_file_provider/custom_file_provider.c`_ file
in the UMF repository.

TODO
Custom providers using operations version 1.3 or newer should implement the
``get_address_space`` callback. The callback returns the process-local address
space used by every allocation from that provider. UMF uses this information
to distinguish allocations that have the same numerical pointer value but
belong to different memory domains.

The ``namespace_token`` field is NULL for the host address space. For other
address spaces, UMF compares tokens by pointer value and never dereferences
them. Use the same stable token for providers whose pointers share an
address-space namespace, and different tokens for independent namespaces. The
token must remain at a stable address for as long as any provider using it
exists. Other implementations can use the address of a private static object,
for example::

static const char CUSTOM_ADDRESS_SPACE_NAMESPACE;

static umf_result_t custom_get_address_space(
void *provider,
umf_memory_provider_address_space_t *address_space) {
custom_provider_t *custom = provider;

address_space->namespace_token = &CUSTOM_ADDRESS_SPACE_NAMESPACE;
address_space->context = (uintptr_t)custom->context;
address_space->device = (uintptr_t)custom->device;
return UMF_RESULT_SUCCESS;
}

static umf_memory_provider_ops_t custom_ops = {
.version = UMF_PROVIDER_OPS_VERSION_CURRENT,
/* Other required callbacks. */
.get_address_space = custom_get_address_space,
};

Set ``context`` or ``device`` to zero when that part of the identity does not
apply. Providers that cannot determine their address space can return
``UMF_RESULT_ERROR_NOT_SUPPORTED``; tracking then treats each provider instance
as a separate address space, so providers that intentionally share an address
space should return an explicit common identity instead.

CTL example
==============================================================================
Expand Down
17 changes: 17 additions & 0 deletions docs/config/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,23 @@ would be a NUMA node mask for the OS memory provider, file path for the
file-backed memory provider, etc. After creation, the memory provider context
can't be changed.

Address spaces
--------------

Numerically identical pointer values can refer to different memory when they
come from different address spaces, for example from different GPU contexts.
Memory providers identify the address space used by their allocations with a
process-local tuple consisting of a namespace token, context, and device. UMF
uses this identity when tracking allocations so that overlapping virtual
address ranges from independent memory domains do not conflict.

The namespace token distinguishes address-space implementations. Providers
that return pointers in the process host address space use a NULL namespace
token with zero context and device identifiers. GPU and custom providers can
use their own namespace token and native context and device identifiers. The
identity is process-local and is not intended for serialization or
inter-process exchange.

Pool Allocators
===============

Expand Down
4 changes: 4 additions & 0 deletions docs/config/spelling_exceptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ daxX
deallocating
deallocation
deallocations
dereferences
dev
Devdax
Globals
Expand Down Expand Up @@ -39,6 +40,8 @@ memtargets
middleware
minBytesToKeep
multithreading
namespace
namespaces
Nodemask
nodemask
numa
Expand Down Expand Up @@ -77,6 +80,7 @@ umfOsMemoryProviderParamsDestroy
umfPool
umfPoolCalloc
umfPoolDestroy
umfPoolFree
umfPoolGetTag
umfPoolMallocUsableSize
umfPoolRealloc
Expand Down
22 changes: 20 additions & 2 deletions include/umf/base.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (C) 2023-2025 Intel Corporation
* Copyright (C) 2023-2026 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand Down Expand Up @@ -28,7 +28,7 @@ extern "C" {
#define UMF_MINOR_VERSION(_ver) (_ver & 0x0000ffff)

/// @brief Current version of the UMF headers
#define UMF_VERSION_CURRENT UMF_MAKE_VERSION(1, 0)
#define UMF_VERSION_CURRENT UMF_MAKE_VERSION(1, 1)

/// @brief Operation results
typedef enum umf_result_t {
Expand All @@ -50,9 +50,27 @@ typedef enum umf_result_t {
UMF_RESULT_ERROR_OUT_OF_RESOURCES = 8, ///< Out of internal resources
UMF_RESULT_ERROR_INVALID_CTL_PATH =
9, ///< CTL path is not supported or not found
UMF_RESULT_ERROR_AMBIGUOUS =
10, ///< Multiple allocations match the supplied argument
UMF_RESULT_ERROR_UNKNOWN = 0x7ffffffe ///< Unknown error
} umf_result_t;

/// @brief Process-local identity of a virtual address space.
typedef struct umf_memory_provider_address_space_t {
/// Opaque namespace token. NULL identifies the host address space. UMF
/// compares non-NULL tokens by address and never dereferences them.
/// Providers whose pointers belong to the same non-host address-space
/// namespace must return the same token. The token address must remain
/// stable while providers using it exist.
const void *namespace_token;
/// Process-local native context identifier within the namespace, or zero
/// when the namespace does not use contexts.
uintptr_t context;
/// Process-local native device identifier within the context, or zero when
/// the namespace does not use devices.
uintptr_t device;
} umf_memory_provider_address_space_t;

/// @brief Handle to the memory properties structure
typedef struct umf_memory_properties_t *umf_memory_properties_handle_t;

Expand Down
4 changes: 3 additions & 1 deletion include/umf/memory_pool.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (C) 2023-2025 Intel Corporation
* Copyright (C) 2023-2026 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand Down Expand Up @@ -126,6 +126,8 @@ umf_result_t umfPoolFree(umf_memory_pool_handle_t hPool, void *ptr);
/// @brief Frees the memory space pointed by ptr if it belongs to UMF pool, does nothing otherwise.
/// @param ptr pointer to the allocated memory
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
/// UMF_RESULT_ERROR_AMBIGUOUS if multiple active allocations have the
/// same address. Use umfPoolFree() to select the allocation's pool.
/// Whether any status other than UMF_RESULT_SUCCESS can be returned
/// depends on the memory provider used by the pool.
///
Expand Down
16 changes: 16 additions & 0 deletions include/umf/memory_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,22 @@ umf_result_t
umfMemoryProviderGetCacheLineSize(umf_memory_provider_handle_t hProvider,
size_t *size);

///
/// @brief Retrieve the process-local address-space identity used by allocations
/// from the provider.
/// @details The returned namespace token is NULL for the host address space.
/// Providers that share another address-space namespace must return
/// the same stable non-NULL token.
/// @param hProvider handle to the memory provider
/// @param address_space [out] pointer to the address-space identity
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
/// UMF_RESULT_ERROR_NOT_SUPPORTED if the provider cannot determine its
/// address space.
///
umf_result_t umfMemoryProviderGetAddressSpace(
umf_memory_provider_handle_t hProvider,
umf_memory_provider_address_space_t *address_space);

///
/// @brief Discard physical pages within the virtual memory mapping associated at the given addr
/// and \p size. This call is asynchronous and may delay purging the pages indefinitely.
Expand Down
19 changes: 18 additions & 1 deletion include/umf/memory_provider_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ extern "C" {
/// @brief Version of the Memory Provider ops structure.
/// NOTE: This is equal to the latest UMF version, in which the ops structure
/// has been modified.
#define UMF_PROVIDER_OPS_VERSION_CURRENT UMF_MAKE_VERSION(1, 2)
#define UMF_PROVIDER_OPS_VERSION_CURRENT UMF_MAKE_VERSION(1, 3)

///
/// @brief This structure comprises function pointers used by corresponding
Expand Down Expand Up @@ -336,6 +336,23 @@ typedef struct umf_memory_provider_ops_t {
///
umf_result_t (*get_cache_line_size)(void *provider, size_t *size);

// The following operations were added in ops version 1.3

///
/// @brief Retrieve the process-local address-space identity used by
/// allocations from the provider.
/// @details The callback must return a NULL namespace token for the host
/// address space. Providers that share another address-space
/// namespace must return the same stable non-NULL token.
/// @param provider pointer to the memory provider
/// @param address_space [out] pointer to the address-space identity
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on
/// failure. UMF_RESULT_ERROR_NOT_SUPPORTED if the provider cannot
/// determine its address space.
///
umf_result_t (*get_address_space)(
void *provider, umf_memory_provider_address_space_t *address_space);

} umf_memory_provider_ops_t;

#ifdef __cplusplus
Expand Down
10 changes: 9 additions & 1 deletion include/umf/providers/provider_fixed_memory.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2024-2025 Intel Corporation
* Copyright (C) 2024-2026 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand Down Expand Up @@ -41,6 +41,14 @@ umf_result_t umfFixedMemoryProviderParamsCreate(
umf_result_t umfFixedMemoryProviderParamsSetMemory(
umf_fixed_memory_provider_params_handle_t hParams, void *ptr, size_t size);

/// @brief Set the address space containing the fixed memory region.
/// @param hParams [in] handle to the parameters of the Fixed Memory Provider.
/// @param addressSpace [in] process-local address-space identity.
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
umf_result_t umfFixedMemoryProviderParamsSetAddressSpace(
umf_fixed_memory_provider_params_handle_t hParams,
const umf_memory_provider_address_space_t *addressSpace);

/// @brief Destroy parameters struct.
/// @param hParams [in] handle to the parameters of the Fixed Memory Provider.
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
Expand Down
3 changes: 3 additions & 0 deletions src/libumf.def
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,6 @@ EXPORTS
umfScalablePoolParamsSetName
; Added in UMF_1.2
umfMemoryProviderGetCacheLineSize
; Added in UMF_1.3
umfFixedMemoryProviderParamsSetAddressSpace
umfMemoryProviderGetAddressSpace
7 changes: 6 additions & 1 deletion src/libumf.map
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ UMF_1.1 {
umfScalablePoolParamsSetName;
} UMF_1.0;

UMF_1.2 {
UMF_1.2 {
umfMemoryProviderGetCacheLineSize;
} UMF_1.1;

UMF_1.3 {
umfFixedMemoryProviderParamsSetAddressSpace;
umfMemoryProviderGetAddressSpace;
} UMF_1.2;
Loading