Skip to content

Commit 9f9bf38

Browse files
Jaime ArteagaCompute-Runtime-Automation
authored andcommitted
Copy user buffers when not accepted by Kernel
When performing copy operations to or from buffers allocated by the user, it could happen that the buffer address is not accepted by kernel, even though the buffer is valid. In those ocassions, then allocate a new graphics allocation and copy the user buffer. Change-Id: I6b1b6f2ef5fea0acf32c868bc87eafe8746f9a79 Signed-off: Jaime Arteaga <jaime.a.arteaga.molina@intel.com>
1 parent 38dc396 commit 9f9bf38

File tree

5 files changed

+90
-9
lines changed

5 files changed

+90
-9
lines changed

level_zero/core/source/device/device_imp.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -735,12 +735,18 @@ NEO::GraphicsAllocation *DeviceImp::allocateManagedMemoryFromHostPtr(void *buffe
735735
}
736736

737737
NEO::GraphicsAllocation *DeviceImp::allocateMemoryFromHostPtr(const void *buffer, size_t size) {
738-
NEO::AllocationProperties properties = {getRootDeviceIndex(), false, size, NEO::GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR, false, neoDevice->getDeviceBitfield()};
738+
NEO::AllocationProperties properties = {getRootDeviceIndex(), false, size,
739+
NEO::GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR,
740+
false, neoDevice->getDeviceBitfield()};
739741
properties.flags.flushL3RequiredForRead = properties.flags.flushL3RequiredForWrite = true;
740742
auto allocation = neoDevice->getMemoryManager()->allocateGraphicsMemoryWithProperties(properties,
741743
buffer);
742-
743-
UNRECOVERABLE_IF(allocation == nullptr);
744+
if (allocation == nullptr) {
745+
allocation = neoDevice->getMemoryManager()->allocateInternalGraphicsMemoryWithHostCopy(neoDevice->getRootDeviceIndex(),
746+
neoDevice->getDeviceBitfield(),
747+
buffer,
748+
size);
749+
}
744750

745751
return allocation;
746752
}

level_zero/core/test/unit_tests/sources/device/test_device.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,65 @@ TEST_F(DeviceTest, givenEmptySVmAllocStorageWhenAllocateMemoryFromHostPtrThenVal
9090
neoDevice->getMemoryManager()->freeGraphicsMemory(allocation);
9191
}
9292

