diff --git a/runtime/command_queue/enqueue_read_buffer.h b/runtime/command_queue/enqueue_read_buffer.h index 3d8006c515..8abc546059 100644 --- a/runtime/command_queue/enqueue_read_buffer.h +++ b/runtime/command_queue/enqueue_read_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2019 Intel Corporation + * Copyright (C) 2017-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -7,6 +7,7 @@ #pragma once #include "core/helpers/cache_policy.h" +#include "core/memory_manager/unified_memory_manager.h" #include "runtime/built_ins/built_ins.h" #include "runtime/command_queue/command_queue_hw.h" #include "runtime/command_queue/enqueue_common.h" @@ -69,6 +70,21 @@ cl_int CommandQueueHw::enqueueReadBuffer( GeneralSurface mapSurface; Surface *surfaces[] = {&bufferSurf, nullptr}; + //check if we are dealing with SVM pointer here for which we already have an allocation + if (!mapAllocation && this->getContext().getSVMAllocsManager()) { + auto svmEntry = this->getContext().getSVMAllocsManager()->getSVMAlloc(ptr); + if (svmEntry) { + if (svmEntry->memoryType == DEVICE_UNIFIED_MEMORY) { + return CL_INVALID_OPERATION; + } + if ((svmEntry->gpuAllocation->getGpuAddress() + svmEntry->size) < (castToUint64(ptr) + size)) { + return CL_INVALID_OPERATION; + } + + mapAllocation = svmEntry->cpuAllocation ? svmEntry->cpuAllocation : svmEntry->gpuAllocation; + } + } + if (mapAllocation) { surfaces[1] = &mapSurface; mapSurface.setGraphicsAllocation(mapAllocation); diff --git a/unit_tests/memory_manager/unified_memory_manager_tests.cpp b/unit_tests/memory_manager/unified_memory_manager_tests.cpp index 3297b28824..6290dbfec5 100644 --- a/unit_tests/memory_manager/unified_memory_manager_tests.cpp +++ b/unit_tests/memory_manager/unified_memory_manager_tests.cpp @@ -580,7 +580,7 @@ TEST_F(ShareableUnifiedMemoryManagerPropertiesTest, givenShareableUnifiedPropert svmManager->freeSVMAlloc(ptr); } -TEST(UnfiedSharedMemoryTransferCalls, givenHostUSMllocationWhenPointerIsUsedAsWriteBufferSourceThenUSMAllocationIsReused) { +TEST(UnfiedSharedMemoryTransferCalls, givenHostUSMllocationWhenPointerIsUsedForTransferCallsThenUSMAllocationIsReused) { MockContext mockContext; cl_context clContext = &mockContext; @@ -608,13 +608,18 @@ TEST(UnfiedSharedMemoryTransferCalls, givenHostUSMllocationWhenPointerIsUsedAsWr EXPECT_EQ(1u, svmAllocation->gpuAllocation->getTaskCount(osContextId)); + status = clEnqueueReadBuffer(commandQueue, buffer, false, 0u, 4096u, hostMemory, 0u, nullptr, nullptr); + ASSERT_EQ(CL_SUCCESS, status); + EXPECT_TRUE(temporaryAllocations.peekIsEmpty()); + EXPECT_EQ(2u, svmAllocation->gpuAllocation->getTaskCount(osContextId)); + status = clReleaseMemObject(buffer); ASSERT_EQ(CL_SUCCESS, status); status = clMemFreeINTEL(clContext, hostMemory); ASSERT_EQ(CL_SUCCESS, status); clReleaseCommandQueue(commandQueue); } -TEST(UnfiedSharedMemoryTransferCalls, givenDeviceUsmAllocationWhenItIsPassedToWriteBufferAsSourceThenErrorIsReturned) { +TEST(UnfiedSharedMemoryTransferCalls, givenDeviceUsmAllocationWhenPtrIsUsedForTransferCallsThenErrorIsReturned) { MockContext mockContext; cl_context clContext = &mockContext; @@ -633,6 +638,9 @@ TEST(UnfiedSharedMemoryTransferCalls, givenDeviceUsmAllocationWhenItIsPassedToWr status = clEnqueueWriteBuffer(commandQueue, buffer, false, 0u, 4096u, deviceMemory, 0u, nullptr, nullptr); EXPECT_EQ(CL_INVALID_OPERATION, status); + status = clEnqueueReadBuffer(commandQueue, buffer, false, 0u, 4096u, deviceMemory, 0u, nullptr, nullptr); + ASSERT_EQ(CL_INVALID_OPERATION, status); + status = clReleaseMemObject(buffer); ASSERT_EQ(CL_SUCCESS, status); status = clMemFreeINTEL(clContext, deviceMemory); @@ -640,7 +648,7 @@ TEST(UnfiedSharedMemoryTransferCalls, givenDeviceUsmAllocationWhenItIsPassedToWr clReleaseCommandQueue(commandQueue); } -TEST(UnfiedSharedMemoryTransferCalls, givenHostAllocationThatIsSmallerThenWriteBufferTranfserSizeWhenTransferCallIsEmittedThenErrorIsReturned) { +TEST(UnfiedSharedMemoryTransferCalls, givenHostAllocationThatIsSmallerThenTransferRequirementsThenErrorIsReturned) { MockContext mockContext; cl_context clContext = &mockContext; @@ -660,6 +668,9 @@ TEST(UnfiedSharedMemoryTransferCalls, givenHostAllocationThatIsSmallerThenWriteB status = clEnqueueWriteBuffer(commandQueue, buffer, false, 0u, 4096u, hostMemory, 0u, nullptr, nullptr); EXPECT_EQ(CL_INVALID_OPERATION, status); + status = clEnqueueReadBuffer(commandQueue, buffer, false, 0u, 4096u, hostMemory, 0u, nullptr, nullptr); + ASSERT_EQ(CL_INVALID_OPERATION, status); + status = clReleaseMemObject(buffer); ASSERT_EQ(CL_SUCCESS, status); status = clMemFreeINTEL(clContext, hostMemory); @@ -667,7 +678,7 @@ TEST(UnfiedSharedMemoryTransferCalls, givenHostAllocationThatIsSmallerThenWriteB clReleaseCommandQueue(commandQueue); } -TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithoutLocalMemoryWhenPointerIsUsedAsWriteBufferSourceThenUSMAllocationIsReused) { +TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithoutLocalMemoryWhenPointerIsUsedAsTranfserParameterThenUSMAllocationIsReused) { DebugManagerStateRestore restore; DebugManager.flags.EnableLocalMemory.set(0); @@ -697,6 +708,11 @@ TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithoutLocalMemoryW EXPECT_EQ(1u, svmAllocation->gpuAllocation->getTaskCount(osContextId)); + status = clEnqueueReadBuffer(commandQueue, buffer, false, 0u, 4096u, sharedMemory, 0u, nullptr, nullptr); + ASSERT_EQ(CL_SUCCESS, status); + EXPECT_TRUE(temporaryAllocations.peekIsEmpty()); + EXPECT_EQ(2u, svmAllocation->gpuAllocation->getTaskCount(osContextId)); + status = clReleaseMemObject(buffer); ASSERT_EQ(CL_SUCCESS, status); status = clMemFreeINTEL(clContext, sharedMemory); @@ -704,7 +720,7 @@ TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithoutLocalMemoryW clReleaseCommandQueue(commandQueue); } -TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithLocalMemoryWhenPointerIsUsedAsWriteBufferSourceThenUSMAllocationIsReused) { +TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithLocalMemoryWhenPointerIsUsedAsTransferParameterThenUSMAllocationIsReused) { DebugManagerStateRestore restore; DebugManager.flags.EnableLocalMemory.set(1); @@ -737,6 +753,11 @@ TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithLocalMemoryWhen EXPECT_EQ(2u, svmAllocation->cpuAllocation->getTaskCount(osContextId)); + status = clEnqueueReadBuffer(commandQueue, buffer, false, 0u, 4096u, sharedMemory, 0u, nullptr, nullptr); + ASSERT_EQ(CL_SUCCESS, status); + EXPECT_TRUE(temporaryAllocations.peekIsEmpty()); + EXPECT_EQ(3u, svmAllocation->cpuAllocation->getTaskCount(osContextId)); + status = clReleaseMemObject(buffer); ASSERT_EQ(CL_SUCCESS, status); status = clMemFreeINTEL(clContext, sharedMemory);