Skip to content

Commit 07a63c9

Browse files
cl_cache: do not call fcl when not needed
call to FCL can be costly. we don't need this when kernel source is simple and does not contain '#include'. In this case we can compute hash directly based on kernel source. Change-Id: I0455be57d9ee13919a53c145e3feeb00a113d71e
1 parent fbf00d3 commit 07a63c9

File tree

2 files changed

+94
-7
lines changed

2 files changed

+94
-7
lines changed

runtime/compiler_interface/compiler_interface.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, Intel Corporation
2+
* Copyright (c) 2017 - 2018, Intel Corporation
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a
55
* copy of this software and associated documentation files (the "Software"),
@@ -40,6 +40,12 @@ CompilerInterface *CompilerInterface::pInstance = nullptr;
4040
bool CompilerInterface::useLlvmText = false;
4141
std::mutex CompilerInterface::mtx;
4242

43+
enum CachingMode {
44+
None,
45+
Direct,
46+
PreProcess
47+
};
48+
4349
CompilerInterface::CompilerInterface() = default;
4450
CompilerInterface::~CompilerInterface() = default;
4551
NO_SANITIZE
@@ -69,16 +75,39 @@ cl_int CompilerInterface::build(
6975
}
7076
}
7177

78+
CachingMode cachingMode = None;
79+
80+
if (enableCaching) {
81+
if ((highLevelCodeType == IGC::CodeType::oclC) && (std::strstr(inputArgs.pInput, "#include") == nullptr)) {
82+
cachingMode = CachingMode::Direct;
83+
} else {
84+
cachingMode = CachingMode::PreProcess;
85+
}
86+
}
87+
7288
uint32_t numDevices = static_cast<uint32_t>(program.getNumDevices());
7389
for (uint32_t i = 0; i < numDevices; i++) {
7490
const auto &device = program.getDevice(i);
7591
UNRECOVERABLE_IF(intermediateCodeType == IGC::CodeType::undefined);
7692

93+
bool binaryLoaded = false;
94+
std::string kernelFileHash;
95+
if (cachingMode == CachingMode::Direct) {
96+
kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(),
97+
ArrayRef<const char>(inputArgs.pInput, inputArgs.InputSize),
98+
ArrayRef<const char>(inputArgs.pOptions, inputArgs.OptionsSize),
99+
ArrayRef<const char>(inputArgs.pInternalOptions, inputArgs.InternalOptionsSize));
100+
if (cache->loadCachedBinary(kernelFileHash, program)) {
101+
continue;
102+
}
103+
}
104+
77105
auto inSrc = CIF::Builtins::CreateConstBuffer(fclMain.get(), inputArgs.pInput, inputArgs.InputSize);
78106
auto fclOptions = CIF::Builtins::CreateConstBuffer(fclMain.get(), inputArgs.pOptions, inputArgs.OptionsSize);
79107
auto fclInternalOptions = CIF::Builtins::CreateConstBuffer(fclMain.get(), inputArgs.pInternalOptions, inputArgs.InternalOptionsSize);
80108