93+
struct MemoryManagerHostPointer : public NEO::OsAgnosticMemoryManager {
94+
MemoryManagerHostPointer(NEO::ExecutionEnvironment &executionEnvironment) : OsAgnosticMemoryManager(const_cast<NEO::ExecutionEnvironment &>(executionEnvironment)) {}
95+
GraphicsAllocation *allocateGraphicsMemoryWithProperties(const AllocationProperties &properties,
96+
const void *ptr) override {
97+
return nullptr;
98+
}
99+
};
100+
101+
struct DeviceHostPointerTest : public ::testing::Test {
102+
void SetUp() override {
103+
executionEnvironment = new NEO::ExecutionEnvironment();
104+
executionEnvironment->prepareRootDeviceEnvironments(numRootDevices);
105+
for (uint32_t i = 0; i < numRootDevices; i++) {
106+
executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(NEO::defaultHwInfo.get());
107+
}
108+
109+
memoryManager = new MemoryManagerHostPointer(*executionEnvironment);
110+
executionEnvironment->memoryManager.reset(memoryManager);
111+
112+
neoDevice = NEO::MockDevice::create<NEO::MockDevice>(executionEnvironment, rootDeviceIndex);
113+
std::vector<std::unique_ptr<NEO::Device>> devices;
114+
devices.push_back(std::unique_ptr<NEO::Device>(neoDevice));
115+
116+
driverHandle = std::make_unique<Mock<L0::DriverHandleImp>>();
117+
driverHandle->initialize(std::move(devices));
118+
119+
device = driverHandle->devices[0];
120+
}
121+
void TearDown() override {
122+
}
123+
124+
NEO::ExecutionEnvironment *executionEnvironment = nullptr;
125+
std::unique_ptr<Mock<L0::DriverHandleImp>> driverHandle;
126+
NEO::MockDevice *neoDevice = nullptr;
127+
L0::Device *device = nullptr;
128+
MemoryManagerHostPointer *memoryManager = nullptr;
129+
const uint32_t rootDeviceIndex = 1u;
130+
const uint32_t numRootDevices = 2u;
131+
};
132+
133+
TEST_F(DeviceHostPointerTest, givenHostPointerNotAcceptedByKernelThenNewAllocationIsCreatedAndHostPointerCopied) {
134+
size_t size = 55;
135+
uint64_t *buffer = new uint64_t[size];
136+
for (uint32_t i = 0; i < size; i++) {
137+
buffer[i] = i + 10;
138+
}
139+
140+
auto allocation = device->allocateMemoryFromHostPtr(buffer, size);
141+
EXPECT_NE(nullptr, allocation);
142+
EXPECT_EQ(NEO::GraphicsAllocation::AllocationType::INTERNAL_HOST_MEMORY, allocation->getAllocationType());
143+
EXPECT_EQ(rootDeviceIndex, allocation->getRootDeviceIndex());
144+
EXPECT_NE(allocation->getUnderlyingBuffer(), reinterpret_cast<void *>(buffer));
145+
EXPECT_EQ(allocation->getUnderlyingBufferSize(), size);
146+
EXPECT_EQ(0, memcmp(buffer, allocation->getUnderlyingBuffer(), size));
147+
148+
neoDevice->getMemoryManager()->freeGraphicsMemory(allocation);
149+
delete[] buffer;
150+
}
151+
93152
TEST_F(DeviceTest, givenKernelPropertiesStructureWhenKernelPropertiesCalledThenAllPropertiesAreAssigned) {
94153
const auto &hardwareInfo = this->neoDevice->getHardwareInfo();
95154

shared/source/command_stream/command_stream_receiver.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,10 @@ bool CommandStreamReceiver::createAllocationForHostSurface(HostPtrSurface &surfa
483483
allocation.reset(memoryManager->allocateGraphicsMemoryWithProperties(properties, surface.getMemoryPointer()));
484484
if (allocation == nullptr && surface.peekIsPtrCopyAllowed()) {
485485
// Try with no host pointer allocation and copy
486-
AllocationProperties copyProperties{rootDeviceIndex, surface.getSurfaceSize(), GraphicsAllocation::AllocationType::INTERNAL_HOST_MEMORY, internalAllocationStorage->getDeviceBitfield()};
487-
copyProperties.alignment = MemoryConstants::pageSize;
488-
allocation.reset(memoryManager->allocateGraphicsMemoryWithProperties(copyProperties));
489-
if (allocation) {
490-
memcpy_s(allocation->getUnderlyingBuffer(), allocation->getUnderlyingBufferSize(), surface.getMemoryPointer(), surface.getSurfaceSize());
491-
}
486+
allocation.reset(memoryManager->allocateInternalGraphicsMemoryWithHostCopy(rootDeviceIndex,
487+
internalAllocationStorage->getDeviceBitfield(),
488+
surface.getMemoryPointer(),
489+
surface.getSurfaceSize()));
492490
}
493491
}
494492

shared/source/memory_manager/memory_manager.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,22 @@ GraphicsAllocation *MemoryManager::allocateGraphicsMemoryInPreferredPool(const A
422422
return allocation;
423423
}
424424

425+
GraphicsAllocation *MemoryManager::allocateInternalGraphicsMemoryWithHostCopy(uint32_t rootDeviceIndex,
426+
DeviceBitfield bitField,
427+
const void *ptr,
428+
size_t size) {
429+
NEO::AllocationProperties copyProperties{rootDeviceIndex,
430+
size,
431+
NEO::GraphicsAllocation::AllocationType::INTERNAL_HOST_MEMORY,
432+
bitField};
433+
copyProperties.alignment = MemoryConstants::pageSize;
434+
auto allocation = this->allocateGraphicsMemoryWithProperties(copyProperties);
435+
if (allocation) {
436+
memcpy_s(allocation->getUnderlyingBuffer(), allocation->getUnderlyingBufferSize(), ptr, size);
437+
}
438+
return allocation;
439+
}
440+
425441
bool MemoryManager::mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) {
426442
auto index = graphicsAllocation->getRootDeviceIndex();
427443
if (executionEnvironment.rootDeviceEnvironments[index]->pageTableManager.get()) {

shared/source/memory_manager/memory_manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class MemoryManager {
7676
return allocateGraphicsMemoryInPreferredPool(properties, ptr);
7777
}
7878

79+
GraphicsAllocation *allocateInternalGraphicsMemoryWithHostCopy(uint32_t rootDeviceIndex, DeviceBitfield bitField, const void *ptr, size_t size);
80+
7981
MOCKABLE_VIRTUAL GraphicsAllocation *allocateGraphicsMemoryInPreferredPool(const AllocationProperties &properties, const void *hostPtr);
8082

8183
virtual bool verifyHandle(osHandle handle, uint32_t rootDeviceIndex, bool) { return true; }

0 commit comments

Comments
 (0)