Initial implementation for creating buffer with ext memory for OpenCl

Related-To: NEO-6757

Signed-off-by: Baj, Tomasz <tomasz.baj@intel.com>
This commit is contained in:
Baj, Tomasz 2022-04-26 10:25:41 +00:00 committed by Compute-Runtime-Automation
parent 28317e7062
commit 2a0c395db5
14 changed files with 383 additions and 5 deletions

View File

@ -266,3 +266,26 @@ typedef cl_bitfield cl_command_queue_mdapi_properties_intel;
/* cl_command_queue_mdapi_properties_intel - bitfield */
#define CL_QUEUE_MDAPI_ENABLE_INTEL (1 << 0)
/************************************************
* cl_khr_external_memory extension *
*************************************************/
/* clGetPlatformInfo */
#define CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR 0x2044
/* clGetDeviceInfo */
#define CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR 0x204F
/* clCreateBufferWithProperties and clCreateImageWithProperties */
#define CL_DEVICE_HANDLE_LIST_KHR 0x2051
#define CL_DEVICE_HANDLE_LIST_END_KHR 0
#define CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR 0x2060
#define CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR 0x2061
#define CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR 0x2062
#define CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KHR 0x2063
#define CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KMT_KHR 0x2064
#define CL_EXTERNAL_MEMORY_HANDLE_D3D12_HEAP_KHR 0x2065
#define CL_EXTERNAL_MEMORY_HANDLE_D3D12_RESOURCE_KHR 0x2066
#define CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR 0x2067

View File

