fix(ocl zebin): do not expose functions as kernel

Do not expose dummy kernel containing functions' ISAs as kernels.

Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
Krystian Chmielewski
2022-11-25 11:35:36 +00:00
committed by Compute-Runtime-Automation
parent 4981b3e0d2
commit 359b9278b8
6 changed files with 93 additions and 10 deletions

View File

@ -38,6 +38,10 @@ const KernelInfo *Program::getKernelInfo(
return nullptr;
}
if (kernelName == NEO::Elf::SectionsNamesZebin::externalFunctions) {
return nullptr;
}
auto &kernelInfoArray = buildInfos[rootDeviceIndex].kernelInfoArray;
auto it = std::find_if(kernelInfoArray.begin(), kernelInfoArray.end(),
@ -47,11 +51,19 @@ const KernelInfo *Program::getKernelInfo(
}
size_t Program::getNumKernels() const {
return buildInfos[clDevices[0]->getRootDeviceIndex()].kernelInfoArray.size();
auto numKernels = buildInfos[clDevices[0]->getRootDeviceIndex()].kernelInfoArray.size();
auto usesExportedFunctions = (exportedFunctionsKernelId != std::numeric_limits<size_t>::max());
if (usesExportedFunctions) {
numKernels--;
}
return numKernels;
}
const KernelInfo *Program::getKernelInfo(size_t ordinal, uint32_t rootDeviceIndex) const {
auto &kernelInfoArray = buildInfos[rootDeviceIndex].kernelInfoArray;
if (exportedFunctionsKernelId == ordinal) {
ordinal++;
}
DEBUG_BREAK_IF(ordinal >= kernelInfoArray.size());
return kernelInfoArray[ordinal];
}
@ -85,6 +97,7 @@ cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, size_
strings.segmentSize = stringsInfo.size;
}
if (linkerInput->getExportedFunctionsSegmentId() >= 0) {
exportedFunctionsKernelId = static_cast<size_t>(linkerInput->getExportedFunctionsSegmentId());
// Exported functions reside in instruction heap of one of kernels
auto exportedFunctionHeapId = linkerInput->getExportedFunctionsSegmentId();
buildInfos[rootDeviceIndex].exportedFunctionsSurface = kernelInfoArray[exportedFunctionHeapId]->getGraphicsAllocation();

View File

@ -370,6 +370,8 @@ class Program : public BaseObject<_cl_program> {
std::mutex lockMutex;
uint32_t exposedKernels = 0;
size_t exportedFunctionsKernelId = std::numeric_limits<size_t>::max();
std::once_flag extractAndDecodeMetadataOnce;
};

View File

@ -8,6 +8,7 @@
#include "opencl/test/unit_test/fixtures/program_fixture.h"
#include "opencl/source/program/create.inl"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "opencl/test/unit_test/mocks/mock_program.h"
namespace NEO {
@ -40,6 +41,13 @@ void ProgramFixture::createProgramWithSource(Context *pContext,
ASSERT_EQ(CL_SUCCESS, retVal);
}
void ProgramFixture::cleanup() {
if (pProgram != nullptr) {
pProgram->release();
}
knownSource.reset();
}
void ProgramFixture::createProgramFromBinary(Context *pContext,
const ClDeviceVector &deviceVector,
const std::string &binaryFileName,
@ -83,4 +91,14 @@ void ProgramFixture::createProgramFromBinary(Context *pContext,
ASSERT_EQ(CL_SUCCESS, retVal);
}
NEOProgramFixture::NEOProgramFixture() = default;
NEOProgramFixture::~NEOProgramFixture() = default;
void NEOProgramFixture::setUp() {
context = std::make_unique<MockContext>();
program = std::make_unique<MockNeoProgram>(context.get(), false, context->getDevices());
}
void NEOProgramFixture::tearDown() {}
} // namespace NEO

View File

@ -9,12 +9,31 @@
#include "shared/source/helpers/file_io.h"
#include "shared/test/common/helpers/test_files.h"
#include "opencl/source/program/program.h"
#include "opencl/test/unit_test/mocks/mock_program.h"
#include "gtest/gtest.h"
#include <memory>
#include <string>
namespace NEO {
class Context;
class ClDeviceVector;
class MockContext;
class MockProgram;
class ClDevice;
class MockNeoProgram;
using cl_int = int;
class NEOProgramFixture {
public:
NEOProgramFixture();
~NEOProgramFixture();
protected:
void setUp();
void tearDown();
std::unique_ptr<MockContext> context;
std::unique_ptr<MockNeoProgram> program;
};
class ProgramFixture {
public:
@ -40,12 +59,7 @@ class ProgramFixture {
cleanup();
}
void cleanup() {
if (pProgram != nullptr) {
pProgram->release();
}
knownSource.reset();
}
void cleanup();
MockProgram *pProgram = nullptr;
std::unique_ptr<char[]> knownSource;

View File

@ -25,6 +25,23 @@ ClDeviceVector toClDeviceVector(ClDevice &clDevice);
////////////////////////////////////////////////////////////////////////////////
// Program - Core implementation
////////////////////////////////////////////////////////////////////////////////
class MockNeoProgram : public NEO::Program {
public:
using Base = NEO::Program;
using Base::buildInfos;
using Base::exportedFunctionsKernelId;
MockNeoProgram(NEO::Context *context, bool isBuiltIn, const NEO::ClDeviceVector &devices)
: NEO::Program(context, isBuiltIn, devices) {}
void resizeAndPopulateKernelInfoArray(size_t size) {
buildInfos[0].kernelInfoArray.resize(size);
for (auto &entry : buildInfos[0].kernelInfoArray) {
entry = new KernelInfo();
}
}
};
class MockProgram : public Program {
public:
using Program::allowNonUniform;

View File

@ -565,6 +565,25 @@ TEST_F(ProgramFromBinaryTest, givenReuseKernelBinariesWhenCleanCurrentKernelInfo
EXPECT_EQ(0u, kernelAllocMap.size());
}
using ProgramGetNumKernelsTest = Test<NEOProgramFixture>;
TEST_F(ProgramGetNumKernelsTest, givenProgramWithFunctionsWhenGettingNumKernelsFunctionsAreNotExposed) {
program->resizeAndPopulateKernelInfoArray(2);
program->exportedFunctionsKernelId = 0;
EXPECT_EQ(1U, program->getNumKernels());
}
using ProgramGetKernelInfoTest = Test<NEOProgramFixture>;
TEST_F(ProgramGetKernelInfoTest, givenProgramWithFunctionsWhenGettingKernelInfoByIndexThenFunctionsAreNotExposed) {
program->resizeAndPopulateKernelInfoArray(2);
program->exportedFunctionsKernelId = 0;
auto kernelInfo = program->getKernelInfo(size_t(0), uint32_t(0));
EXPECT_EQ(program->buildInfos[0].kernelInfoArray[1], kernelInfo);
}
TEST_F(ProgramGetKernelInfoTest, givenProgramFunctionsWhenGettingKernelInfoByNameThenFunctionsAreNotExposed) {
EXPECT_EQ(nullptr, program->getKernelInfo(NEO::Elf::SectionsNamesZebin::externalFunctions.data(), uint32_t(0)));
}
HWTEST_F(ProgramFromBinaryTest, givenProgramWhenCleanCurrentKernelInfoIsCalledButGpuIsNotYetDoneThenKernelAllocationIsPutOnDeferredFreeListAndCsrRegistersCacheFlush) {
auto &csr = pDevice->getGpgpuCommandStreamReceiver();
EXPECT_TRUE(csr.getTemporaryAllocations().peekIsEmpty());