From 29613a2b1a5305d966ed4866024eed2ed3575ac1 Mon Sep 17 00:00:00 2001 From: "Mrozek, Michal" Date: Wed, 4 Sep 2019 17:26:57 +0200 Subject: [PATCH] Allow to set shared system memory pointers in constant buffers. Change-Id: Ie2a811c0f50abf667df82517abf2291e00a18460 Signed-off-by: Mrozek, Michal --- runtime/api/api.cpp | 12 +++++++---- runtime/device/device.h | 3 +++ .../api/cl_unified_shared_memory_tests.inl | 20 ++++++++++++++++++ unit_tests/device/device_caps_tests.cpp | 2 ++ unit_tests/kernel/kernel_arg_svm_tests.cpp | 21 +++++++++++++++++++ 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/runtime/api/api.cpp b/runtime/api/api.cpp index 5d6af5001e..2375407618 100644 --- a/runtime/api/api.cpp +++ b/runtime/api/api.cpp @@ -4204,12 +4204,16 @@ cl_int CL_API_CALL clSetKernelArgSVMPointer(cl_kernel kernel, if (argValue != nullptr) { auto svmData = svmManager->getSVMAlloc(argValue); if (svmData == nullptr) { - retVal = CL_INVALID_ARG_VALUE; - TRACING_EXIT(clSetKernelArgSVMPointer, &retVal); - return retVal; + if (!pKernel->getDevice().areSharedSystemAllocationsAllowed()) { + retVal = CL_INVALID_ARG_VALUE; + TRACING_EXIT(clSetKernelArgSVMPointer, &retVal); + return retVal; + } + } else { + pSvmAlloc = svmData->gpuAllocation; } - pSvmAlloc = svmData->gpuAllocation; } + retVal = pKernel->setArgSvmAlloc(argIndex, const_cast(argValue), pSvmAlloc); TRACING_EXIT(clSetKernelArgSVMPointer, &retVal); return retVal; diff --git a/runtime/device/device.h b/runtime/device/device.h index ba6b16f002..578f8b67d8 100644 --- a/runtime/device/device.h +++ b/runtime/device/device.h @@ -93,6 +93,9 @@ class Device : public BaseObject<_cl_device_id> { bool isFullRangeSvm() const { return executionEnvironment->isFullRangeSvm(); } + bool areSharedSystemAllocationsAllowed() const { + return this->deviceInfo.sharedSystemMemCapabilities != 0u; + } protected: Device() = delete; diff --git a/unit_tests/api/cl_unified_shared_memory_tests.inl b/unit_tests/api/cl_unified_shared_memory_tests.inl index 9bd6b384c9..3b2c96d79e 100644 --- a/unit_tests/api/cl_unified_shared_memory_tests.inl +++ b/unit_tests/api/cl_unified_shared_memory_tests.inl @@ -5,6 +5,7 @@ * */ +#include "core/unit_tests/helpers/debug_manager_state_restore.h" #include "runtime/api/api.h" #include "runtime/memory_manager/unified_memory_manager.h" #include "unit_tests/mocks/mock_context.h" @@ -292,6 +293,25 @@ TEST(clUnifiedSharedMemoryTests, whenClSetKernelArgMemPointerINTELisCalledWithIn EXPECT_EQ(CL_INVALID_KERNEL, retVal); } +TEST(clUnifiedSharedMemoryTests, whenDeviceSupportSharedMemoryAllocationsAndSystemPointerIsPassedItIsProperlySetInKernel) { + DebugManagerStateRestore restorer; + DebugManager.flags.EnableSharedSystemUsmSupport.set(1u); + auto mockContext = std::make_unique(); + + MockKernelWithInternals mockKernel(*mockContext->getDevice(0u), mockContext.get(), true); + + auto systemPointer = reinterpret_cast(0xfeedbac); + + auto retVal = clSetKernelArgMemPointerINTEL(mockKernel.mockKernel, 0, systemPointer); + EXPECT_EQ(retVal, CL_SUCCESS); + + //check if cross thread is updated + auto crossThreadLocation = reinterpret_cast(ptrOffset(mockKernel.mockKernel->getCrossThreadData(), mockKernel.kernelInfo.kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset)); + auto systemAddress = reinterpret_cast(systemPointer); + + EXPECT_EQ(*crossThreadLocation, systemAddress); +} + TEST(clUnifiedSharedMemoryTests, whenClSetKernelArgMemPointerINTELisCalledWithValidUnifiedMemoryAllocationThenProperFieldsAreSet) { auto mockContext = std::make_unique(); cl_int retVal = CL_SUCCESS; diff --git a/unit_tests/device/device_caps_tests.cpp b/unit_tests/device/device_caps_tests.cpp index 3e7625fc74..db85935f64 100644 --- a/unit_tests/device/device_caps_tests.cpp +++ b/unit_tests/device/device_caps_tests.cpp @@ -857,11 +857,13 @@ TEST(DeviceGetCapsTest, givenUnifiedMemoryShardeSystemFlagWhenDeviceIsCreatedItC std::unique_ptr device(MockDevice::createWithNewExecutionEnvironment(platformDevices[0])); EXPECT_EQ(0u, device->getDeviceInfo().sharedSystemMemCapabilities); + EXPECT_FALSE(device->areSharedSystemAllocationsAllowed()); DebugManager.flags.EnableSharedSystemUsmSupport.set(1u); device.reset(MockDevice::createWithNewExecutionEnvironment(platformDevices[0])); cl_unified_shared_memory_capabilities_intel expectedProperties = CL_UNIFIED_SHARED_MEMORY_ACCESS_INTEL | CL_UNIFIED_SHARED_MEMORY_ATOMIC_ACCESS_INTEL | CL_UNIFIED_SHARED_MEMORY_CONCURRENT_ACCESS_INTEL | CL_UNIFIED_SHARED_MEMORY_CONCURRENT_ATOMIC_ACCESS_INTEL; EXPECT_EQ(expectedProperties, device->getDeviceInfo().sharedSystemMemCapabilities); + EXPECT_TRUE(device->areSharedSystemAllocationsAllowed()); } TEST(DeviceGetCapsTest, givenDeviceWithNullSourceLevelDebuggerWhenCapsAreInitializedThenSourceLevelDebuggerActiveIsSetToFalse) { diff --git a/unit_tests/kernel/kernel_arg_svm_tests.cpp b/unit_tests/kernel/kernel_arg_svm_tests.cpp index d406aeefc3..731c53e840 100644 --- a/unit_tests/kernel/kernel_arg_svm_tests.cpp +++ b/unit_tests/kernel/kernel_arg_svm_tests.cpp @@ -204,6 +204,27 @@ HWTEST_F(KernelArgSvmTest, givenOffsetedSvmPointerWhenSetArgSvmAllocIsCalledThen EXPECT_EQ(offsetedPtr, surfaceAddress); } +HWTEST_F(KernelArgSvmTest, givenDeviceSupportingSharedSystemAllocationsWhenSetArgSvmIsCalledWithSurfaceStateThenSizeIsMaxAndAddressIsProgrammed) { + this->pDevice->deviceInfo.sharedSystemMemCapabilities = CL_UNIFIED_SHARED_MEMORY_ACCESS_INTEL | CL_UNIFIED_SHARED_MEMORY_ATOMIC_ACCESS_INTEL | CL_UNIFIED_SHARED_MEMORY_CONCURRENT_ACCESS_INTEL | CL_UNIFIED_SHARED_MEMORY_CONCURRENT_ATOMIC_ACCESS_INTEL; + + auto systemPointer = reinterpret_cast(0xfeedbac); + pKernelInfo->usesSsh = true; + pKernelInfo->requiresSshForBuffers = true; + + pKernel->setArgSvmAlloc(0, systemPointer, nullptr); + + typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE; + auto surfaceState = reinterpret_cast( + ptrOffset(pKernel->getSurfaceStateHeap(), + pKernelInfo->kernelArgInfo[0].offsetHeap)); + + void *surfaceAddress = reinterpret_cast(surfaceState->getSurfaceBaseAddress()); + EXPECT_EQ(systemPointer, surfaceAddress); + EXPECT_EQ(128u, surfaceState->getWidth()); + EXPECT_EQ(2048u, surfaceState->getDepth()); + EXPECT_EQ(16384u, surfaceState->getHeight()); +} + TEST_F(KernelArgSvmTest, SetKernelArgImmediateInvalidArgValue) { auto retVal = pKernel->setArgImmediate(0, 256, nullptr); EXPECT_EQ(CL_INVALID_ARG_VALUE, retVal);