[llvm] Draft: [Offload] Implement olMemAlloc, olMemFree (PR #119549)
Callum Fare via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 11 04:13:41 PST 2024
https://github.com/callumfare updated https://github.com/llvm/llvm-project/pull/119549
>From 7cbe788ddc0de682ce0f939caf4619e99889f992 Mon Sep 17 00:00:00 2001
From: Callum Fare <callum at codeplay.com>
Date: Wed, 11 Dec 2024 12:08:44 +0000
Subject: [PATCH 1/2] WIP: Implement olMemAlloc, olMemFree
---
offload/liboffload/API/Memory.td | 45 +++++++++
offload/liboffload/API/OffloadAPI.td | 1 +
.../liboffload/include/generated/OffloadAPI.h | 95 +++++++++++++++++++
.../include/generated/OffloadEntryPoints.inc | 93 ++++++++++++++++++
.../include/generated/OffloadFuncs.inc | 4 +
.../generated/OffloadImplFuncDecls.inc | 7 ++
.../include/generated/OffloadPrint.hpp | 53 +++++++++++
offload/liboffload/src/OffloadImpl.cpp | 35 +++++++
8 files changed, 333 insertions(+)
create mode 100644 offload/liboffload/API/Memory.td
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
new file mode 100644
index 00000000000000..8cfaf70311e346
--- /dev/null
+++ b/offload/liboffload/API/Memory.td
@@ -0,0 +1,45 @@
+//===-- Memory.td - Memory definitions for Offload ---------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains Offload API definitions related to memory allocations
+//
+//===----------------------------------------------------------------------===//
+
+def : Enum {
+ let name = "ol_alloc_type_t";
+ let desc = "Represents the type of allocation made with olMemAlloc";
+ let etors = [
+ Etor<"HOST", "Host allocation">,
+ Etor<"DEVICE", "Device allocation">,
+ Etor<"SHARED", "Shared allocation">
+ ];
+}
+
+def : Function {
+ let name = "olMemAlloc";
+ let desc = "Creates a memory allocation on the specified device";
+ let params = [
+ Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
+ Param<"ol_alloc_type_t", "Type", "type of the allocation", PARAM_IN>,
+ Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>,
+ Param<"size_t", "Aligment", "alignment of the allocation in bytes", PARAM_IN>,
+ Param<"void**", "AllocationOut", "output for the allocated pointer", PARAM_OUT>
+ ];
+ let returns = [];
+}
+
+def : Function {
+ let name = "olMemFree";
+ let desc = "Frees a memory allocation previously made by olMemAlloc";
+ let params = [
+ Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
+ Param<"ol_alloc_type_t", "Type", "type of the allocation", PARAM_IN>,
+ Param<"void*", "Address", "address of the allocation to free", PARAM_IN>,
+ ];
+ let returns = [];
+}
diff --git a/offload/liboffload/API/OffloadAPI.td b/offload/liboffload/API/OffloadAPI.td
index 8a0c3c40581223..a609cc7ac80b41 100644
--- a/offload/liboffload/API/OffloadAPI.td
+++ b/offload/liboffload/API/OffloadAPI.td
@@ -13,3 +13,4 @@ include "APIDefs.td"
include "Common.td"
include "Platform.td"
include "Device.td"
+include "Memory.td"
diff --git a/offload/liboffload/include/generated/OffloadAPI.h b/offload/liboffload/include/generated/OffloadAPI.h
index 11fcc96625ab8d..81f3a8e0201bad 100644
--- a/offload/liboffload/include/generated/OffloadAPI.h
+++ b/offload/liboffload/include/generated/OffloadAPI.h
@@ -460,6 +460,67 @@ OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceInfoSize(
// [out] pointer to the number of bytes required to store the query
size_t *PropSizeRet);
+///////////////////////////////////////////////////////////////////////////////
+/// @brief Represents the type of allocation made with olMemAlloc
+typedef enum ol_alloc_type_t {
+ /// Host allocation
+ OL_ALLOC_TYPE_HOST = 0,
+ /// Device allocation
+ OL_ALLOC_TYPE_DEVICE = 1,
+ /// Shared allocation
+ OL_ALLOC_TYPE_SHARED = 2,
+ /// @cond
+ OL_ALLOC_TYPE_FORCE_UINT32 = 0x7fffffff
+ /// @endcond
+
+} ol_alloc_type_t;
+
+///////////////////////////////////////////////////////////////////////////////
+/// @brief Creates a memory allocation on the specified device
+///
+/// @details
+///
+/// @returns
+/// - ::OL_RESULT_SUCCESS
+/// - ::OL_ERRC_UNINITIALIZED
+/// - ::OL_ERRC_DEVICE_LOST
+/// - ::OL_ERRC_INVALID_NULL_HANDLE
+/// + `NULL == Device`
+/// - ::OL_ERRC_INVALID_NULL_POINTER
+/// + `NULL == AllocationOut`
+OL_APIEXPORT ol_result_t OL_APICALL olMemAlloc(
+ // [in] handle of the device to allocate on
+ ol_device_handle_t Device,
+ // [in] type of the allocation
+ ol_alloc_type_t Type,
+ // [in] size of the allocation in bytes
+ size_t Size,
+ // [in] alignment of the allocation in bytes
+ size_t Aligment,
+ // [out] output for the allocated pointer
+ void **AllocationOut);
+
+///////////////////////////////////////////////////////////////////////////////
+/// @brief Frees a memory allocation previously made by olMemAlloc
+///
+/// @details
+///
+/// @returns
+/// - ::OL_RESULT_SUCCESS
+/// - ::OL_ERRC_UNINITIALIZED
+/// - ::OL_ERRC_DEVICE_LOST
+/// - ::OL_ERRC_INVALID_NULL_HANDLE
+/// + `NULL == Device`
+/// - ::OL_ERRC_INVALID_NULL_POINTER
+/// + `NULL == Address`
+OL_APIEXPORT ol_result_t OL_APICALL olMemFree(
+ // [in] handle of the device to allocate on
+ ol_device_handle_t Device,
+ // [in] type of the allocation
+ ol_alloc_type_t Type,
+ // [in] address of the allocation to free
+ void *Address);
+
///////////////////////////////////////////////////////////////////////////////
/// @brief Function parameters for olGetPlatform
/// @details Each entry is a pointer to the parameter passed to the function;
@@ -530,6 +591,26 @@ typedef struct ol_get_device_info_size_params_t {
size_t **pPropSizeRet;
} ol_get_device_info_size_params_t;
+///////////////////////////////////////////////////////////////////////////////
+/// @brief Function parameters for olMemAlloc
+/// @details Each entry is a pointer to the parameter passed to the function;
+typedef struct ol_mem_alloc_params_t {
+ ol_device_handle_t *pDevice;
+ ol_alloc_type_t *pType;
+ size_t *pSize;
+ size_t *pAligment;
+ void ***pAllocationOut;
+} ol_mem_alloc_params_t;
+
+///////////////////////////////////////////////////////////////////////////////
+/// @brief Function parameters for olMemFree
+/// @details Each entry is a pointer to the parameter passed to the function;
+typedef struct ol_mem_free_params_t {
+ ol_device_handle_t *pDevice;
+ ol_alloc_type_t *pType;
+ void **pAddress;
+} ol_mem_free_params_t;
+
///////////////////////////////////////////////////////////////////////////////
/// @brief Variant of olInit that also sets source code location information
/// @details See also ::olInit
@@ -605,6 +686,20 @@ OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceInfoSizeWithCodeLoc(
ol_device_handle_t Device, ol_device_info_t PropName, size_t *PropSizeRet,
ol_code_location_t *CodeLocation);
+///////////////////////////////////////////////////////////////////////////////
+/// @brief Variant of olMemAlloc that also sets source code location information
+/// @details See also ::olMemAlloc
+OL_APIEXPORT ol_result_t OL_APICALL olMemAllocWithCodeLoc(
+ ol_device_handle_t Device, ol_alloc_type_t Type, size_t Size,
+ size_t Aligment, void **AllocationOut, ol_code_location_t *CodeLocation);
+
+///////////////////////////////////////////////////////////////////////////////
+/// @brief Variant of olMemFree that also sets source code location information
+/// @details See also ::olMemFree
+OL_APIEXPORT ol_result_t OL_APICALL
+olMemFreeWithCodeLoc(ol_device_handle_t Device, ol_alloc_type_t Type,
+ void *Address, ol_code_location_t *CodeLocation);
+
#if defined(__cplusplus)
} // extern "C"
#endif
diff --git a/offload/liboffload/include/generated/OffloadEntryPoints.inc b/offload/liboffload/include/generated/OffloadEntryPoints.inc
index 49c1c8169615e5..08060dae80f035 100644
--- a/offload/liboffload/include/generated/OffloadEntryPoints.inc
+++ b/offload/liboffload/include/generated/OffloadEntryPoints.inc
@@ -439,3 +439,96 @@ ol_result_t olGetDeviceInfoSizeWithCodeLoc(ol_device_handle_t Device,
currentCodeLocation() = nullptr;
return Result;
}
+
+///////////////////////////////////////////////////////////////////////////////
+ol_impl_result_t olMemAlloc_val(ol_device_handle_t Device, ol_alloc_type_t Type,
+ size_t Size, size_t Aligment,
+ void **AllocationOut) {
+ if (true /*enableParameterValidation*/) {
+ if (NULL == Device) {
+ return OL_ERRC_INVALID_NULL_HANDLE;
+ }
+
+ if (NULL == AllocationOut) {
+ return OL_ERRC_INVALID_NULL_POINTER;
+ }
+ }
+
+ return olMemAlloc_impl(Device, Type, Size, Aligment, AllocationOut);
+}
+OL_APIEXPORT ol_result_t OL_APICALL olMemAlloc(ol_device_handle_t Device,
+ ol_alloc_type_t Type,
+ size_t Size, size_t Aligment,
+ void **AllocationOut) {
+ if (offloadConfig().TracingEnabled) {
+ std::cout << "---> olMemAlloc";
+ }
+
+ ol_result_t Result =
+ olMemAlloc_val(Device, Type, Size, Aligment, AllocationOut);
+
+ if (offloadConfig().TracingEnabled) {
+ ol_mem_alloc_params_t Params = {&Device, &Type, &Size, &Aligment,
+ &AllocationOut};
+ std::cout << "(" << &Params << ")";
+ std::cout << "-> " << Result << "\n";
+ if (Result && Result->Details) {
+ std::cout << " *Error Details* " << Result->Details << " \n";
+ }
+ }
+ return Result;
+}
+ol_result_t olMemAllocWithCodeLoc(ol_device_handle_t Device,
+ ol_alloc_type_t Type, size_t Size,
+ size_t Aligment, void **AllocationOut,
+ ol_code_location_t *CodeLocation) {
+ currentCodeLocation() = CodeLocation;
+ ol_result_t Result = olMemAlloc(Device, Type, Size, Aligment, AllocationOut);
+
+ currentCodeLocation() = nullptr;
+ return Result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+ol_impl_result_t olMemFree_val(ol_device_handle_t Device, ol_alloc_type_t Type,
+ void *Address) {
+ if (true /*enableParameterValidation*/) {
+ if (NULL == Device) {
+ return OL_ERRC_INVALID_NULL_HANDLE;
+ }
+
+ if (NULL == Address) {
+ return OL_ERRC_INVALID_NULL_POINTER;
+ }
+ }
+
+ return olMemFree_impl(Device, Type, Address);
+}
+OL_APIEXPORT ol_result_t OL_APICALL olMemFree(ol_device_handle_t Device,
+ ol_alloc_type_t Type,
+ void *Address) {
+ if (offloadConfig().TracingEnabled) {
+ std::cout << "---> olMemFree";
+ }
+
+ ol_result_t Result = olMemFree_val(Device, Type, Address);
+
+ if (offloadConfig().TracingEnabled) {
+ ol_mem_free_params_t Params = {&Device, &Type, &Address};
+ std::cout << "(" << &Params << ")";
+ std::cout << "-> " << Result << "\n";
+ if (Result && Result->Details) {
+ std::cout << " *Error Details* " << Result->Details << " \n";
+ }
+ }
+ return Result;
+}
+ol_result_t olMemFreeWithCodeLoc(ol_device_handle_t Device,
+ ol_alloc_type_t Type, void *Address,
+ ol_code_location_t *CodeLocation) {
+ currentCodeLocation() = CodeLocation;
+ ol_result_t Result = olMemFree(Device, Type, Address);
+
+ currentCodeLocation() = nullptr;
+ return Result;
+}
diff --git a/offload/liboffload/include/generated/OffloadFuncs.inc b/offload/liboffload/include/generated/OffloadFuncs.inc
index 48115493c790f4..26120f18279dcc 100644
--- a/offload/liboffload/include/generated/OffloadFuncs.inc
+++ b/offload/liboffload/include/generated/OffloadFuncs.inc
@@ -20,6 +20,8 @@ OFFLOAD_FUNC(olGetDeviceCount)
OFFLOAD_FUNC(olGetDevice)
OFFLOAD_FUNC(olGetDeviceInfo)
OFFLOAD_FUNC(olGetDeviceInfoSize)
+OFFLOAD_FUNC(olMemAlloc)
+OFFLOAD_FUNC(olMemFree)
OFFLOAD_FUNC(olInitWithCodeLoc)
OFFLOAD_FUNC(olShutDownWithCodeLoc)
OFFLOAD_FUNC(olGetPlatformWithCodeLoc)
@@ -30,5 +32,7 @@ OFFLOAD_FUNC(olGetDeviceCountWithCodeLoc)
OFFLOAD_FUNC(olGetDeviceWithCodeLoc)
OFFLOAD_FUNC(olGetDeviceInfoWithCodeLoc)
OFFLOAD_FUNC(olGetDeviceInfoSizeWithCodeLoc)
+OFFLOAD_FUNC(olMemAllocWithCodeLoc)
+OFFLOAD_FUNC(olMemFreeWithCodeLoc)
#undef OFFLOAD_FUNC
diff --git a/offload/liboffload/include/generated/OffloadImplFuncDecls.inc b/offload/liboffload/include/generated/OffloadImplFuncDecls.inc
index 5b26b2653a05d9..f0a96081fd2431 100644
--- a/offload/liboffload/include/generated/OffloadImplFuncDecls.inc
+++ b/offload/liboffload/include/generated/OffloadImplFuncDecls.inc
@@ -36,3 +36,10 @@ ol_impl_result_t olGetDeviceInfo_impl(ol_device_handle_t Device,
ol_impl_result_t olGetDeviceInfoSize_impl(ol_device_handle_t Device,
ol_device_info_t PropName,
size_t *PropSizeRet);
+
+ol_impl_result_t olMemAlloc_impl(ol_device_handle_t Device,
+ ol_alloc_type_t Type, size_t Size,
+ size_t Aligment, void **AllocationOut);
+
+ol_impl_result_t olMemFree_impl(ol_device_handle_t Device, ol_alloc_type_t Type,
+ void *Address);
diff --git a/offload/liboffload/include/generated/OffloadPrint.hpp b/offload/liboffload/include/generated/OffloadPrint.hpp
index 8981bb054a4cb1..cff754237568e6 100644
--- a/offload/liboffload/include/generated/OffloadPrint.hpp
+++ b/offload/liboffload/include/generated/OffloadPrint.hpp
@@ -31,6 +31,7 @@ inline std::ostream &operator<<(std::ostream &os,
enum ol_platform_backend_t value);
inline std::ostream &operator<<(std::ostream &os, enum ol_device_type_t value);
inline std::ostream &operator<<(std::ostream &os, enum ol_device_info_t value);
+inline std::ostream &operator<<(std::ostream &os, enum ol_alloc_type_t value);
///////////////////////////////////////////////////////////////////////////////
/// @brief Print operator for the ol_errc_t type
@@ -274,6 +275,26 @@ inline void printTagged(std::ostream &os, const void *ptr,
break;
}
}
+///////////////////////////////////////////////////////////////////////////////
+/// @brief Print operator for the ol_alloc_type_t type
+/// @returns std::ostream &
+inline std::ostream &operator<<(std::ostream &os, enum ol_alloc_type_t value) {
+ switch (value) {
+ case OL_ALLOC_TYPE_HOST:
+ os << "OL_ALLOC_TYPE_HOST";
+ break;
+ case OL_ALLOC_TYPE_DEVICE:
+ os << "OL_ALLOC_TYPE_DEVICE";
+ break;
+ case OL_ALLOC_TYPE_SHARED:
+ os << "OL_ALLOC_TYPE_SHARED";
+ break;
+ default:
+ os << "unknown enumerator";
+ break;
+ }
+ return os;
+}
inline std::ostream &operator<<(std::ostream &os,
const ol_error_struct_t *Err) {
@@ -402,6 +423,38 @@ operator<<(std::ostream &os,
return os;
}
+inline std::ostream &operator<<(std::ostream &os,
+ const struct ol_mem_alloc_params_t *params) {
+ os << ".Device = ";
+ printPtr(os, *params->pDevice);
+ os << ", ";
+ os << ".Type = ";
+ os << *params->pType;
+ os << ", ";
+ os << ".Size = ";
+ os << *params->pSize;
+ os << ", ";
+ os << ".Aligment = ";
+ os << *params->pAligment;
+ os << ", ";
+ os << ".AllocationOut = ";
+ printPtr(os, *params->pAllocationOut);
+ return os;
+}
+
+inline std::ostream &operator<<(std::ostream &os,
+ const struct ol_mem_free_params_t *params) {
+ os << ".Device = ";
+ printPtr(os, *params->pDevice);
+ os << ", ";
+ os << ".Type = ";
+ os << *params->pType;
+ os << ", ";
+ os << ".Address = ";
+ printPtr(os, *params->pAddress);
+ return os;
+}
+
///////////////////////////////////////////////////////////////////////////////
// @brief Print pointer value
template <typename T>
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 457f1053f16341..3e609ed03917f4 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -245,3 +245,38 @@ ol_impl_result_t olGetDeviceInfoSize_impl(ol_device_handle_t Device,
size_t *PropSizeRet) {
return olGetDeviceInfoImplDetail(Device, PropName, 0, nullptr, PropSizeRet);
}
+
+TargetAllocTy convertOlToPluginAllocTy(ol_alloc_type_t Type) {
+ switch (Type) {
+ case OL_ALLOC_TYPE_DEVICE:
+ return TARGET_ALLOC_DEVICE;
+ case OL_ALLOC_TYPE_HOST:
+ return TARGET_ALLOC_HOST;
+ case OL_ALLOC_TYPE_SHARED:
+ default:
+ return TARGET_ALLOC_SHARED;
+ }
+}
+
+ol_impl_result_t olMemAlloc_impl(ol_device_handle_t Device,
+ ol_alloc_type_t Type, size_t Size, size_t,
+ void **AllocationOut) {
+ auto Alloc =
+ Device->Device.dataAlloc(Size, nullptr, convertOlToPluginAllocTy(Type));
+ if (!Alloc) {
+ return {OL_ERRC_OUT_OF_RESOURCES,
+ formatv("Could not create allocation on device {0}", Device).str()};
+ }
+
+ *AllocationOut = *Alloc;
+ return OL_SUCCESS;
+}
+
+ol_impl_result_t olMemFree_impl(ol_device_handle_t Device, ol_alloc_type_t Type,
+ void *Address) {
+ auto Res = Device->Device.dataDelete(Address, convertOlToPluginAllocTy(Type));
+ if (Res) {
+ return {OL_ERRC_OUT_OF_RESOURCES, "Could not free allocation"};
+ }
+ return OL_SUCCESS;
+}
>From 73ed36a366dec72b63dccdc24d240e0efc0bf528 Mon Sep 17 00:00:00 2001
From: Callum Fare <callum at codeplay.com>
Date: Wed, 11 Dec 2024 12:13:29 +0000
Subject: [PATCH 2/2] Add size check
---
offload/liboffload/API/Memory.td | 6 +++++-
offload/liboffload/include/generated/OffloadAPI.h | 2 ++
offload/liboffload/include/generated/OffloadEntryPoints.inc | 4 ++++
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 8cfaf70311e346..c15ae6f6d21ca2 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -30,7 +30,11 @@ def : Function {
Param<"size_t", "Aligment", "alignment of the allocation in bytes", PARAM_IN>,
Param<"void**", "AllocationOut", "output for the allocated pointer", PARAM_OUT>
];
- let returns = [];
+ let returns = [
+ Return<"OL_ERRC_INVALID_SIZE", [
+ "`Size == 0`"
+ ]>
+ ];
}
def : Function {
diff --git a/offload/liboffload/include/generated/OffloadAPI.h b/offload/liboffload/include/generated/OffloadAPI.h
index 81f3a8e0201bad..4c3356645e55aa 100644
--- a/offload/liboffload/include/generated/OffloadAPI.h
+++ b/offload/liboffload/include/generated/OffloadAPI.h
@@ -484,6 +484,8 @@ typedef enum ol_alloc_type_t {
/// - ::OL_RESULT_SUCCESS
/// - ::OL_ERRC_UNINITIALIZED
/// - ::OL_ERRC_DEVICE_LOST
+/// - ::OL_ERRC_INVALID_SIZE
+/// + `Size == 0`
/// - ::OL_ERRC_INVALID_NULL_HANDLE
/// + `NULL == Device`
/// - ::OL_ERRC_INVALID_NULL_POINTER
diff --git a/offload/liboffload/include/generated/OffloadEntryPoints.inc b/offload/liboffload/include/generated/OffloadEntryPoints.inc
index 08060dae80f035..bcde65452b265f 100644
--- a/offload/liboffload/include/generated/OffloadEntryPoints.inc
+++ b/offload/liboffload/include/generated/OffloadEntryPoints.inc
@@ -445,6 +445,10 @@ ol_impl_result_t olMemAlloc_val(ol_device_handle_t Device, ol_alloc_type_t Type,
size_t Size, size_t Aligment,
void **AllocationOut) {
if (true /*enableParameterValidation*/) {
+ if (Size == 0) {
+ return OL_ERRC_INVALID_SIZE;
+ }
+
if (NULL == Device) {
return OL_ERRC_INVALID_NULL_HANDLE;
}
More information about the llvm-commits
mailing list