81109
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> intermediateRepresentation;
110+
82111
if (highLevelCodeType != IGC::CodeType::undefined) {
83112
auto fclTranslationCtx = createFclTranslationCtx(device, highLevelCodeType, intermediateCodeType);
84113
auto fclOutput = translate(fclTranslationCtx.get(), inSrc.get(),
@@ -103,9 +132,7 @@ cl_int CompilerInterface::build(
103132
intermediateRepresentation.reset(inSrc.get());
104133
}
105134

106-
bool binaryLoaded = false;
107-
std::string kernelFileHash;
108-
if (enableCaching) {
135+
if (cachingMode == CachingMode::PreProcess) {
109136
kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(), ArrayRef<const char>(intermediateRepresentation->GetMemory<char>(), intermediateRepresentation->GetSize<char>()),
110137
ArrayRef<const char>(fclOptions->GetMemory<char>(), fclOptions->GetSize<char>()),
111138
ArrayRef<const char>(fclInternalOptions->GetMemory<char>(), fclInternalOptions->GetSize<char>()));

unit_tests/compiler_interface/binary_cache_tests.cpp

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ TEST_F(CompilerInterfaceCachedTests, notCachedAndIgcFailed) {
357357
TranslationArgs inputArgs;
358358

359359
inputArgs.pInput = new char[128];
360-
strcpy_s(inputArgs.pInput, 128, "__kernel k() {}");
360+
strcpy_s(inputArgs.pInput, 128, "#include \"header.h\"\n__kernel k() {}");
361361
inputArgs.InputSize = static_cast<uint32_t>(strlen(inputArgs.pInput));
362362

363363
MockCompilerDebugVars fclDebugVars;
@@ -388,7 +388,7 @@ TEST_F(CompilerInterfaceCachedTests, wasCached) {
388388
TranslationArgs inputArgs;
389389

390390
inputArgs.pInput = new char[128];
391-
strcpy_s(inputArgs.pInput, 128, "__kernel k() {}");
391+
strcpy_s(inputArgs.pInput, 128, "#include \"header.h\"\n__kernel k() {}");
392392
inputArgs.InputSize = static_cast<uint32_t>(strlen(inputArgs.pInput));
393393

394394
MockCompilerDebugVars fclDebugVars;
@@ -419,7 +419,7 @@ TEST_F(CompilerInterfaceCachedTests, builtThenCached) {
419419
TranslationArgs inputArgs;
420420

421421
inputArgs.pInput = new char[128];
422-
strcpy_s(inputArgs.pInput, 128, "__kernel k() {}");
422+
strcpy_s(inputArgs.pInput, 128, "#include \"header.h\"\n__kernel k() {}");
423423
inputArgs.InputSize = static_cast<uint32_t>(strlen(inputArgs.pInput));
424424

425425
MockCompilerDebugVars fclDebugVars;
@@ -441,3 +441,63 @@ TEST_F(CompilerInterfaceCachedTests, builtThenCached) {
441441
gEnvironment->fclPopDebugVars();
442442
gEnvironment->igcPopDebugVars();
443443
}
444+
445+
TEST_F(CompilerInterfaceCachedTests, givenKernelWithoutIncludesAndBinaryInCacheWhenCompilationRequestedThenFCLIsNotCalled) {
446+
MockContext context(pDevice, true);
447+
MockProgram program(&context, false);
448+
BinaryCacheMock cache;
449+
TranslationArgs inputArgs;
450+
451+
inputArgs.pInput = new char[128];
452+
strcpy_s(inputArgs.pInput, 128, "__kernel k() {}");
453+
inputArgs.InputSize = static_cast<uint32_t>(strlen(inputArgs.pInput));
454+
455+
// we force both compilers to fail compilation request
456+
// at the end we expect CL_SUCCESS which means compilation ends in cache
457+
MockCompilerDebugVars fclDebugVars;
458+
fclDebugVars.fileName = gEnvironment->fclGetMockFile();
459+
fclDebugVars.forceBuildFailure = true;
460+
gEnvironment->fclPushDebugVars(fclDebugVars);
461+
462+
MockCompilerDebugVars igcDebugVars;
463+
igcDebugVars.fileName = gEnvironment->igcGetMockFile();
464+
igcDebugVars.forceBuildFailure = true;
465+
gEnvironment->igcPushDebugVars(igcDebugVars);
466+
467+
auto res = pCompilerInterface->replaceBinaryCache(&cache);
468+
cache.loadResult = true;
469+
auto retVal = pCompilerInterface->build(program, inputArgs, true);
470+
EXPECT_EQ(CL_SUCCESS, retVal);
471+
472+
pCompilerInterface->replaceBinaryCache(res);
473+
delete[] inputArgs.pInput;
474+
475+
gEnvironment->fclPopDebugVars();
476+
gEnvironment->igcPopDebugVars();
477+
}
478+
479+
TEST_F(CompilerInterfaceCachedTests, givenKernelWithIncludesAndBinaryInCacheWhenCompilationRequestedThenFCLIsCalled) {
480+
MockContext context(pDevice, true);
481+
MockProgram program(&context, false);
482+
BinaryCacheMock cache;
483+
TranslationArgs inputArgs;
484+
485+
inputArgs.pInput = new char[128];
486+
strcpy_s(inputArgs.pInput, 128, "#include \"file.h\"\n__kernel k() {}");
487+
inputArgs.InputSize = static_cast<uint32_t>(strlen(inputArgs.pInput));
488+
489+
MockCompilerDebugVars fclDebugVars;
490+
fclDebugVars.fileName = gEnvironment->fclGetMockFile();
491+
fclDebugVars.forceBuildFailure = true;
492+
gEnvironment->fclPushDebugVars(fclDebugVars);
493+
494+
auto res = pCompilerInterface->replaceBinaryCache(&cache);
495+
cache.loadResult = true;
496+
auto retVal = pCompilerInterface->build(program, inputArgs, true);
497+
EXPECT_EQ(CL_BUILD_PROGRAM_FAILURE, retVal);
498+
499+
pCompilerInterface->replaceBinaryCache(res);
500+
delete[] inputArgs.pInput;
501+
502+
gEnvironment->fclPopDebugVars();
503+
}

0 commit comments

Comments
 (0)