@ -9,6 +9,7 @@
#include "opencl/source/context/context.h"
#include "opencl/source/helpers/cl_memory_properties_helpers_base.inl"
#include "opencl/source/mem_obj/mem_obj_helper.h"
#include "opencl/source/sharings/unified/unified_buffer.h"
namespace NEO {
@ -16,6 +17,8 @@ bool ClMemoryPropertiesHelper::parseMemoryProperties(const cl_mem_properties_int
cl_mem_flags &flags, cl_mem_flags_intel &flagsIntel,
cl_mem_alloc_flags_intel &allocflags, MemoryPropertiesHelper::ObjType objectType, Context &context) {
Device *pDevice = &context.getDevice(0)->getDevice();
uint64_t handle = 0;
uint64_t handleType = 0;
uintptr_t hostptr = 0;
if (properties != nullptr) {
for (int i = 0; properties[i] != 0; i += 2) {
@ -32,6 +35,10 @@ bool ClMemoryPropertiesHelper::parseMemoryProperties(const cl_mem_properties_int
case CL_MEM_ALLOC_USE_HOST_PTR_INTEL:
hostptr = static_cast<uintptr_t>(properties[i + 1]);
break;
case CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR:
handle = static_cast<uint64_t>(properties[i + 1]);
handleType = static_cast<uint64_t>(UnifiedSharingHandleType::LinuxFd);
break;
default:
return false;
}
@ -39,6 +46,8 @@ bool ClMemoryPropertiesHelper::parseMemoryProperties(const cl_mem_properties_int
}
memoryProperties = ClMemoryPropertiesHelper::createMemoryProperties(flags, flagsIntel, allocflags, pDevice);
memoryProperties.handleType = handleType;
memoryProperties.handle = handle;
memoryProperties.hostptr = hostptr;
switch (objectType) {

View File

@ -27,6 +27,16 @@ set(RUNTIME_SRCS_MEM_OBJ
${CMAKE_CURRENT_SOURCE_DIR}/definitions${BRANCH_DIR_SUFFIX}image_ext.inl
)
if(WIN32)
list(APPEND RUNTIME_SRCS_MEM_OBJ
${CMAKE_CURRENT_SOURCE_DIR}/buffer_windows.cpp
)
else()
list(APPEND RUNTIME_SRCS_MEM_OBJ
${CMAKE_CURRENT_SOURCE_DIR}/buffer_linux.cpp
)
endif()
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_MEM_OBJ})
set_property(GLOBAL PROPERTY RUNTIME_SRCS_MEM_OBJ ${RUNTIME_SRCS_MEM_OBJ})
add_subdirectories()

View File

@ -141,13 +141,28 @@ cl_mem Buffer::validateInputAndCreateBuffer(cl_context context,
}
// create the buffer
auto buffer = create(pContext, memoryProperties, flags, flagsIntel, size, hostPtr, retVal);
if (retVal == CL_SUCCESS) {
buffer->storeProperties(properties);
Buffer *pBuffer = nullptr;
UnifiedSharingMemoryDescription extMem{};
if (memoryProperties.handle) {
if (validateHandleType(memoryProperties, extMem)) {
extMem.handle = &memoryProperties.handle;
extMem.size = size;
pBuffer = UnifiedBuffer::createSharedUnifiedBuffer(pContext, flags, extMem, &retVal);
} else {
retVal = CL_INVALID_PROPERTY;
return nullptr;
}
} else {
pBuffer = create(pContext, memoryProperties, flags, flagsIntel, size, hostPtr, retVal);
}
return buffer;
if (retVal == CL_SUCCESS) {
pBuffer->storeProperties(properties);
}
return pBuffer;
}
Buffer *Buffer::create(Context *context,

View File

@ -12,6 +12,7 @@
#include "opencl/extensions/public/cl_ext_private.h"
#include "opencl/source/context/context_type.h"
#include "opencl/source/mem_obj/mem_obj.h"
#include "opencl/source/sharings/unified/unified_buffer.h"
#include "igfxfmid.h"
#include "memory_properties_flags.h"
@ -162,6 +163,8 @@ class Buffer : public MemObj {
bool isCompressed(uint32_t rootDeviceIndex) const;
static bool validateHandleType(MemoryProperties &memoryProperties, UnifiedSharingMemoryDescription &extMem);
protected:
Buffer(Context *context,
MemoryProperties memoryProperties,

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/source/mem_obj/buffer.h"
namespace NEO {
bool Buffer::validateHandleType(MemoryProperties &memoryProperties, UnifiedSharingMemoryDescription &extMem) {
if (memoryProperties.handleType == static_cast<uint64_t>(UnifiedSharingHandleType::LinuxFd)) {
extMem.type = UnifiedSharingHandleType::LinuxFd;
return true;
}
return false;
}
} // namespace NEO

View File

@ -0,0 +1,14 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/source/mem_obj/buffer.h"
namespace NEO {
bool Buffer::validateHandleType(MemoryProperties &memoryProperties, UnifiedSharingMemoryDescription &extMem) {
return false;
}
} // namespace NEO

View File

@ -409,6 +409,18 @@ TEST_F(MemoryPropertiesHelperTests, givenMemFlagsWithFlagsAndPropertiesWhenParsi
}
}
TEST_F(MemoryPropertiesHelperTests, givenDmaBufWhenParsePropertiesThenHandleIsSet) {
cl_mem_properties_intel properties[] = {
CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR,
0x1234u,
0};
EXPECT_TRUE(ClMemoryPropertiesHelper::parseMemoryProperties(properties, memoryProperties, flags, flagsIntel, allocflags,
MemoryPropertiesHelper::ObjType::BUFFER, context));
EXPECT_EQ(memoryProperties.handle, 0x1234u);
}
TEST_F(MemoryPropertiesHelperTests, WhenAdjustingDeviceBitfieldThenCorrectBitfieldIsReturned) {
UltClDeviceFactory deviceFactory{2, 4};
auto memoryPropertiesRootDevice0 = ClMemoryPropertiesHelper::createMemoryProperties(0, 0, 0, &deviceFactory.rootDevices[0]->getDevice());

View File

@ -608,6 +608,7 @@ TEST(Buffer, givenClMemCopyHostPointerPassedToBufferCreateWhenAllocationIsNotInS
EXPECT_LT(taskCount, taskCountSent);
}
}
struct CompressedBuffersTests : public ::testing::Test {
void SetUp() override {
ExecutionEnvironment *executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
@ -1195,6 +1196,14 @@ TEST_P(ValidHostPtr, GivenSvmHostPtrWhenCreatingBufferThenBufferIsCreatedCorrect
}
}
TEST_P(ValidHostPtr, WhenValidateInputAndCreateBufferThenCorrectBufferIsSet) {
auto buffer = BufferFunctions::validateInputAndCreateBuffer(context.get(), nullptr, flags, 0, g_scTestBufferSizeInBytes, pHostPtr, retVal);
EXPECT_EQ(retVal, CL_SUCCESS);
EXPECT_NE(nullptr, buffer);
clReleaseMemObject(buffer);
}
// Parameterized test that tests buffer creation with all flags that should be
// valid with a valid host ptr
cl_mem_flags ValidHostPtrFlags[] = {

View File

@ -0,0 +1,15 @@
#
# Copyright (C) 2022 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(UNIX)
set(IGDRCL_SRCS_tests_mem_obj_linux
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/buffer_linux_tests.cpp
)
target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_mem_obj_linux})
set_property(GLOBAL PROPERTY IGDRCL_SRCS_tests_mem_obj_linux ${IGDRCL_SRCS_tests_mem_obj_linux})
endif()

View File

@ -0,0 +1,121 @@
/*
* Copyright (C) 2018-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/helpers/array_count.h"
#include "shared/source/helpers/compiler_hw_info_config.h"
#include "shared/source/helpers/hw_helper.h"
#include "shared/source/memory_manager/memory_operations_handler.h"
#include "shared/source/memory_manager/unified_memory_manager.h"
#include "shared/test/common/fixtures/memory_management_fixture.h"
#include "shared/test/common/helpers/ult_hw_config.h"
#include "shared/test/common/helpers/unit_test_helper.h"
#include "shared/test/common/mocks/mock_allocation_properties.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/mocks/mock_gmm.h"
#include "shared/test/common/mocks/ult_device_factory.h"
#include "shared/test/common/test_macros/test.h"
#include "opencl/extensions/public/cl_ext_private.h"
#include "opencl/source/command_queue/command_queue_hw.h"
#include "opencl/source/mem_obj/mem_obj_helper.h"
#include "opencl/test/unit_test/fixtures/cl_device_fixture.h"
#include "opencl/test/unit_test/fixtures/multi_root_device_fixture.h"
#include "opencl/test/unit_test/mocks/mock_buffer.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
using namespace NEO;
static const unsigned int g_scTestBufferSizeInBytes = 16;
TEST(Buffer, GivenInvalidHandleTypeWhenValidateHandleTypeThenReturnFalse) {
MemoryProperties memoryProperties;
memoryProperties.handleType = 0;
UnifiedSharingMemoryDescription extMem;
bool isValid = Buffer::validateHandleType(memoryProperties, extMem);
EXPECT_FALSE(isValid);
}
TEST(Buffer, GivenLinuxFdHandleTypeWhenValidateHandleTypeThenReturnTrue) {
MemoryProperties memoryProperties;
memoryProperties.handleType = static_cast<uint64_t>(UnifiedSharingHandleType::LinuxFd);
UnifiedSharingMemoryDescription extMem;
bool isValid = Buffer::validateHandleType(memoryProperties, extMem);
EXPECT_TRUE(isValid);
}
class ExportBufferTests : public ClDeviceFixture,
public testing::Test {
public:
ExportBufferTests() {
}
protected:
void SetUp() override {
flags = CL_MEM_READ_WRITE;
ClDeviceFixture::SetUp();
context.reset(new MockContext(pClDevice));
}
void TearDown() override {
context.reset();
ClDeviceFixture::TearDown();
}
cl_int retVal = CL_SUCCESS;
std::unique_ptr<MockContext> context;
MemoryManager *contextMemoryManager;
cl_mem_flags flags = CL_MEM_READ_WRITE;
unsigned char pHostPtr[g_scTestBufferSizeInBytes];
};
struct ValidExportHostPtr
: public ExportBufferTests,
public MemoryManagementFixture {
typedef ExportBufferTests BaseClass;
using ExportBufferTests::SetUp;
using MemoryManagementFixture::SetUp;
ValidExportHostPtr() {
}
void SetUp() override {
MemoryManagementFixture::SetUp();
BaseClass::SetUp();
ASSERT_NE(nullptr, pDevice);
}
void TearDown() override {
delete buffer;
BaseClass::TearDown();
MemoryManagementFixture::TearDown();
}
Buffer *createBuffer() {
return Buffer::create(
context.get(),
flags,
g_scTestBufferSizeInBytes,
pHostPtr,
retVal);
}
cl_int retVal = CL_INVALID_VALUE;
Buffer *buffer = nullptr;
};
TEST_F(ValidExportHostPtr, givenPropertiesWithDmaBufWhenValidateInputAndCreateBufferThenCorrectBufferIsSet) {
cl_mem_properties properties[] = {CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR, 0x1234, 0};
auto buffer = BufferFunctions::validateInputAndCreateBuffer(context.get(), properties, flags, 0, g_scTestBufferSizeInBytes, nullptr, retVal);
EXPECT_EQ(retVal, CL_SUCCESS);
EXPECT_NE(nullptr, buffer);
clReleaseMemObject(buffer);
}

View File

@ -0,0 +1,15 @@
#
# Copyright (C) 2022 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(WIN32)
set(IGDRCL_SRCS_tests_mem_obj_windows
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/buffer_windows_tests.cpp
)
target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_mem_obj_windows})
set_property(GLOBAL PROPERTY IGDRCL_SRCS_tests_mem_obj_windows ${IGDRCL_SRCS_tests_mem_obj_windows})
endif()

View File

@ -0,0 +1,112 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/helpers/array_count.h"
#include "shared/source/helpers/compiler_hw_info_config.h"
#include "shared/source/helpers/hw_helper.h"
#include "shared/source/memory_manager/memory_operations_handler.h"
#include "shared/source/memory_manager/unified_memory_manager.h"
#include "shared/test/common/fixtures/memory_management_fixture.h"
#include "shared/test/common/helpers/ult_hw_config.h"
#include "shared/test/common/helpers/unit_test_helper.h"
#include "shared/test/common/mocks/mock_allocation_properties.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/mocks/mock_gmm.h"
#include "shared/test/common/mocks/ult_device_factory.h"
#include "shared/test/common/test_macros/test.h"
#include "opencl/extensions/public/cl_ext_private.h"
#include "opencl/source/command_queue/command_queue_hw.h"
#include "opencl/source/mem_obj/mem_obj_helper.h"
#include "opencl/test/unit_test/fixtures/cl_device_fixture.h"
#include "opencl/test/unit_test/fixtures/multi_root_device_fixture.h"
#include "opencl/test/unit_test/mocks/mock_buffer.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
using namespace NEO;
static const unsigned int g_scTestBufferSizeInBytes = 16;
TEST(Buffer, WhenValidateHandleTypeThenReturnFalse) {
MemoryProperties memoryProperties;
UnifiedSharingMemoryDescription extMem;
bool isValid = Buffer::validateHandleType(memoryProperties, extMem);
EXPECT_FALSE(isValid);
}
class ExportBufferTests : public ClDeviceFixture,
public testing::Test {
public:
ExportBufferTests() {
}
protected:
void SetUp() override {
flags = CL_MEM_READ_WRITE;
ClDeviceFixture::SetUp();
context.reset(new MockContext(pClDevice));
}
void TearDown() override {
context.reset();
ClDeviceFixture::TearDown();
}
cl_int retVal = CL_SUCCESS;
std::unique_ptr<MockContext> context;
MemoryManager *contextMemoryManager;
cl_mem_flags flags = CL_MEM_READ_WRITE;
unsigned char pHostPtr[g_scTestBufferSizeInBytes];
};
struct ValidExportHostPtr
: public ExportBufferTests,
public MemoryManagementFixture {
typedef ExportBufferTests BaseClass;
using ExportBufferTests::SetUp;
using MemoryManagementFixture::SetUp;
ValidExportHostPtr() {
}
void SetUp() override {
MemoryManagementFixture::SetUp();
BaseClass::SetUp();
ASSERT_NE(nullptr, pDevice);
}
void TearDown() override {
delete buffer;
BaseClass::TearDown();
MemoryManagementFixture::TearDown();
}
Buffer *createBuffer() {
return Buffer::create(
context.get(),
flags,
g_scTestBufferSizeInBytes,
pHostPtr,
retVal);
}
cl_int retVal = CL_INVALID_VALUE;
Buffer *buffer = nullptr;
};
TEST_F(ValidExportHostPtr, givenPropertiesWithDmaBufWhenValidateInputAndCreateBufferThenCorrectBufferIsSet) {
cl_mem_properties properties[] = {CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR, 0x1234, 0};
auto buffer = BufferFunctions::validateInputAndCreateBuffer(context.get(), properties, flags, 0, g_scTestBufferSizeInBytes, nullptr, retVal);
EXPECT_EQ(retVal, CL_INVALID_PROPERTY);
EXPECT_EQ(nullptr, buffer);
clReleaseMemObject(buffer);
}

View File

@ -13,6 +13,9 @@ namespace NEO {
class Device;
struct MemoryProperties {
uint64_t handle = 0;
uint64_t handleType = 0;
uintptr_t hostptr = 0;
const Device *pDevice = nullptr;
uint32_t memCacheClos = 0;
union {
@ -23,7 +26,6 @@ struct MemoryProperties {
MemoryAllocFlags allocFlags;
uint32_t allAllocFlags = 0;
};
uintptr_t hostptr = 0;
static_assert(sizeof(MemoryProperties::flags) == sizeof(MemoryProperties::allFlags) && sizeof(MemoryProperties::allocFlags) == sizeof(MemoryProperties::allAllocFlags), "");
};
} // namespace NEO