diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td new file mode 100644 index 0000000000000..c15ae6f6d21ca --- /dev/null +++ b/offload/liboffload/API/Memory.td @@ -0,0 +1,49 @@ +//===-- 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 = [ + Return<"OL_ERRC_INVALID_SIZE", [ + "`Size == 0`" + ]> + ]; +} + +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 8a0c3c4058122..a609cc7ac80b4 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 11fcc96625ab8..4c3356645e55a 100644 --- a/offload/liboffload/include/generated/OffloadAPI.h +++ b/offload/liboffload/include/generated/OffloadAPI.h @@ -460,6 +460,69 @@ 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_SIZE +/// + `Size == 0` +/// - ::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 +593,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 +688,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 49c1c8169615e..bcde65452b265 100644 --- a/offload/liboffload/include/generated/OffloadEntryPoints.inc +++ b/offload/liboffload/include/generated/OffloadEntryPoints.inc @@ -439,3 +439,100 @@ 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 (Size == 0) { + return OL_ERRC_INVALID_SIZE; + } + + 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 48115493c790f..26120f18279dc 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 5b26b2653a05d..f0a96081fd243 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 8981bb054a4cb..cff754237568e 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 diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp index 457f1053f1634..3e609ed03917f 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; +}