From 2bb64b2d1153bff1dccdf65022308928ec1a1e5a Mon Sep 17 00:00:00 2001 From: "Mrozek, Michal" Date: Thu, 8 Mar 2018 11:56:44 +0100 Subject: [PATCH] [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 --- runtime/device/device.cpp | 4 +-- runtime/program/kernel_info.h | 5 +++- runtime/program/process_gen_binary.cpp | 18 ++++++++--- runtime/program/program.cpp | 25 ++++++++++++---- runtime/program/program.h | 5 ++-- unit_tests/fixtures/kernel_data_fixture.cpp | 12 +++++++- unit_tests/fixtures/kernel_data_fixture.h | 6 +++- unit_tests/gtpin/gtpin_tests.cpp | 32 +++++++++++--------- unit_tests/program/program_tests.cpp | 33 ++++++++++++++++----- 9 files changed, 102 insertions(+), 38 deletions(-) diff --git a/runtime/device/device.cpp b/runtime/device/device.cpp index 5388b5e7e4..ea61f44f8c 100644 --- a/runtime/device/device.cpp +++ b/runtime/device/device.cpp @@ -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, diff --git a/runtime/program/kernel_info.h b/runtime/program/kernel_info.h index a806e3d6aa..df4c7fa151 100644 --- a/runtime/program/kernel_info.h +++ b/runtime/program/kernel_info.h @@ -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 accessQualifierMap; extern std::unordered_map 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 diff --git a/runtime/program/process_gen_binary.cpp b/runtime/program/process_gen_binary.cpp index 57e6de90aa..7ecb9b6077 100644 --- a/runtime/program/process_gen_binary.cpp +++ b/runtime/program/process_gen_binary.cpp @@ -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) { diff --git a/runtime/program/program.cpp b/runtime/program/program.cpp index 8dc7f04c17..39621acaff 100644 --- a/runtime/program/program.cpp +++ b/runtime/program/program.cpp @@ -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); diff --git a/runtime/program/program.h b/runtime/program/program.h index f9856e35a7..e8d73039c0 100644 --- a/runtime/program/program.h +++ b/runtime/program/program.h @@ -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; } diff --git a/unit_tests/fixtures/kernel_data_fixture.cpp b/unit_tests/fixtures/kernel_data_fixture.cpp index 1fa7fb625e..671eb8bec6 100644 --- a/unit_tests/fixtures/kernel_data_fixture.cpp +++ b/unit_tests/fixtures/kernel_data_fixture.cpp @@ -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()); + } } diff --git a/unit_tests/fixtures/kernel_data_fixture.h b/unit_tests/fixtures/kernel_data_fixture.h index ea48578a0b..86f5dab279 100644 --- a/unit_tests/fixtures/kernel_data_fixture.h +++ b/unit_tests/fixtures/kernel_data_fixture.h @@ -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(pKernelInfo)->kernelAllocation = nullptr; + } delete pDevice; alignedFree(pKernelData); } diff --git a/unit_tests/gtpin/gtpin_tests.cpp b/unit_tests/gtpin/gtpin_tests.cpp index 4e58524611..e986ca5408 100644 --- a/unit_tests/gtpin/gtpin_tests.cpp +++ b/unit_tests/gtpin/gtpin_tests.cpp @@ -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); diff --git a/unit_tests/program/program_tests.cpp b/unit_tests/program/program_tests.cpp index ec871d0b87..0cba5f5636 100644 --- a/unit_tests/program/program_tests.cpp +++ b/unit_tests/program/program_tests.cpp @@ -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;