[11/n] Allocate graphics allocations during processKernel.

- This ensures each kernel has ISH set up after it is created.
- refactor freeBlockPrivateSurfaces to freeBlockResources, this is to properly
clean allocations for blocks
- Add method cleanCurrentKernelInfo to avoid code duplication in KernelInfo
cleanup

Change-Id: I01f155d434579fe5ce2675bc4e89b04628ef8158
This commit is contained in:
Mrozek, Michal
2018-03-08 11:56:44 +01:00
parent 8d5e099aa3
commit 2bb64b2d11
9 changed files with 102 additions and 38 deletions

View File

@ -86,6 +86,8 @@ Device::Device(const HardwareInfo &hwInfo,
}
Device::~Device() {
BuiltIns::shutDown();
CompilerInterface::shutdown();
DEBUG_BREAK_IF(nullptr == memoryManager);
if (performanceCounters) {
performanceCounters->shutdown();
@ -105,8 +107,6 @@ Device::~Device() {
tagAllocation = nullptr;
delete memoryManager;
memoryManager = nullptr;
BuiltIns::shutDown();
CompilerInterface::shutdown();
}
bool Device::createDeviceImpl(const HardwareInfo *pHwInfo,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2017 - 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -42,6 +42,7 @@ class Kernel;
struct KernelInfo;
class DispatchInfo;
struct KernelArgumentType;
class GraphicsAllocation;
extern std::unordered_map<std::string, uint32_t> accessQualifierMap;
extern std::unordered_map<std::string, uint32_t> addressQualifierMap;
@ -152,6 +153,7 @@ struct KernelInfo {
void storePatchToken(const SPatchAllocateStatelessDefaultDeviceQueueSurface *pStatelessDefaultDeviceQueueSurfaceArg);
void storePatchToken(const SPatchString *pStringArg);
void storePatchToken(const SPatchKernelAttributesInfo *pKernelAttributesInfo);
GraphicsAllocation *getGraphicsAllocation() const { return this->kernelAllocation; }
cl_int resolveKernelInfo();
void resizeKernelArgInfoAndRegisterParameter(uint32_t argCount) {
if (kernelArgInfo.size() <= argCount) {
@ -237,5 +239,6 @@ struct KernelInfo {
uint32_t systemKernelOffset = 0;
uint64_t kernelId = 0;
bool isKernelHeapSubstituted = false;
GraphicsAllocation *kernelAllocation = nullptr;
};
} // namespace OCLRT

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2017 - 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -795,6 +795,18 @@ cl_int Program::parsePatchList(KernelInfo &kernelInfo) {
}
}
if (kernelInfo.heapInfo.pKernelHeader->KernelHeapSize && this->pDevice) {
auto memoryManager = this->pDevice->getMemoryManager();
auto kernelIsaSize = kernelInfo.heapInfo.pKernelHeader->KernelHeapSize;
auto kernelAllocation = memoryManager->createInternalGraphicsAllocation(nullptr, kernelIsaSize);
if (kernelAllocation) {
memcpy_s(kernelAllocation->getUnderlyingBuffer(), kernelIsaSize, kernelInfo.heapInfo.pKernelHeap, kernelIsaSize);
kernelInfo.kernelAllocation = kernelAllocation;
} else {
retVal = CL_OUT_OF_HOST_MEMORY;
}
}
return retVal;
}
@ -923,9 +935,7 @@ cl_int Program::parseProgramScopePatchList() {
cl_int Program::processGenBinary() {
cl_int retVal = CL_SUCCESS;
for (auto &i : kernelInfoArray)
delete i;
kernelInfoArray.clear();
cleanCurrentKernelInfo();
do {
if (!genBinary || genBinarySize == 0) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2017 - 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -113,11 +113,9 @@ Program::~Program() {
elfBinary = nullptr;
elfBinarySize = 0;
for (auto &i : kernelInfoArray) {
delete i;
}
cleanCurrentKernelInfo();
freeBlockPrivateSurfaces();
freeBlockResources();
delete blockKernelManager;
@ -393,7 +391,7 @@ void Program::allocateBlockPrivateSurfaces() {
}
}
void Program::freeBlockPrivateSurfaces() {
void Program::freeBlockResources() {
size_t blockCount = blockKernelManager->getCount();
for (uint32_t i = 0; i < blockCount; i++) {
@ -404,9 +402,24 @@ void Program::freeBlockPrivateSurfaces() {
blockKernelManager->pushPrivateSurface(nullptr, i);
getDevice(0).getMemoryManager()->freeGraphicsMemory(privateSurface);
}
auto kernelInfo = blockKernelManager->getBlockKernelInfo(i);
DEBUG_BREAK_IF(!kernelInfo->kernelAllocation);
if (kernelInfo->kernelAllocation) {
getDevice(0).getMemoryManager()->freeGraphicsMemory(kernelInfo->kernelAllocation);
}
}
}
void Program::cleanCurrentKernelInfo() {
for (auto &kernelInfo : kernelInfoArray) {
if (kernelInfo->kernelAllocation) {
this->pDevice->getMemoryManager()->freeGraphicsMemory(kernelInfo->kernelAllocation);
}
delete kernelInfo;
}
kernelInfoArray.clear();
}
void Program::updateNonUniformFlag() {
//Look for -cl-std=CL substring and extract value behind which can be 1.2 2.0 2.1 and convert to value
auto pos = options.find(clOptNameClVer);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2017 - 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -216,7 +216,8 @@ class Program : public BaseObject<_cl_program> {
}
void allocateBlockPrivateSurfaces();
void freeBlockPrivateSurfaces();
void freeBlockResources();
void cleanCurrentKernelInfo();
const std::string &getOptions() const { return options; }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2017 - 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -22,6 +22,7 @@
#include "runtime/helpers/aligned_memory.h"
#include "runtime/helpers/string.h"
#include "runtime/memory_manager/graphics_allocation.h"
#include "unit_tests/fixtures/kernel_data_fixture.h"
void KernelDataTest::buildAndDecode() {
@ -123,4 +124,13 @@ void KernelDataTest::buildAndDecode() {
if (pPatchList != nullptr) {
EXPECT_EQ(0, memcmp(pKernelInfo->heapInfo.pPatchList, pPatchList, patchListSize));
}
if (kernelHeapSize) {
auto kernelAllocation = pKernelInfo->getGraphicsAllocation();
UNRECOVERABLE_IF(kernelAllocation == nullptr);
EXPECT_EQ(kernelAllocation->getUnderlyingBufferSize(), kernelHeapSize);
auto kernelIsa = kernelAllocation->getUnderlyingBuffer();
EXPECT_EQ(0, memcmp(kernelIsa, pKernelInfo->heapInfo.pKernelHeap, kernelHeapSize));
} else {
EXPECT_EQ(nullptr, pKernelInfo->getGraphicsAllocation());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2017 - 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -67,6 +67,10 @@ class KernelDataTest : public testing::Test {
}
void TearDown() override {
if (pKernelInfo->kernelAllocation) {
pDevice->getMemoryManager()->freeGraphicsMemory(pKernelInfo->kernelAllocation);
const_cast<KernelInfo *>(pKernelInfo)->kernelAllocation = nullptr;
}
delete pDevice;
alignedFree(pKernelData);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2017 - 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -1854,20 +1854,24 @@ TEST_F(GTPinTests, givenInitializedGTPinInterfaceWhenLowMemoryConditionOccursThe
pProgram->storeGenBinary(&binary[0], binSize);
retVal = pProgram->processGenBinary();
EXPECT_EQ(CL_SUCCESS, retVal);
// Create kernels from program
cl_kernel kernels[2] = {0};
cl_uint numCreatedKernels = 0;
retVal = clCreateKernelsInProgram(pProgram, 0, &kernels[0], &numCreatedKernels);
if (nonfailingAllocation != failureIndex) {
EXPECT_EQ(nullptr, kernels[0]);
EXPECT_EQ(1u, numCreatedKernels);
if (retVal == CL_OUT_OF_HOST_MEMORY) {
auto nonFailingAlloc = nonfailingAllocation;
EXPECT_NE(nonFailingAlloc, failureIndex);
} else {
EXPECT_NE(nullptr, kernels[0]);
EXPECT_EQ(1u, numCreatedKernels);
clReleaseKernel(kernels[0]);
EXPECT_EQ(CL_SUCCESS, retVal);
// Create kernels from program
cl_kernel kernels[2] = {0};
cl_uint numCreatedKernels = 0;
retVal = clCreateKernelsInProgram(pProgram, 0, &kernels[0], &numCreatedKernels);
if (nonfailingAllocation != failureIndex) {
EXPECT_EQ(nullptr, kernels[0]);
EXPECT_EQ(1u, numCreatedKernels);
} else {
EXPECT_NE(nullptr, kernels[0]);
EXPECT_EQ(1u, numCreatedKernels);
clReleaseKernel(kernels[0]);
}
}
clReleaseProgram(pProgram);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Intel Corporation
* Copyright (c) 2017 - 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -601,10 +601,29 @@ TEST_P(ProgramFromBinaryTest, GetBuildInfo_GlobalVariableTotalSize) {
EXPECT_EQ(globalVarSize, 1024u);
}
////////////////////////////////////////////////////////////////////////////////
// Program::Create (from source)
////////////////////////////////////////////////////////////////////////////////
TEST_P(ProgramFromSourceTest, CreateWithSource_Simple) {}
TEST_P(ProgramFromBinaryTest, givenProgramWhenItIsBeingBuildThenItContainsGraphicsAllocationInKernelInfo) {
cl_device_id device = pDevice;
pProgram->build(1, &device, nullptr, nullptr, nullptr, true);
auto kernelInfo = pProgram->getKernelInfo(size_t(0));
auto graphicsAllocation = kernelInfo->getGraphicsAllocation();
ASSERT_NE(nullptr, graphicsAllocation);
EXPECT_TRUE(graphicsAllocation->is32BitAllocation);
EXPECT_EQ(graphicsAllocation->getUnderlyingBufferSize(), kernelInfo->heapInfo.pKernelHeader->KernelHeapSize);
auto kernelIsa = graphicsAllocation->getUnderlyingBuffer();
EXPECT_NE(kernelInfo->heapInfo.pKernelHeap, kernelIsa);
EXPECT_EQ(0, memcmp(kernelIsa, kernelInfo->heapInfo.pKernelHeap, kernelInfo->heapInfo.pKernelHeader->KernelHeapSize));
EXPECT_NE(0u, graphicsAllocation->gpuBaseAddress);
}
TEST_P(ProgramFromBinaryTest, givenProgramWhenCleanKernelInfoIsCalledThenKernelAllocationIsFreed) {
cl_device_id device = pDevice;
pProgram->build(1, &device, nullptr, nullptr, nullptr, true);
EXPECT_EQ(1u, pProgram->getNumKernels());
pProgram->cleanCurrentKernelInfo();
EXPECT_EQ(0u, pProgram->getNumKernels());
}
////////////////////////////////////////////////////////////////////////////////
// Program::Build (source)
@ -2562,7 +2581,7 @@ TEST_F(ProgramTests, GivenNonZeroPrivateSizeInBlockWhenAllocateBlockProvateSurfa
delete program;
}
TEST_F(ProgramTests, freeBlockPrivateSurfacesFreesGraphicsAllocationsFromBlockKernelManager) {
TEST_F(ProgramTests, givenProgramWithBlockKernelsWhenfreeBlockResourcesisCalledThenFreeGraphhicsAllocationsFromBlockKernelManagerIsCalled) {
MockProgram *program = new MockProgram(pContext, false);
uint32_t crossThreadOffsetBlock = 0;
@ -2585,7 +2604,7 @@ TEST_F(ProgramTests, freeBlockPrivateSurfacesFreesGraphicsAllocationsFromBlockKe
program->getBlockKernelManager()->pushPrivateSurface(privateSurface, 0);
program->freeBlockPrivateSurfaces();
program->freeBlockResources();
delete privateSurfaceBlock;
delete program;