Skip to content

Commit 35b59b7

Browse files
committed
Reuse SVM storage on writeBuffer call.
- Instead of creating new allocation, look if it already exists if so re-use it. Change-Id: I23bc4ac8b8e59e96fce7d48546b76289bedc157f Signed-off-by: Michal Mrozek <[email protected]>
1 parent 0d7cc3a commit 35b59b7

File tree

3 files changed

+126
-2
lines changed

3 files changed

+126
-2
lines changed

Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!groovy
22
dependenciesRevision='31422303aeb91920dbad182d97ef610bf75b5599-1360'
33
strategy='EQUAL'
4-
allowedCD=259
4+
allowedCD=257
55
allowedF=11

runtime/command_queue/enqueue_write_buffer.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/*
2-
* Copyright (C) 2017-2019 Intel Corporation
2+
* Copyright (C) 2017-2020 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
66
*/
77

88
#pragma once
99
#include "core/helpers/string.h"
10+
#include "core/memory_manager/unified_memory_manager.h"
1011
#include "runtime/built_ins/built_ins.h"
1112
#include "runtime/command_queue/command_queue_hw.h"
1213
#include "runtime/command_stream/command_stream_receiver.h"
@@ -65,6 +66,14 @@ cl_int CommandQueueHw<GfxFamily>::enqueueWriteBuffer(
6566
GeneralSurface mapSurface;
6667
Surface *surfaces[] = {&bufferSurf, nullptr};
6768

69+
//check if we are dealing with SVM pointer here for which we already have an allocation
70+
if (!mapAllocation && this->getContext().getSVMAllocsManager()) {
71+
auto svmEntry = this->getContext().getSVMAllocsManager()->getSVMAlloc(ptr);
72+
if (svmEntry) {
73+
mapAllocation = svmEntry->cpuAllocation ? svmEntry->cpuAllocation : svmEntry->gpuAllocation;
74+
}
75+
}
76+
6877
if (mapAllocation) {
6978
surfaces[1] = &mapSurface;
7079
mapSurface.setGraphicsAllocation(mapAllocation);

unit_tests/memory_manager/unified_memory_manager_tests.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
*
66
*/
77

8+
#include "core/memory_manager/allocations_list.h"
89
#include "core/unit_tests/helpers/debug_manager_state_restore.h"
910
#include "core/unit_tests/page_fault_manager/mock_cpu_page_fault_manager.h"
11+
#include "runtime/api/api.h"
1012
#include "runtime/command_stream/command_stream_receiver.h"
1113
#include "runtime/mem_obj/mem_obj_helper.h"
1214
#include "test.h"
1315
#include "unit_tests/mocks/mock_command_queue.h"
16+
#include "unit_tests/mocks/mock_context.h"
1417
#include "unit_tests/mocks/mock_execution_environment.h"
1518
#include "unit_tests/mocks/mock_memory_manager.h"
1619
#include "unit_tests/mocks/mock_svm_manager.h"
@@ -576,3 +579,115 @@ TEST_F(ShareableUnifiedMemoryManagerPropertiesTest, givenShareableUnifiedPropert
576579
EXPECT_TRUE(memoryManager->shareablePassed);
577580
svmManager->freeSVMAlloc(ptr);
578581
}
582+
583+
TEST(UnfiedSharedMemoryTransferCalls, givenHostUSMllocationWhenPointerIsUsedAsWriteBufferSourceThenUSMAllocationIsReused) {
584+
MockContext mockContext;
585+
cl_context clContext = &mockContext;
586+
587+
auto status = CL_SUCCESS;
588+
589+
auto hostMemory = clHostMemAllocINTEL(clContext, nullptr, 4096u, 0u, &status);
590+
auto svmAllocation = mockContext.getSVMAllocsManager()->getSVMAlloc(hostMemory);
591+
592+
ASSERT_EQ(CL_SUCCESS, status);
593+
auto buffer = clCreateBuffer(clContext, CL_MEM_READ_WRITE, 4096u, nullptr, &status);
594+
ASSERT_EQ(CL_SUCCESS, status);
595+
596+
cl_device_id clDevice = mockContext.getDevice(0u);
597+
598+
auto commandQueue = clCreateCommandQueue(clContext, clDevice, 0u, &status);
599+
ASSERT_EQ(CL_SUCCESS, status);
600+
601+
status = clEnqueueWriteBuffer(commandQueue, buffer, false, 0u, 4096u, hostMemory, 0u, nullptr, nullptr);
602+
ASSERT_EQ(CL_SUCCESS, status);
603+
604+
auto neoQueue = castToObject<CommandQueue>(commandQueue);
605+
auto &temporaryAllocations = neoQueue->getGpgpuCommandStreamReceiver().getTemporaryAllocations();
606+
EXPECT_TRUE(temporaryAllocations.peekIsEmpty());
607+
auto osContextId = neoQueue->getGpgpuCommandStreamReceiver().getOsContext().getContextId();
608+
609+
EXPECT_EQ(1u, svmAllocation->gpuAllocation->getTaskCount(osContextId));
610+
611+
status = clReleaseMemObject(buffer);
612+
ASSERT_EQ(CL_SUCCESS, status);
613+
status = clMemFreeINTEL(clContext, hostMemory);
614+
ASSERT_EQ(CL_SUCCESS, status);
615+
clReleaseCommandQueue(commandQueue);
616+
}
617+
618+
TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithoutLocalMemoryWhenPointerIsUsedAsWriteBufferSourceThenUSMAllocationIsReused) {
619+
DebugManagerStateRestore restore;
620+
DebugManager.flags.EnableLocalMemory.set(0);
621+
622+
MockContext mockContext;
623+
cl_context clContext = &mockContext;
624+
cl_device_id clDevice = mockContext.getDevice(0u);
625+
626+
auto status = CL_SUCCESS;
627+
628+
auto sharedMemory = clSharedMemAllocINTEL(clContext, clDevice, nullptr, 4096u, 0u, &status);
629+
auto svmAllocation = mockContext.getSVMAllocsManager()->getSVMAlloc(sharedMemory);
630+
631+
ASSERT_EQ(CL_SUCCESS, status);
632+
auto buffer = clCreateBuffer(clContext, CL_MEM_READ_WRITE, 4096u, nullptr, &status);
633+
ASSERT_EQ(CL_SUCCESS, status);
634+
635+
auto commandQueue = clCreateCommandQueue(clContext, clDevice, 0u, &status);
636+
ASSERT_EQ(CL_SUCCESS, status);
637+
638+
status = clEnqueueWriteBuffer(commandQueue, buffer, false, 0u, 4096u, sharedMemory, 0u, nullptr, nullptr);
639+
ASSERT_EQ(CL_SUCCESS, status);
640+
641+
auto neoQueue = castToObject<CommandQueue>(commandQueue);
642+
auto &temporaryAllocations = neoQueue->getGpgpuCommandStreamReceiver().getTemporaryAllocations();
643+
EXPECT_TRUE(temporaryAllocations.peekIsEmpty());
644+
auto osContextId = neoQueue->getGpgpuCommandStreamReceiver().getOsContext().getContextId();
645+
646+
EXPECT_EQ(1u, svmAllocation->gpuAllocation->getTaskCount(osContextId));
647+
648+
status = clReleaseMemObject(buffer);
649+
ASSERT_EQ(CL_SUCCESS, status);
650+
status = clMemFreeINTEL(clContext, sharedMemory);
651+
ASSERT_EQ(CL_SUCCESS, status);
652+
clReleaseCommandQueue(commandQueue);
653+
}
654+
655+
TEST(UnfiedSharedMemoryTransferCalls, givenSharedUSMllocationWithLocalMemoryWhenPointerIsUsedAsWriteBufferSourceThenUSMAllocationIsReused) {
656+
DebugManagerStateRestore restore;
657+
DebugManager.flags.EnableLocalMemory.set(1);
658+
659+
MockContext mockContext;
660+
cl_context clContext = &mockContext;
661+
cl_device_id clDevice = mockContext.getDevice(0u);
662+
663+
auto status = CL_SUCCESS;
664+
665+
auto sharedMemory = clSharedMemAllocINTEL(clContext, clDevice, nullptr, 4096u, 0u, &status);
666+
auto svmAllocation = mockContext.getSVMAllocsManager()->getSVMAlloc(sharedMemory);
667+
668+
ASSERT_EQ(CL_SUCCESS, status);
669+
auto buffer = clCreateBuffer(clContext, CL_MEM_READ_WRITE, 4096u, nullptr, &status);
670+
ASSERT_EQ(CL_SUCCESS, status);
671+
672+
auto commandQueue = clCreateCommandQueue(clContext, clDevice, 0u, &status);
673+
ASSERT_EQ(CL_SUCCESS, status);
674+
675+
auto neoQueue = castToObject<CommandQueue>(commandQueue);
676+
auto osContextId = neoQueue->getGpgpuCommandStreamReceiver().getOsContext().getContextId();
677+
678+
EXPECT_EQ(1u, svmAllocation->cpuAllocation->getTaskCount(osContextId));
679+
680+
status = clEnqueueWriteBuffer(commandQueue, buffer, false, 0u, 4096u, sharedMemory, 0u, nullptr, nullptr);
681+
ASSERT_EQ(CL_SUCCESS, status);
682+
683+
auto &temporaryAllocations = neoQueue->getGpgpuCommandStreamReceiver().getTemporaryAllocations();
684+
EXPECT_TRUE(temporaryAllocations.peekIsEmpty());
685+
686+
EXPECT_EQ(2u, svmAllocation->cpuAllocation->getTaskCount(osContextId));
687+
688+
status = clReleaseMemObject(buffer);
689+
ASSERT_EQ(CL_SUCCESS, status);
690+
status = clMemFreeINTEL(clContext, sharedMemory);
691+
ASSERT_EQ(CL_SUCCESS, status);
692+
clReleaseCommandQueue(commandQueue);
693+
}

0 commit comments

Comments
 (0)