mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 12:23:05 +08:00
Program refactor
* decouple program_info * move global allocations relocation to linker * remove obsolete tests * initial cleanup to kernel_info kernelInfo * unified patchtoken validation Change-Id: I0567cd6d607b4f3cf44e6caf33681f6210760f76
This commit is contained in:
committed by
sys_ocldev
parent
570b09850d
commit
f057712fa7
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -1,5 +1,5 @@
|
||||
#!groovy
|
||||
dependenciesRevision='8a86a70513be57f370417793c63ca03d55824432-1362'
|
||||
strategy='EQUAL'
|
||||
allowedCD=257
|
||||
allowedCD=253
|
||||
allowedF=11
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -29,13 +29,14 @@ bool LinkerInput::decodeGlobalVariablesSymbolTable(const void *data, uint32_t nu
|
||||
switch (symbolEntryIt->s_type) {
|
||||
default:
|
||||
DEBUG_BREAK_IF(true);
|
||||
this->valid = false;
|
||||
return false;
|
||||
case vISA::S_GLOBAL_VAR:
|
||||
symbolInfo.type = SymbolInfo::GlobalVariable;
|
||||
symbolInfo.segment = SegmentType::GlobalVariables;
|
||||
traits.exportsGlobalVariables = true;
|
||||
break;
|
||||
case vISA::S_GLOBAL_VAR_CONST:
|
||||
symbolInfo.type = SymbolInfo::GlobalConstant;
|
||||
symbolInfo.segment = SegmentType::GlobalConstants;
|
||||
traits.exportsGlobalConstants = true;
|
||||
break;
|
||||
}
|
||||
@@ -54,17 +55,18 @@ bool LinkerInput::decodeExportedFunctionsSymbolTable(const void *data, uint32_t
|
||||
switch (symbolEntryIt->s_type) {
|
||||
default:
|
||||
DEBUG_BREAK_IF(true);
|
||||
this->valid = false;
|
||||
return false;
|
||||
case vISA::S_GLOBAL_VAR:
|
||||
symbolInfo.type = SymbolInfo::GlobalVariable;
|
||||
symbolInfo.segment = SegmentType::GlobalVariables;
|
||||
traits.exportsGlobalVariables = true;
|
||||
break;
|
||||
case vISA::S_GLOBAL_VAR_CONST:
|
||||
symbolInfo.type = SymbolInfo::GlobalConstant;
|
||||
symbolInfo.segment = SegmentType::GlobalConstants;
|
||||
traits.exportsGlobalConstants = true;
|
||||
break;
|
||||
case vISA::S_FUNC:
|
||||
symbolInfo.type = SymbolInfo::Function;
|
||||
symbolInfo.segment = SegmentType::Instructions;
|
||||
traits.exportsFunctions = true;
|
||||
UNRECOVERABLE_IF((this->exportedFunctionsSegmentId != -1) && (this->exportedFunctionsSegmentId != static_cast<int32_t>(instructionsSegmentId)));
|
||||
this->exportedFunctionsSegmentId = static_cast<int32_t>(instructionsSegmentId);
|
||||
@@ -89,9 +91,12 @@ bool LinkerInput::decodeRelocationTable(const void *data, uint32_t numEntries, u
|
||||
RelocationInfo relocInfo{};
|
||||
relocInfo.offset = relocEntryIt->r_offset;
|
||||
relocInfo.symbolName = relocEntryIt->r_symbol;
|
||||
relocInfo.symbolSegment = SegmentType::Unknown;
|
||||
relocInfo.relocationSegment = SegmentType::Instructions;
|
||||
switch (relocEntryIt->r_type) {
|
||||
default:
|
||||
DEBUG_BREAK_IF(true);
|
||||
this->valid = false;
|
||||
return false;
|
||||
case vISA::R_SYM_ADDR:
|
||||
relocInfo.type = RelocationInfo::Type::Address;
|
||||
@@ -108,21 +113,30 @@ bool LinkerInput::decodeRelocationTable(const void *data, uint32_t numEntries, u
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Linker::processRelocations(const Segment &globalVariables, const Segment &globalConstants, const Segment &exportedFunctions) {
|
||||
void LinkerInput::addDataRelocationInfo(const RelocationInfo &relocationInfo) {
|
||||
DEBUG_BREAK_IF((relocationInfo.relocationSegment != SegmentType::GlobalConstants) && (relocationInfo.relocationSegment != SegmentType::GlobalVariables));
|
||||
DEBUG_BREAK_IF((relocationInfo.symbolSegment != SegmentType::GlobalConstants) && (relocationInfo.symbolSegment != SegmentType::GlobalVariables));
|
||||
DEBUG_BREAK_IF(relocationInfo.type == LinkerInput::RelocationInfo::Type::AddressHigh);
|
||||
this->traits.requiresPatchingOfGlobalVariablesBuffer |= (relocationInfo.relocationSegment == SegmentType::GlobalVariables);
|
||||
this->traits.requiresPatchingOfGlobalConstantsBuffer |= (relocationInfo.relocationSegment == SegmentType::GlobalConstants);
|
||||
this->dataRelocations.push_back(relocationInfo);
|
||||
}
|
||||
|
||||
bool Linker::processRelocations(const SegmentInfo &globalVariables, const SegmentInfo &globalConstants, const SegmentInfo &exportedFunctions) {
|
||||
relocatedSymbols.reserve(data.getSymbols().size());
|
||||
for (auto &symbol : data.getSymbols()) {
|
||||
const Segment *seg = nullptr;
|
||||
switch (symbol.second.type) {
|
||||
const SegmentInfo *seg = nullptr;
|
||||
switch (symbol.second.segment) {
|
||||
default:
|
||||
DEBUG_BREAK_IF(true);
|
||||
return false;
|
||||
case SymbolInfo::GlobalVariable:
|
||||
case SegmentType::GlobalVariables:
|
||||
seg = &globalVariables;
|
||||
break;
|
||||
case SymbolInfo::GlobalConstant:
|
||||
case SegmentType::GlobalConstants:
|
||||
seg = &globalConstants;
|
||||
break;
|
||||
case SymbolInfo::Function:
|
||||
case SegmentType::Instructions:
|
||||
seg = &exportedFunctions;
|
||||
break;
|
||||
}
|
||||
@@ -136,28 +150,33 @@ bool Linker::processRelocations(const Segment &globalVariables, const Segment &g
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t addressSizeInBytes(LinkerInput::RelocationInfo::Type relocationtype) {
|
||||
return (relocationtype == LinkerInput::RelocationInfo::Type::Address) ? sizeof(uintptr_t) : sizeof(uint32_t);
|
||||
}
|
||||
|
||||
bool Linker::patchInstructionsSegments(const std::vector<PatchableSegment> &instructionsSegments, std::vector<UnresolvedExternal> &outUnresolvedExternals) {
|
||||
if (false == data.getTraits().requiresPatchingOfInstructionSegments) {
|
||||
return true;
|
||||
}
|
||||
UNRECOVERABLE_IF(data.getRelocations().size() > instructionsSegments.size());
|
||||
std::vector<UnresolvedExternal> unresolvedExternals;
|
||||
UNRECOVERABLE_IF(data.getRelocationsInInstructionSegments().size() > instructionsSegments.size());
|
||||
auto unresolvedExternalsPrev = outUnresolvedExternals.size();
|
||||
auto segIt = instructionsSegments.begin();
|
||||
for (auto relocsIt = data.getRelocations().begin(), relocsEnd = data.getRelocations().end();
|
||||
for (auto relocsIt = data.getRelocationsInInstructionSegments().begin(), relocsEnd = data.getRelocationsInInstructionSegments().end();
|
||||
relocsIt != relocsEnd; ++relocsIt, ++segIt) {
|
||||
auto &thisSegmentRelocs = *relocsIt;
|
||||
const PatchableSegment &instSeg = *segIt;
|
||||
for (const auto &relocation : thisSegmentRelocs) {
|
||||
auto relocAddress = ptrOffset(instSeg.hostPointer, relocation.offset);
|
||||
UNRECOVERABLE_IF(nullptr == instSeg.hostPointer);
|
||||
auto relocAddress = ptrOffset(instSeg.hostPointer, static_cast<uintptr_t>(relocation.offset));
|
||||
auto symbolIt = relocatedSymbols.find(relocation.symbolName);
|
||||
|
||||
bool invalidOffset = relocation.offset + sizeof(uintptr_t) > instSeg.segmentSize;
|
||||
bool invalidOffset = relocation.offset + addressSizeInBytes(relocation.type) > instSeg.segmentSize;
|
||||
bool unresolvedExternal = (symbolIt == relocatedSymbols.end());
|
||||
|
||||
DEBUG_BREAK_IF(invalidOffset);
|
||||
if (invalidOffset || unresolvedExternal) {
|
||||
uint32_t segId = static_cast<uint32_t>(segIt - instructionsSegments.begin());
|
||||
unresolvedExternals.push_back(UnresolvedExternal{relocation, segId, invalidOffset});
|
||||
outUnresolvedExternals.push_back(UnresolvedExternal{relocation, segId, invalidOffset});
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -176,8 +195,71 @@ bool Linker::patchInstructionsSegments(const std::vector<PatchableSegment> &inst
|
||||
}
|
||||
}
|
||||
}
|
||||
outUnresolvedExternals.swap(unresolvedExternals);
|
||||
return outUnresolvedExternals.size() == 0;
|
||||
return outUnresolvedExternals.size() == unresolvedExternalsPrev;
|
||||
}
|
||||
|
||||
bool Linker::patchDataSegments(const SegmentInfo &globalVariablesSegInfo, const SegmentInfo &globalConstantsSegInfo,
|
||||
PatchableSegment &globalVariablesSeg, PatchableSegment &globalConstantsSeg,
|
||||
std::vector<UnresolvedExternal> &outUnresolvedExternals) {
|
||||
if (false == (data.getTraits().requiresPatchingOfGlobalConstantsBuffer || data.getTraits().requiresPatchingOfGlobalVariablesBuffer)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto unresolvedExternalsPrev = outUnresolvedExternals.size();
|
||||
for (const auto &relocation : data.getDataRelocations()) {
|
||||
const SegmentInfo *src = nullptr;
|
||||
const PatchableSegment *dst = nullptr;
|
||||
switch (relocation.symbolSegment) {
|
||||
default:
|
||||
outUnresolvedExternals.push_back(UnresolvedExternal{relocation});
|
||||
continue;
|
||||
case SegmentType::GlobalVariables:
|
||||
src = &globalVariablesSegInfo;
|
||||
break;
|
||||
case SegmentType::GlobalConstants:
|
||||
src = &globalConstantsSegInfo;
|
||||
break;
|
||||
}
|
||||
switch (relocation.relocationSegment) {
|
||||
default:
|
||||
outUnresolvedExternals.push_back(UnresolvedExternal{relocation});
|
||||
continue;
|
||||
case SegmentType::GlobalVariables:
|
||||
dst = &globalVariablesSeg;
|
||||
break;
|
||||
case SegmentType::GlobalConstants:
|
||||
dst = &globalConstantsSeg;
|
||||
break;
|
||||
}
|
||||
|
||||
UNRECOVERABLE_IF(nullptr == dst->hostPointer);
|
||||
|
||||
if (RelocationInfo::Type::AddressHigh == relocation.type) {
|
||||
outUnresolvedExternals.push_back(UnresolvedExternal{relocation});
|
||||
continue;
|
||||
}
|
||||
|
||||
auto relocType = (LinkerInput::Traits::PointerSize::Ptr32bit == data.getTraits().pointerSize) ? RelocationInfo::Type::AddressLow : relocation.type;
|
||||
bool invalidOffset = relocation.offset + addressSizeInBytes(relocType) > dst->segmentSize;
|
||||
DEBUG_BREAK_IF(invalidOffset);
|
||||
if (invalidOffset) {
|
||||
outUnresolvedExternals.push_back(UnresolvedExternal{relocation});
|
||||
continue;
|
||||
}
|
||||
|
||||
uint64_t gpuAddressAs64bit = src->gpuAddress;
|
||||
auto relocAddress = ptrOffset(dst->hostPointer, static_cast<uintptr_t>(relocation.offset));
|
||||
switch (relocType) {
|
||||
default:
|
||||
UNRECOVERABLE_IF(RelocationInfo::Type::Address != relocType);
|
||||
patchIncrement(relocAddress, sizeof(uintptr_t), gpuAddressAs64bit);
|
||||
break;
|
||||
case RelocationInfo::Type::AddressLow:
|
||||
patchIncrement(relocAddress, 4, static_cast<uint32_t>(gpuAddressAs64bit & 0xffffffff));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return outUnresolvedExternals.size() == unresolvedExternalsPrev;
|
||||
}
|
||||
|
||||
std::string constructLinkerErrorMessage(const Linker::UnresolvedExternals &unresolvedExternals, const std::vector<std::string> &instructionsSegmentsNames) {
|
||||
@@ -191,10 +273,16 @@ std::string constructLinkerErrorMessage(const Linker::UnresolvedExternals &unres
|
||||
} else {
|
||||
errorStream << "error : unresolved external symbol ";
|
||||
}
|
||||
errorStream << unresExtern.unresolvedRelocation.symbolName << " at offset " << unresExtern.unresolvedRelocation.offset
|
||||
<< " in instructions segment #" << unresExtern.instructionsSegmentId;
|
||||
if (instructionsSegmentsNames.size() > unresExtern.instructionsSegmentId) {
|
||||
errorStream << " (aka " << instructionsSegmentsNames[unresExtern.instructionsSegmentId] << ")";
|
||||
|
||||
if (unresExtern.unresolvedRelocation.relocationSegment == NEO::SegmentType::Instructions) {
|
||||
errorStream << unresExtern.unresolvedRelocation.symbolName << " at offset " << unresExtern.unresolvedRelocation.offset
|
||||
<< " in instructions segment #" << unresExtern.instructionsSegmentId;
|
||||
if (instructionsSegmentsNames.size() > unresExtern.instructionsSegmentId) {
|
||||
errorStream << " (aka " << instructionsSegmentsNames[unresExtern.instructionsSegmentId] << ")";
|
||||
}
|
||||
} else {
|
||||
errorStream << " address of segment #" << asString(unresExtern.unresolvedRelocation.symbolSegment) << " at offset " << unresExtern.unresolvedRelocation.offset
|
||||
<< " in data segment #" << asString(unresExtern.unresolvedRelocation.relocationSegment);
|
||||
}
|
||||
errorStream << "\n";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -16,28 +16,49 @@
|
||||
|
||||
namespace NEO {
|
||||
|
||||
enum class SegmentType : uint32_t {
|
||||
Unknown,
|
||||
GlobalConstants,
|
||||
GlobalVariables,
|
||||
Instructions,
|
||||
};
|
||||
|
||||
inline const char *asString(SegmentType segment) {
|
||||
switch (segment) {
|
||||
default:
|
||||
return "UNKOWN";
|
||||
case SegmentType::GlobalConstants:
|
||||
return "GLOBAL_CONSTANTS";
|
||||
case SegmentType::GlobalVariables:
|
||||
return "GLOBAL_VARIABLES";
|
||||
case SegmentType::Instructions:
|
||||
return "INSTRUCTIONS";
|
||||
}
|
||||
}
|
||||
|
||||
struct SymbolInfo {
|
||||
enum Type : uint32_t {
|
||||
Unknown,
|
||||
GlobalConstant,
|
||||
GlobalVariable,
|
||||
Function
|
||||
};
|
||||
uint32_t offset = std::numeric_limits<uint32_t>::max();
|
||||
uint32_t size = std::numeric_limits<uint32_t>::max();
|
||||
Type type = Unknown;
|
||||
SegmentType segment = SegmentType::Unknown;
|
||||
};
|
||||
|
||||
struct LinkerInput {
|
||||
|
||||
union Traits {
|
||||
enum PointerSize : uint8_t {
|
||||
Ptr32bit = 0,
|
||||
Ptr64bit = 1
|
||||
};
|
||||
Traits() : packed(0) {
|
||||
pointerSize = (sizeof(void *) == 4) ? PointerSize::Ptr32bit : PointerSize::Ptr64bit;
|
||||
}
|
||||
struct {
|
||||
bool exportsGlobalVariables : 1;
|
||||
bool exportsGlobalConstants : 1;
|
||||
bool exportsFunctions : 1;
|
||||
bool requiresPatchingOfInstructionSegments : 1;
|
||||
bool requiresPatchingOfGlobalVariablesBuffer : 1;
|
||||
bool requiresPatchingOfGlobalConstantsBuffer : 1;
|
||||
uint8_t pointerSize : 1;
|
||||
};
|
||||
uint32_t packed;
|
||||
};
|
||||
@@ -52,17 +73,22 @@ struct LinkerInput {
|
||||
};
|
||||
|
||||
std::string symbolName;
|
||||
uint32_t offset = std::numeric_limits<uint32_t>::max();
|
||||
uint64_t offset = std::numeric_limits<uint64_t>::max();
|
||||
Type type = Type::Unknown;
|
||||
SegmentType relocationSegment = SegmentType::Unknown;
|
||||
SegmentType symbolSegment = SegmentType::Unknown;
|
||||
};
|
||||
|
||||
using Relocations = std::vector<RelocationInfo>;
|
||||
using SymbolMap = std::unordered_map<std::string, SymbolInfo>;
|
||||
using RelocationsPerInstSegment = std::vector<Relocations>;
|
||||
|
||||
bool decodeGlobalVariablesSymbolTable(const void *data, uint32_t numEntries);
|
||||
bool decodeExportedFunctionsSymbolTable(const void *data, uint32_t numEntries, uint32_t instructionsSegmentId);
|
||||
bool decodeRelocationTable(const void *data, uint32_t numEntries, uint32_t instructionsSegmentId);
|
||||
virtual ~LinkerInput() = default;
|
||||
|
||||
MOCKABLE_VIRTUAL bool decodeGlobalVariablesSymbolTable(const void *data, uint32_t numEntries);
|
||||
MOCKABLE_VIRTUAL bool decodeExportedFunctionsSymbolTable(const void *data, uint32_t numEntries, uint32_t instructionsSegmentId);
|
||||
MOCKABLE_VIRTUAL bool decodeRelocationTable(const void *data, uint32_t numEntries, uint32_t instructionsSegmentId);
|
||||
void addDataRelocationInfo(const RelocationInfo &relocationInfo);
|
||||
|
||||
const Traits &getTraits() const {
|
||||
return traits;
|
||||
@@ -76,21 +102,35 @@ struct LinkerInput {
|
||||
return symbols;
|
||||
}
|
||||
|
||||
const RelocationsPerInstSegment &getRelocations() const {
|
||||
const RelocationsPerInstSegment &getRelocationsInInstructionSegments() const {
|
||||
return relocations;
|
||||
}
|
||||
|
||||
const Relocations &getDataRelocations() const {
|
||||
return dataRelocations;
|
||||
}
|
||||
|
||||
void setPointerSize(Traits::PointerSize pointerSize) {
|
||||
traits.pointerSize = pointerSize;
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return valid;
|
||||
}
|
||||
|
||||
protected:
|
||||
Traits traits;
|
||||
SymbolMap symbols;
|
||||
RelocationsPerInstSegment relocations;
|
||||
Relocations dataRelocations;
|
||||
int32_t exportedFunctionsSegmentId = -1;
|
||||
bool valid = true;
|
||||
};
|
||||
|
||||
struct Linker {
|
||||
using RelocationInfo = LinkerInput::RelocationInfo;
|
||||
|
||||
struct Segment {
|
||||
struct SegmentInfo {
|
||||
uintptr_t gpuAddress = std::numeric_limits<uintptr_t>::max();
|
||||
size_t segmentSize = std::numeric_limits<size_t>::max();
|
||||
};
|
||||
@@ -119,10 +159,15 @@ struct Linker {
|
||||
: data(data) {
|
||||
}
|
||||
|
||||
bool link(const Segment &globalVariables, const Segment &globalConstants, const Segment &exportedFunctions,
|
||||
const PatchableSegments &instructionsSegments,
|
||||
bool link(const SegmentInfo &globalVariablesSegInfo, const SegmentInfo &globalConstantsSegInfo, const SegmentInfo &exportedFunctionsSegInfo,
|
||||
PatchableSegment &globalVariablesSeg, PatchableSegment &globalConstantsSeg, const PatchableSegments &instructionsSegments,
|
||||
UnresolvedExternals &outUnresolvedExternals) {
|
||||
return processRelocations(globalVariables, globalConstants, exportedFunctions) && patchInstructionsSegments(instructionsSegments, outUnresolvedExternals);
|
||||
bool success = data.isValid();
|
||||
success = success && processRelocations(globalVariablesSegInfo, globalConstantsSegInfo, exportedFunctionsSegInfo);
|
||||
success = success && patchInstructionsSegments(instructionsSegments, outUnresolvedExternals);
|
||||
success = success && patchDataSegments(globalVariablesSegInfo, globalConstantsSegInfo, globalVariablesSeg, globalConstantsSeg, outUnresolvedExternals);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
RelocatedSymbolsMap extractRelocatedSymbols() {
|
||||
@@ -133,9 +178,13 @@ struct Linker {
|
||||
const LinkerInput &data;
|
||||
RelocatedSymbolsMap relocatedSymbols;
|
||||
|
||||
bool processRelocations(const Segment &globalVariables, const Segment &globalConstants, const Segment &exportedFunctions);
|
||||
bool processRelocations(const SegmentInfo &globalVariables, const SegmentInfo &globalConstants, const SegmentInfo &exportedFunctions);
|
||||
|
||||
bool patchInstructionsSegments(const std::vector<PatchableSegment> &instructionsSegments, std::vector<UnresolvedExternal> &outUnresolvedExternals);
|
||||
|
||||
bool patchDataSegments(const SegmentInfo &globalVariablesSegInfo, const SegmentInfo &globalConstantsSegInfo,
|
||||
PatchableSegment &globalVariablesSeg, PatchableSegment &globalConstantsSeg,
|
||||
std::vector<UnresolvedExternal> &outUnresolvedExternals);
|
||||
};
|
||||
|
||||
std::string constructLinkerErrorMessage(const Linker::UnresolvedExternals &unresolvedExternals, const std::vector<std::string> &instructionsSegmentsNames);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation
|
||||
# Copyright (C) 2019-2020 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
@@ -8,6 +8,12 @@ set(NEO_CORE_PROGRAM
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/print_formatter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/print_formatter.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_info.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_info.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_info_from_patchtokens.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_info_from_patchtokens.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_initialization.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_initialization.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sync_buffer_handler.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sync_buffer_handler.h
|
||||
)
|
||||
|
||||
21
core/program/program_info.cpp
Normal file
21
core/program/program_info.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/program/program_info.h"
|
||||
|
||||
#include "runtime/program/kernel_info.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
ProgramInfo::~ProgramInfo() {
|
||||
for (auto &kernelInfo : kernelInfos) {
|
||||
delete kernelInfo;
|
||||
}
|
||||
kernelInfos.clear();
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
43
core/program/program_info.h
Normal file
43
core/program/program_info.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/compiler_interface/linker.h"
|
||||
#include "core/utilities/stackvec.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace NEO {
|
||||
struct KernelInfo;
|
||||
|
||||
struct ProgramInfo {
|
||||
ProgramInfo() = default;
|
||||
ProgramInfo(ProgramInfo &&) = default;
|
||||
ProgramInfo &operator=(ProgramInfo &&) = default;
|
||||
~ProgramInfo();
|
||||
|
||||
struct GlobalSurfaceInfo {
|
||||
const void *initData = nullptr;
|
||||
size_t size = 0U;
|
||||
};
|
||||
|
||||
void prepareLinkerInputStorage() {
|
||||
if (this->linkerInput == nullptr) {
|
||||
this->linkerInput = std::make_unique<LinkerInput>();
|
||||
}
|
||||
}
|
||||
|
||||
GlobalSurfaceInfo globalConstants;
|
||||
GlobalSurfaceInfo globalVariables;
|
||||
std::unique_ptr<LinkerInput> linkerInput;
|
||||
|
||||
std::vector<KernelInfo *> kernelInfos;
|
||||
};
|
||||
|
||||
} // namespace NEO
|
||||
102
core/program/program_info_from_patchtokens.cpp
Normal file
102
core/program/program_info_from_patchtokens.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/program/program_info_from_patchtokens.h"
|
||||
|
||||
#include "core/compiler_interface/linker.h"
|
||||
#include "core/debug_settings/debug_settings_manager.h"
|
||||
#include "core/program/program_info.h"
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
#include "runtime/program/kernel_info.h"
|
||||
#include "runtime/program/kernel_info_from_patchtokens.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
bool requiresLocalMemoryWindowVA(const PatchTokenBinary::ProgramFromPatchtokens &src) {
|
||||
for (const auto kernel : src.kernels) {
|
||||
if (kernel.tokens.crossThreadPayloadArgs.localMemoryStatelessWindowStartAddress) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void populateSingleKernelInfo(ProgramInfo &dst, const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram, const DeviceInfoKernelPayloadConstants &constants, uint32_t kernelNum) {
|
||||
auto kernelInfo = std::make_unique<KernelInfo>();
|
||||
const PatchTokenBinary::KernelFromPatchtokens &decodedKernel = decodedProgram.kernels[kernelNum];
|
||||
|
||||
NEO::populateKernelInfo(*kernelInfo, decodedKernel, decodedProgram.header->GPUPointerSizeInBytes, constants);
|
||||
|
||||
if (decodedKernel.tokens.programSymbolTable) {
|
||||
dst.prepareLinkerInputStorage();
|
||||
dst.linkerInput->decodeExportedFunctionsSymbolTable(decodedKernel.tokens.programSymbolTable + 1, decodedKernel.tokens.programSymbolTable->NumEntries, kernelNum);
|
||||
}
|
||||
|
||||
if (decodedKernel.tokens.programRelocationTable) {
|
||||
dst.prepareLinkerInputStorage();
|
||||
dst.linkerInput->decodeRelocationTable(decodedKernel.tokens.programRelocationTable + 1, decodedKernel.tokens.programRelocationTable->NumEntries, kernelNum);
|
||||
}
|
||||
|
||||
dst.kernelInfos.push_back(kernelInfo.release());
|
||||
}
|
||||
|
||||
void populateProgramInfo(ProgramInfo &dst, const PatchTokenBinary::ProgramFromPatchtokens &src, const DeviceInfoKernelPayloadConstants &constants) {
|
||||
for (uint32_t i = 0; i < src.kernels.size(); ++i) {
|
||||
populateSingleKernelInfo(dst, src, constants, i);
|
||||
}
|
||||
|
||||
if (src.programScopeTokens.allocateConstantMemorySurface.empty() == false) {
|
||||
auto surface = src.programScopeTokens.allocateConstantMemorySurface[0];
|
||||
dst.globalConstants.size = surface->InlineDataSize;
|
||||
dst.globalConstants.initData = NEO::PatchTokenBinary::getInlineData(surface);
|
||||
}
|
||||
|
||||
if (src.programScopeTokens.allocateGlobalMemorySurface.empty() == false) {
|
||||
auto surface = src.programScopeTokens.allocateGlobalMemorySurface[0];
|
||||
dst.globalVariables.size = surface->InlineDataSize;
|
||||
dst.globalVariables.initData = NEO::PatchTokenBinary::getInlineData(surface);
|
||||
}
|
||||
|
||||
if (false == (src.programScopeTokens.constantPointer.empty() && src.programScopeTokens.globalPointer.empty() && (src.programScopeTokens.symbolTable == nullptr))) {
|
||||
UNRECOVERABLE_IF((src.header->GPUPointerSizeInBytes != 4) && (src.header->GPUPointerSizeInBytes != 8));
|
||||
dst.prepareLinkerInputStorage();
|
||||
dst.linkerInput->setPointerSize((src.header->GPUPointerSizeInBytes == 4) ? LinkerInput::Traits::PointerSize::Ptr32bit : LinkerInput::Traits::PointerSize::Ptr64bit);
|
||||
}
|
||||
|
||||
for (const auto &globalConstantPointerToken : src.programScopeTokens.constantPointer) {
|
||||
NEO::LinkerInput::RelocationInfo relocInfo = {};
|
||||
relocInfo.relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocInfo.offset = readMisalignedUint64(&globalConstantPointerToken->ConstantPointerOffset);
|
||||
relocInfo.symbolSegment = NEO::SegmentType::GlobalConstants;
|
||||
if (globalConstantPointerToken->BufferType != iOpenCL::PROGRAM_SCOPE_CONSTANT_BUFFER) {
|
||||
UNRECOVERABLE_IF(globalConstantPointerToken->BufferType != iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER);
|
||||
relocInfo.symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
}
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
dst.linkerInput->addDataRelocationInfo(relocInfo);
|
||||
}
|
||||
|
||||
for (const auto &globalVariablePointerToken : src.programScopeTokens.globalPointer) {
|
||||
NEO::LinkerInput::RelocationInfo relocInfo = {};
|
||||
relocInfo.relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocInfo.offset = readMisalignedUint64(&globalVariablePointerToken->GlobalPointerOffset);
|
||||
relocInfo.symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
if (globalVariablePointerToken->BufferType != iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER) {
|
||||
UNRECOVERABLE_IF(globalVariablePointerToken->BufferType != iOpenCL::PROGRAM_SCOPE_CONSTANT_BUFFER);
|
||||
relocInfo.symbolSegment = NEO::SegmentType::GlobalConstants;
|
||||
}
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
dst.linkerInput->addDataRelocationInfo(relocInfo);
|
||||
}
|
||||
|
||||
if (src.programScopeTokens.symbolTable != nullptr) {
|
||||
const auto patch = src.programScopeTokens.symbolTable;
|
||||
dst.linkerInput->decodeGlobalVariablesSymbolTable(patch + 1, patch->NumEntries);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
30
core/program/program_info_from_patchtokens.h
Normal file
30
core/program/program_info_from_patchtokens.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
struct ProgramInfo;
|
||||
struct DeviceInfoKernelPayloadConstants;
|
||||
|
||||
namespace PatchTokenBinary {
|
||||
struct ProgramFromPatchtokens;
|
||||
}
|
||||
|
||||
inline uint64_t readMisalignedUint64(const uint64_t *address) {
|
||||
const uint32_t *addressBits = reinterpret_cast<const uint32_t *>(address);
|
||||
return static_cast<uint64_t>(static_cast<uint64_t>(addressBits[1]) << 32) | addressBits[0];
|
||||
}
|
||||
|
||||
bool requiresLocalMemoryWindowVA(const PatchTokenBinary::ProgramFromPatchtokens &src);
|
||||
|
||||
void populateProgramInfo(ProgramInfo &dst, const PatchTokenBinary::ProgramFromPatchtokens &src, const DeviceInfoKernelPayloadConstants &constants);
|
||||
|
||||
} // namespace NEO
|
||||
54
core/program/program_initialization.cpp
Normal file
54
core/program/program_initialization.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "program_initialization.h"
|
||||
|
||||
#include "core/compiler_interface/linker.h"
|
||||
#include "core/helpers/string.h"
|
||||
#include "core/memory_manager/graphics_allocation.h"
|
||||
#include "core/memory_manager/unified_memory_manager.h"
|
||||
#include "core/program/program_info.h"
|
||||
#include "runtime/device/device.h"
|
||||
#include "runtime/memory_manager/memory_manager.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
GraphicsAllocation *allocateGlobalsSurface(NEO::SVMAllocsManager *const svmAllocManager, NEO::Device &device, size_t size, bool constant, LinkerInput *const linkerInput, const void *const initData) {
|
||||
bool globalsAreExported = false;
|
||||
if (linkerInput != nullptr) {
|
||||
globalsAreExported = constant ? linkerInput->getTraits().exportsGlobalConstants : linkerInput->getTraits().exportsGlobalVariables;
|
||||
}
|
||||
|
||||
if (globalsAreExported && (svmAllocManager != nullptr)) {
|
||||
NEO::SVMAllocsManager::SvmAllocationProperties svmProps = {};
|
||||
svmProps.coherent = false;
|
||||
svmProps.readOnly = constant;
|
||||
svmProps.hostPtrReadOnly = constant;
|
||||
auto ptr = svmAllocManager->createSVMAlloc(device.getRootDeviceIndex(), size, svmProps);
|
||||
DEBUG_BREAK_IF(ptr == nullptr);
|
||||
if (ptr == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto svmAlloc = svmAllocManager->getSVMAlloc(ptr);
|
||||
UNRECOVERABLE_IF(svmAlloc == nullptr);
|
||||
auto gpuAlloc = svmAlloc->gpuAllocation;
|
||||
UNRECOVERABLE_IF(gpuAlloc == nullptr);
|
||||
device.getMemoryManager()->copyMemoryToAllocation(gpuAlloc, initData, static_cast<uint32_t>(size));
|
||||
return svmAllocManager->getSVMAlloc(ptr)->gpuAllocation;
|
||||
} else {
|
||||
auto allocationType = constant ? GraphicsAllocation::AllocationType::CONSTANT_SURFACE : GraphicsAllocation::AllocationType::GLOBAL_SURFACE;
|
||||
auto gpuAlloc = device.getMemoryManager()->allocateGraphicsMemoryWithProperties({device.getRootDeviceIndex(), size, allocationType});
|
||||
DEBUG_BREAK_IF(gpuAlloc == nullptr);
|
||||
if (gpuAlloc == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
memcpy_s(gpuAlloc->getUnderlyingBuffer(), gpuAlloc->getUnderlyingBufferSize(), initData, size);
|
||||
return gpuAlloc;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
23
core/program/program_initialization.h
Normal file
23
core/program/program_initialization.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
class Device;
|
||||
class GraphicsAllocation;
|
||||
class SVMAllocsManager;
|
||||
struct LinkerInput;
|
||||
|
||||
GraphicsAllocation *allocateGlobalsSurface(SVMAllocsManager *const svmAllocManager, Device &device,
|
||||
size_t size, bool constant,
|
||||
LinkerInput *const linkerInput, const void *const initData);
|
||||
|
||||
} // namespace NEO
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -9,15 +9,75 @@
|
||||
|
||||
#include "core/compiler_interface/linker.h"
|
||||
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
template <class BaseClass>
|
||||
struct WhiteBox;
|
||||
|
||||
template <class BaseClass>
|
||||
struct Mock;
|
||||
|
||||
template <>
|
||||
struct WhiteBox<NEO::LinkerInput> : NEO::LinkerInput {
|
||||
using BaseClass = NEO::LinkerInput;
|
||||
|
||||
using BaseClass::dataRelocations;
|
||||
using BaseClass::exportedFunctionsSegmentId;
|
||||
using BaseClass::relocations;
|
||||
using BaseClass::symbols;
|
||||
using BaseClass::traits;
|
||||
using BaseClass::valid;
|
||||
};
|
||||
|
||||
template <typename MockT, typename ReturnT, typename... ArgsT>
|
||||
struct LightMockConfig {
|
||||
using MockReturnT = ReturnT;
|
||||
using OverrideT = std::function<ReturnT(MockT *, ArgsT...)>;
|
||||
|
||||
uint32_t timesCalled = 0U;
|
||||
OverrideT overrideFunc;
|
||||
};
|
||||
|
||||
template <typename ConfigT, typename ObjT, typename... ArgsT>
|
||||
typename ConfigT::MockReturnT invokeMocked(ConfigT &config, ObjT obj, ArgsT &&... args) {
|
||||
config.timesCalled += 1;
|
||||
if (config.overrideFunc) {
|
||||
return config.overrideFunc(obj, std::forward<ArgsT>(args)...);
|
||||
} else {
|
||||
return config.originalFunc(obj, std::forward<ArgsT>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
#define LIGHT_MOCK_OVERRIDE_2(NAME, MOCK_T, BASE_T, RETURN_T, ARG0_T, ARG1_T) \
|
||||
struct : LightMockConfig<MOCK_T, RETURN_T, ARG0_T, ARG1_T> { \
|
||||
OverrideT originalFunc = +[](BaseT *obj, ARG0_T arg0, ARG1_T arg1) -> RETURN_T { \
|
||||
return obj->BaseT::NAME(std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1)); \
|
||||
}; \
|
||||
} NAME##MockConfig; \
|
||||
\
|
||||
RETURN_T NAME(ARG0_T arg0, ARG1_T arg1) override { \
|
||||
return invokeMocked(NAME##MockConfig, this, std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1)); \
|
||||
}
|
||||
|
||||
#define LIGHT_MOCK_OVERRIDE_3(NAME, MOCK_T, BASE_T, RETURN_T, ARG0_T, ARG1_T, ARG2_T) \
|
||||
struct : LightMockConfig<MOCK_T, RETURN_T, ARG0_T, ARG1_T, ARG2_T> { \
|
||||
OverrideT originalFunc = +[](BaseT *obj, ARG0_T arg0, ARG1_T arg1, ARG2_T arg2) -> RETURN_T { \
|
||||
return obj->BaseT::NAME(std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1), std::forward<ARG2_T>(arg2)); \
|
||||
}; \
|
||||
} NAME##MockConfig; \
|
||||
\
|
||||
RETURN_T NAME(ARG0_T arg0, ARG1_T arg1, ARG2_T arg2) override { \
|
||||
return invokeMocked(NAME##MockConfig, this, std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1), std::forward<ARG2_T>(arg2)); \
|
||||
}
|
||||
|
||||
template <>
|
||||
struct Mock<NEO::LinkerInput> : WhiteBox<NEO::LinkerInput> {
|
||||
using ThisT = Mock<NEO::LinkerInput>;
|
||||
using BaseT = NEO::LinkerInput;
|
||||
using WhiteBoxBaseT = WhiteBox<BaseT>;
|
||||
|
||||
LIGHT_MOCK_OVERRIDE_2(decodeGlobalVariablesSymbolTable, ThisT, BaseT, bool, const void *, uint32_t);
|
||||
LIGHT_MOCK_OVERRIDE_3(decodeExportedFunctionsSymbolTable, ThisT, BaseT, bool, const void *, uint32_t, uint32_t);
|
||||
LIGHT_MOCK_OVERRIDE_3(decodeRelocationTable, ThisT, BaseT, bool, const void *, uint32_t, uint32_t);
|
||||
};
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/helpers/ptr_math.h"
|
||||
|
||||
#include "RelocationInfo.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "linker_mock.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "RelocationInfo.h"
|
||||
TEST(SegmentTypeTests, givenSegmentTypeWhenAsStringIsCalledThenProperRepresentationIsReturned) {
|
||||
EXPECT_STREQ("UNKOWN", NEO::asString(NEO::SegmentType::Unknown));
|
||||
EXPECT_STREQ("GLOBAL_CONSTANTS", NEO::asString(NEO::SegmentType::GlobalConstants));
|
||||
EXPECT_STREQ("GLOBAL_VARIABLES", NEO::asString(NEO::SegmentType::GlobalVariables));
|
||||
EXPECT_STREQ("INSTRUCTIONS", NEO::asString(NEO::SegmentType::Instructions));
|
||||
}
|
||||
|
||||
TEST(LinkerInputTraitsTests, whenPointerSizeNotSizeThenDefaultsToHostPointerSize) {
|
||||
using PointerSize = NEO::LinkerInput::Traits::PointerSize;
|
||||
auto expectedPointerSize = (sizeof(void *) == 4) ? PointerSize::Ptr32bit : PointerSize::Ptr64bit;
|
||||
auto pointerSize = NEO::LinkerInput::Traits{}.pointerSize;
|
||||
EXPECT_EQ(expectedPointerSize, pointerSize);
|
||||
}
|
||||
|
||||
TEST(LinkerInputTests, givenGlobalsSymbolTableThenProperlyDecodesGlobalVariablesAndGlobalConstants) {
|
||||
NEO::LinkerInput linkerInput;
|
||||
EXPECT_TRUE(linkerInput.isValid());
|
||||
vISA::GenSymEntry entry[2] = {{}, {}};
|
||||
entry[0].s_name[0] = 'A';
|
||||
entry[0].s_offset = 8;
|
||||
@@ -33,6 +49,7 @@ TEST(LinkerInputTests, givenGlobalsSymbolTableThenProperlyDecodesGlobalVariables
|
||||
|
||||
auto decodeResult = linkerInput.decodeGlobalVariablesSymbolTable(entry, 2);
|
||||
EXPECT_TRUE(decodeResult);
|
||||
EXPECT_TRUE(linkerInput.isValid());
|
||||
|
||||
EXPECT_EQ(2U, linkerInput.getSymbols().size());
|
||||
EXPECT_TRUE(linkerInput.getTraits().exportsGlobalVariables);
|
||||
@@ -44,13 +61,13 @@ TEST(LinkerInputTests, givenGlobalsSymbolTableThenProperlyDecodesGlobalVariables
|
||||
ASSERT_NE(linkerInput.getSymbols().end(), symbolA);
|
||||
EXPECT_EQ(entry[0].s_offset, symbolA->second.offset);
|
||||
EXPECT_EQ(entry[0].s_size, symbolA->second.size);
|
||||
EXPECT_EQ(NEO::SymbolInfo::GlobalVariable, symbolA->second.type);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalVariables, symbolA->second.segment);
|
||||
|
||||
auto symbolB = linkerInput.getSymbols().find("B");
|
||||
ASSERT_NE(linkerInput.getSymbols().end(), symbolB);
|
||||
EXPECT_EQ(entry[1].s_offset, symbolB->second.offset);
|
||||
EXPECT_EQ(entry[1].s_size, symbolB->second.size);
|
||||
EXPECT_EQ(NEO::SymbolInfo::GlobalConstant, symbolB->second.type);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalConstants, symbolB->second.segment);
|
||||
|
||||
auto symbolC = linkerInput.getSymbols().find("C");
|
||||
EXPECT_EQ(linkerInput.getSymbols().end(), symbolC);
|
||||
@@ -78,6 +95,7 @@ TEST(LinkerInputTests, givenFunctionsSymbolTableThenProperlyDecodesGlobalVariabl
|
||||
|
||||
auto decodeResult = linkerInput.decodeExportedFunctionsSymbolTable(entry, 2, 3);
|
||||
EXPECT_TRUE(decodeResult);
|
||||
EXPECT_TRUE(linkerInput.isValid());
|
||||
|
||||
EXPECT_EQ(2U, linkerInput.getSymbols().size());
|
||||
EXPECT_TRUE(linkerInput.getTraits().exportsGlobalVariables);
|
||||
@@ -89,13 +107,13 @@ TEST(LinkerInputTests, givenFunctionsSymbolTableThenProperlyDecodesGlobalVariabl
|
||||
ASSERT_NE(linkerInput.getSymbols().end(), symbolA);
|
||||
EXPECT_EQ(entry[0].s_offset, symbolA->second.offset);
|
||||
EXPECT_EQ(entry[0].s_size, symbolA->second.size);
|
||||
EXPECT_EQ(NEO::SymbolInfo::GlobalVariable, symbolA->second.type);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalVariables, symbolA->second.segment);
|
||||
|
||||
auto symbolB = linkerInput.getSymbols().find("B");
|
||||
ASSERT_NE(linkerInput.getSymbols().end(), symbolB);
|
||||
EXPECT_EQ(entry[1].s_offset, symbolB->second.offset);
|
||||
EXPECT_EQ(entry[1].s_size, symbolB->second.size);
|
||||
EXPECT_EQ(NEO::SymbolInfo::GlobalConstant, symbolB->second.type);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalConstants, symbolB->second.segment);
|
||||
|
||||
auto symbolC = linkerInput.getSymbols().find("C");
|
||||
EXPECT_EQ(linkerInput.getSymbols().end(), symbolC);
|
||||
@@ -111,6 +129,7 @@ TEST(LinkerInputTests, givenGlobalsSymbolTableThenFunctionExportsAreNotAllowed)
|
||||
|
||||
auto decodeResult = linkerInput.decodeGlobalVariablesSymbolTable(&entry, 1);
|
||||
EXPECT_FALSE(decodeResult);
|
||||
EXPECT_FALSE(linkerInput.isValid());
|
||||
}
|
||||
|
||||
TEST(LinkerInputTests, givenFunctionsSymbolTableThenProperlyDecodesExportedFunctions) {
|
||||
@@ -134,6 +153,7 @@ TEST(LinkerInputTests, givenFunctionsSymbolTableThenProperlyDecodesExportedFunct
|
||||
|
||||
auto decodeResult = linkerInput.decodeExportedFunctionsSymbolTable(entry, 2, 3);
|
||||
EXPECT_TRUE(decodeResult);
|
||||
EXPECT_TRUE(linkerInput.isValid());
|
||||
|
||||
EXPECT_EQ(2U, linkerInput.getSymbols().size());
|
||||
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalVariables);
|
||||
@@ -145,13 +165,13 @@ TEST(LinkerInputTests, givenFunctionsSymbolTableThenProperlyDecodesExportedFunct
|
||||
ASSERT_NE(linkerInput.getSymbols().end(), symbolA);
|
||||
EXPECT_EQ(entry[0].s_offset, symbolA->second.offset);
|
||||
EXPECT_EQ(entry[0].s_size, symbolA->second.size);
|
||||
EXPECT_EQ(NEO::SymbolInfo::Function, symbolA->second.type);
|
||||
EXPECT_EQ(NEO::SegmentType::Instructions, symbolA->second.segment);
|
||||
|
||||
auto symbolB = linkerInput.getSymbols().find("B");
|
||||
ASSERT_NE(linkerInput.getSymbols().end(), symbolB);
|
||||
EXPECT_EQ(entry[1].s_offset, symbolB->second.offset);
|
||||
EXPECT_EQ(entry[1].s_size, symbolB->second.size);
|
||||
EXPECT_EQ(NEO::SymbolInfo::Function, symbolB->second.type);
|
||||
EXPECT_EQ(NEO::SegmentType::Instructions, symbolB->second.segment);
|
||||
|
||||
EXPECT_EQ(3, linkerInput.getExportedFunctionsSegmentId());
|
||||
}
|
||||
@@ -166,6 +186,7 @@ TEST(LinkerInputTests, givenFunctionsSymbolTableThenUndefIsNotAllowed) {
|
||||
|
||||
auto decodeResult = linkerInput.decodeExportedFunctionsSymbolTable(&entry, 1, 3);
|
||||
EXPECT_FALSE(decodeResult);
|
||||
EXPECT_FALSE(linkerInput.isValid());
|
||||
}
|
||||
|
||||
TEST(LinkerInputTests, givenRelocationTableThenRelocationEntriesAreProperlyParsed) {
|
||||
@@ -186,9 +207,10 @@ TEST(LinkerInputTests, givenRelocationTableThenRelocationEntriesAreProperlyParse
|
||||
|
||||
decodeResult = linkerInput.decodeRelocationTable(&entry, 1, 1);
|
||||
EXPECT_TRUE(decodeResult);
|
||||
EXPECT_TRUE(linkerInput.isValid());
|
||||
}
|
||||
|
||||
TEST(LinkerInputTests, givenRelocationTableThenNoneIsNotAllowed) {
|
||||
TEST(LinkerInputTests, givenRelocationTableThenNoneAsRelocationTypeIsNotAllowed) {
|
||||
NEO::LinkerInput linkerInput;
|
||||
vISA::GenRelocEntry entry = {};
|
||||
entry.r_symbol[0] = 'A';
|
||||
@@ -197,22 +219,74 @@ TEST(LinkerInputTests, givenRelocationTableThenNoneIsNotAllowed) {
|
||||
|
||||
auto decodeResult = linkerInput.decodeRelocationTable(&entry, 1, 3);
|
||||
EXPECT_FALSE(decodeResult);
|
||||
EXPECT_FALSE(linkerInput.isValid());
|
||||
}
|
||||
|
||||
TEST(LinkerInputTests, whenDataRelocationsAreAddedThenProperTraitsAreSet) {
|
||||
NEO::LinkerInput linkerInput;
|
||||
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalConstantsBuffer);
|
||||
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalVariablesBuffer);
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocInfo;
|
||||
relocInfo.offset = 7U;
|
||||
relocInfo.relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocInfo.symbolName = "aaa";
|
||||
relocInfo.symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
linkerInput.addDataRelocationInfo(relocInfo);
|
||||
ASSERT_EQ(1U, linkerInput.getDataRelocations().size());
|
||||
EXPECT_EQ(relocInfo.offset, linkerInput.getDataRelocations()[0].offset);
|
||||
EXPECT_EQ(relocInfo.relocationSegment, linkerInput.getDataRelocations()[0].relocationSegment);
|
||||
EXPECT_EQ(relocInfo.symbolName, linkerInput.getDataRelocations()[0].symbolName);
|
||||
EXPECT_EQ(relocInfo.symbolSegment, linkerInput.getDataRelocations()[0].symbolSegment);
|
||||
EXPECT_EQ(relocInfo.type, linkerInput.getDataRelocations()[0].type);
|
||||
EXPECT_TRUE(linkerInput.getTraits().requiresPatchingOfGlobalConstantsBuffer);
|
||||
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalVariablesBuffer);
|
||||
EXPECT_TRUE(linkerInput.isValid());
|
||||
|
||||
linkerInput = {};
|
||||
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalConstantsBuffer);
|
||||
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalVariablesBuffer);
|
||||
relocInfo.relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocInfo.symbolSegment = NEO::SegmentType::GlobalConstants;
|
||||
linkerInput.addDataRelocationInfo(relocInfo);
|
||||
ASSERT_EQ(1U, linkerInput.getDataRelocations().size());
|
||||
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalConstantsBuffer);
|
||||
EXPECT_TRUE(linkerInput.getTraits().requiresPatchingOfGlobalVariablesBuffer);
|
||||
EXPECT_TRUE(linkerInput.isValid());
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenEmptyLinkerInputThenLinkerOutputIsEmpty) {
|
||||
NEO::LinkerInput linkerInput;
|
||||
NEO::Linker linker(linkerInput);
|
||||
NEO::Linker::Segment globalVar, globalConst, exportedFunc;
|
||||
NEO::Linker::SegmentInfo globalVar, globalConst, exportedFunc;
|
||||
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
bool linkResult = linker.link(globalVar, globalConst, exportedFunc, patchableInstructionSegments, unresolvedExternals);
|
||||
bool linkResult = linker.link(globalVar, globalConst, exportedFunc,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals);
|
||||
EXPECT_TRUE(linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, relocatedSymbols.size());
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenUnresolvedExternalThenLinkerFails) {
|
||||
TEST(LinkerTests, givenInvalidLinkerInputThenLinkerFails) {
|
||||
WhiteBox<NEO::LinkerInput> mockLinkerInput;
|
||||
mockLinkerInput.valid = false;
|
||||
NEO::Linker linker(mockLinkerInput);
|
||||
NEO::Linker::SegmentInfo globalVar, globalConst, exportedFunc;
|
||||
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
bool linkResult = linker.link(globalVar, globalConst, exportedFunc,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals);
|
||||
EXPECT_FALSE(linkResult);
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenUnresolvedExternalWhenPatchingInstructionsThenLinkerFails) {
|
||||
NEO::LinkerInput linkerInput;
|
||||
vISA::GenRelocEntry entry = {};
|
||||
entry.r_symbol[0] = 'A';
|
||||
@@ -222,7 +296,7 @@ TEST(LinkerTests, givenUnresolvedExternalThenLinkerFails) {
|
||||
EXPECT_TRUE(decodeResult);
|
||||
|
||||
NEO::Linker linker(linkerInput);
|
||||
NEO::Linker::Segment globalVar, globalConst, exportedFunc;
|
||||
NEO::Linker::SegmentInfo globalVar, globalConst, exportedFunc;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
|
||||
std::vector<char> instructionSegment;
|
||||
@@ -230,9 +304,12 @@ TEST(LinkerTests, givenUnresolvedExternalThenLinkerFails) {
|
||||
NEO::Linker::PatchableSegment seg0;
|
||||
seg0.hostPointer = instructionSegment.data();
|
||||
seg0.segmentSize = instructionSegment.size();
|
||||
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
|
||||
bool linkResult = linker.link(globalVar, globalConst, exportedFunc, patchableInstructionSegments, unresolvedExternals);
|
||||
bool linkResult = linker.link(globalVar, globalConst, exportedFunc,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals);
|
||||
EXPECT_FALSE(linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, relocatedSymbols.size());
|
||||
@@ -299,7 +376,7 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsThenInstructionSegmentsArePrope
|
||||
EXPECT_TRUE(decodeRelocSuccess);
|
||||
|
||||
NEO::Linker linker(linkerInput);
|
||||
NEO::Linker::Segment globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
globalVarSegment.gpuAddress = 8;
|
||||
globalVarSegment.segmentSize = 64;
|
||||
globalConstSegment.gpuAddress = 128;
|
||||
@@ -315,9 +392,10 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsThenInstructionSegmentsArePrope
|
||||
seg0.hostPointer = instructionSegment.data();
|
||||
seg0.segmentSize = instructionSegment.size();
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
|
||||
|
||||
bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableInstructionSegments, unresolvedExternals);
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals);
|
||||
EXPECT_TRUE(linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
@@ -347,7 +425,7 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsThenInstructionSegmentsArePrope
|
||||
EXPECT_EQ(initData, *reinterpret_cast<const uint32_t *>(instructionSegment.data() + relocCPartHigh.r_offset + sizeof(uint32_t)));
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenInvalidSymbolOffsetThenRelocationFails) {
|
||||
TEST(LinkerTests, givenInvalidSymbolOffsetWhenPatchingInstructionsThenRelocationFails) {
|
||||
NEO::LinkerInput linkerInput;
|
||||
|
||||
vISA::GenSymEntry symGlobalVariable = {};
|
||||
@@ -359,7 +437,7 @@ TEST(LinkerTests, givenInvalidSymbolOffsetThenRelocationFails) {
|
||||
EXPECT_TRUE(decodeSymSuccess);
|
||||
|
||||
NEO::Linker linker(linkerInput);
|
||||
NEO::Linker::Segment globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
globalVarSegment.gpuAddress = 8;
|
||||
globalVarSegment.segmentSize = symGlobalVariable.s_offset;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
@@ -370,9 +448,11 @@ TEST(LinkerTests, givenInvalidSymbolOffsetThenRelocationFails) {
|
||||
seg0.hostPointer = instructionSegment.data();
|
||||
seg0.segmentSize = instructionSegment.size();
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
|
||||
|
||||
bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableInstructionSegments, unresolvedExternals);
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals);
|
||||
EXPECT_FALSE(linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
@@ -380,11 +460,11 @@ TEST(LinkerTests, givenInvalidSymbolOffsetThenRelocationFails) {
|
||||
|
||||
globalVarSegment.segmentSize = symGlobalVariable.s_offset + symGlobalVariable.s_size;
|
||||
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableInstructionSegments, unresolvedExternals);
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals);
|
||||
EXPECT_TRUE(linkResult);
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfIsaFails) {
|
||||
TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfInstructionsFails) {
|
||||
NEO::LinkerInput linkerInput;
|
||||
|
||||
vISA::GenSymEntry symGlobalVariable = {};
|
||||
@@ -403,7 +483,7 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfIsaFails) {
|
||||
EXPECT_TRUE(decodeRelocSuccess);
|
||||
|
||||
NEO::Linker linker(linkerInput);
|
||||
NEO::Linker::Segment globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
globalVarSegment.gpuAddress = 8;
|
||||
globalVarSegment.segmentSize = symGlobalVariable.s_offset + symGlobalVariable.s_size;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
@@ -414,9 +494,11 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfIsaFails) {
|
||||
seg0.hostPointer = instructionSegment.data();
|
||||
seg0.segmentSize = relocA.r_offset;
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
|
||||
|
||||
bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableInstructionSegments, unresolvedExternals);
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals);
|
||||
EXPECT_FALSE(linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(1U, relocatedSymbols.size());
|
||||
@@ -425,11 +507,12 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfIsaFails) {
|
||||
|
||||
patchableInstructionSegments[0].segmentSize = relocA.r_offset + sizeof(uintptr_t);
|
||||
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableInstructionSegments, unresolvedExternals);
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals);
|
||||
EXPECT_TRUE(linkResult);
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenUnknownSymbolTypeThenRelocationFails) {
|
||||
TEST(LinkerTests, givenUnknownSymbolTypeWhenPatchingInstructionsThenRelocationFails) {
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
|
||||
vISA::GenSymEntry symGlobalVariable = {};
|
||||
@@ -448,7 +531,7 @@ TEST(LinkerTests, givenUnknownSymbolTypeThenRelocationFails) {
|
||||
EXPECT_TRUE(decodeRelocSuccess);
|
||||
|
||||
NEO::Linker linker(linkerInput);
|
||||
NEO::Linker::Segment globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
globalVarSegment.gpuAddress = 8;
|
||||
globalVarSegment.segmentSize = 64;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
@@ -459,30 +542,407 @@ TEST(LinkerTests, givenUnknownSymbolTypeThenRelocationFails) {
|
||||
seg0.hostPointer = instructionSegment.data();
|
||||
seg0.segmentSize = instructionSegment.size();
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
|
||||
|
||||
ASSERT_EQ(1U, linkerInput.symbols.count("A"));
|
||||
linkerInput.symbols["A"].type = NEO::SymbolInfo::Unknown;
|
||||
linkerInput.symbols["A"].segment = NEO::SegmentType::Unknown;
|
||||
bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableInstructionSegments, unresolvedExternals);
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals);
|
||||
EXPECT_FALSE(linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, relocatedSymbols.size());
|
||||
ASSERT_EQ(0U, unresolvedExternals.size());
|
||||
|
||||
linkerInput.symbols["A"].type = NEO::SymbolInfo::GlobalVariable;
|
||||
linkerInput.symbols["A"].segment = NEO::SegmentType::GlobalVariables;
|
||||
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableInstructionSegments, unresolvedExternals);
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals);
|
||||
EXPECT_TRUE(linkResult);
|
||||
}
|
||||
|
||||
TEST(LinkerErrorMessageTests, whenNoUnresolvedExternalsThenInternalError) {
|
||||
TEST(LinkerTests, givenInvalidSourceSegmentWhenPatchingDataSegmentsThenLinkerFails) {
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
NEO::Linker linker(linkerInput);
|
||||
|
||||
NEO::Linker::SegmentInfo emptySegmentInfo;
|
||||
NEO::Linker::PatchableSegment emptyPatchableSegment;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
|
||||
std::vector<char> nonEmptypatchableSegmentData;
|
||||
nonEmptypatchableSegmentData.resize(64, 8U);
|
||||
NEO::Linker::PatchableSegment nonEmptypatchableSegment;
|
||||
nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data();
|
||||
nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size();
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocInfo;
|
||||
relocInfo.offset = 0U;
|
||||
relocInfo.symbolName = "aaa";
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
linkerInput.dataRelocations.push_back(relocInfo);
|
||||
|
||||
{
|
||||
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true;
|
||||
linkerInput.traits.requiresPatchingOfGlobalConstantsBuffer = false;
|
||||
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::Unknown;
|
||||
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
nonEmptypatchableSegment, emptyPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_FALSE(linkResult);
|
||||
EXPECT_EQ(1U, unresolvedExternals.size());
|
||||
|
||||
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
unresolvedExternals.clear();
|
||||
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
nonEmptypatchableSegment, emptyPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_TRUE(linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
}
|
||||
|
||||
{
|
||||
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = false;
|
||||
linkerInput.traits.requiresPatchingOfGlobalConstantsBuffer = true;
|
||||
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::Unknown;
|
||||
unresolvedExternals.clear();
|
||||
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
emptyPatchableSegment, nonEmptypatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_FALSE(linkResult);
|
||||
EXPECT_EQ(1U, unresolvedExternals.size());
|
||||
|
||||
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
unresolvedExternals.clear();
|
||||
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
emptyPatchableSegment, nonEmptypatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_TRUE(linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenUnknownRelocationSegmentWhenPatchingDataSegmentsThenLinkerFails) {
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
NEO::Linker linker(linkerInput);
|
||||
|
||||
NEO::Linker::SegmentInfo emptySegmentInfo;
|
||||
NEO::Linker::PatchableSegment emptyPatchableSegment;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
|
||||
std::vector<char> nonEmptypatchableSegmentData;
|
||||
nonEmptypatchableSegmentData.resize(64, 8U);
|
||||
NEO::Linker::PatchableSegment nonEmptypatchableSegment;
|
||||
nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data();
|
||||
nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size();
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocInfo;
|
||||
relocInfo.offset = 0U;
|
||||
relocInfo.symbolName = "aaa";
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
linkerInput.dataRelocations.push_back(relocInfo);
|
||||
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::Unknown;
|
||||
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true;
|
||||
|
||||
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
nonEmptypatchableSegment, emptyPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_FALSE(linkResult);
|
||||
EXPECT_EQ(1U, unresolvedExternals.size());
|
||||
|
||||
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
unresolvedExternals.clear();
|
||||
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
nonEmptypatchableSegment, emptyPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_TRUE(linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenRelocationTypeWithHighPartOfAddressWhenPatchingDataSegmentsThenLinkerFails) {
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
NEO::Linker linker(linkerInput);
|
||||
|
||||
NEO::Linker::SegmentInfo emptySegmentInfo;
|
||||
NEO::Linker::PatchableSegment emptyPatchableSegment;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
|
||||
std::vector<char> nonEmptypatchableSegmentData;
|
||||
nonEmptypatchableSegmentData.resize(64, 8U);
|
||||
NEO::Linker::PatchableSegment nonEmptypatchableSegment;
|
||||
nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data();
|
||||
nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size();
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocInfo;
|
||||
relocInfo.offset = 0U;
|
||||
relocInfo.symbolName = "aaa";
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::AddressHigh;
|
||||
linkerInput.dataRelocations.push_back(relocInfo);
|
||||
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true;
|
||||
|
||||
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
nonEmptypatchableSegment, emptyPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_FALSE(linkResult);
|
||||
EXPECT_EQ(1U, unresolvedExternals.size());
|
||||
|
||||
linkerInput.dataRelocations[0].type = NEO::LinkerInput::RelocationInfo::Type::AddressLow;
|
||||
unresolvedExternals.clear();
|
||||
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
nonEmptypatchableSegment, emptyPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_TRUE(linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenValidSymbolsAndRelocationsThenDataSegmentsAreProperlyPatched) {
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
NEO::Linker linker(linkerInput);
|
||||
|
||||
std::vector<char> globalConstantsSegmentData;
|
||||
globalConstantsSegmentData.resize(128, 7U);
|
||||
|
||||
std::vector<char> globalVariablesSegmentData;
|
||||
globalVariablesSegmentData.resize(256, 13U);
|
||||
|
||||
NEO::Linker::SegmentInfo globalConstantsSegmentInfo, globalVariablesSegmentInfo;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
|
||||
NEO::Linker::PatchableSegment globalConstantsPatchableSegment, globalVariablesPatchableSegment;
|
||||
globalConstantsSegmentInfo.gpuAddress = reinterpret_cast<uintptr_t>(globalConstantsSegmentData.data());
|
||||
globalConstantsSegmentInfo.segmentSize = globalConstantsSegmentData.size();
|
||||
globalConstantsPatchableSegment.hostPointer = globalConstantsSegmentData.data();
|
||||
globalConstantsPatchableSegment.segmentSize = globalConstantsSegmentData.size();
|
||||
|
||||
globalVariablesSegmentInfo.gpuAddress = reinterpret_cast<uintptr_t>(globalVariablesSegmentData.data());
|
||||
globalVariablesSegmentInfo.segmentSize = globalVariablesSegmentData.size();
|
||||
globalVariablesPatchableSegment.hostPointer = globalVariablesSegmentData.data();
|
||||
globalVariablesPatchableSegment.segmentSize = globalVariablesSegmentData.size();
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocationInfo[5];
|
||||
// GlobalVar -> GlobalVar
|
||||
relocationInfo[0].offset = 8U;
|
||||
relocationInfo[0].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[0].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[0].type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
|
||||
// GlobalConst -> GlobalVar
|
||||
relocationInfo[1].offset = 24U;
|
||||
relocationInfo[1].relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocationInfo[1].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[1].type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
|
||||
// GlobalConst -> GlobalConst
|
||||
relocationInfo[2].offset = 40U;
|
||||
relocationInfo[2].relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocationInfo[2].symbolSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocationInfo[2].type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
|
||||
// GlobalVar -> GlobalConst
|
||||
relocationInfo[3].offset = 56U;
|
||||
relocationInfo[3].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[3].symbolSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocationInfo[3].type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
|
||||
// GlobalVar Low -> GlobalVar
|
||||
relocationInfo[4].offset = 72;
|
||||
relocationInfo[4].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[4].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[4].type = NEO::LinkerInput::RelocationInfo::Type::AddressLow;
|
||||
|
||||
uint32_t initValue = 0;
|
||||
for (const auto &reloc : relocationInfo) {
|
||||
linkerInput.addDataRelocationInfo(reloc);
|
||||
void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
|
||||
if (reloc.type == NEO::LinkerInput::RelocationInfo::Type::Address) {
|
||||
*reinterpret_cast<uintptr_t *>(ptrOffset(dstRaw, static_cast<size_t>(reloc.offset))) = initValue * 4; // relocations to global data are currently based on patchIncrement, simulate init data
|
||||
} else {
|
||||
*reinterpret_cast<uint32_t *>(ptrOffset(dstRaw, static_cast<size_t>(reloc.offset))) = initValue * 4; // relocations to global data are currently based on patchIncrement, simulate init data
|
||||
}
|
||||
++initValue;
|
||||
}
|
||||
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {},
|
||||
globalVariablesPatchableSegment, globalConstantsPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
EXPECT_TRUE(linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
EXPECT_EQ(7U, *reinterpret_cast<uint8_t *>(globalConstantsPatchableSegment.hostPointer));
|
||||
EXPECT_EQ(13U, *reinterpret_cast<uint8_t *>(globalVariablesPatchableSegment.hostPointer));
|
||||
|
||||
initValue = 0;
|
||||
for (const auto &reloc : relocationInfo) {
|
||||
void *srcRaw = (reloc.symbolSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
|
||||
void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
|
||||
uint8_t *src = reinterpret_cast<uint8_t *>(srcRaw);
|
||||
uint8_t *dst = reinterpret_cast<uint8_t *>(dstRaw);
|
||||
|
||||
// make sure no buffer underflow occured
|
||||
EXPECT_EQ(dst[0], dst[reloc.offset - 1]);
|
||||
|
||||
// check patch-incremented value
|
||||
if (reloc.type == NEO::LinkerInput::RelocationInfo::Type::Address) {
|
||||
// make sure no buffer overflow occured
|
||||
EXPECT_EQ(dst[0], dst[reloc.offset + sizeof(uintptr_t)]);
|
||||
EXPECT_EQ(reinterpret_cast<uintptr_t>(src) + initValue * 4, *reinterpret_cast<uintptr_t *>(dst + reloc.offset)) << initValue;
|
||||
} else {
|
||||
// make sure no buffer overflow occured
|
||||
EXPECT_EQ(dst[0], dst[reloc.offset + sizeof(uint32_t)]);
|
||||
EXPECT_EQ(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(src)) + initValue * 4, *reinterpret_cast<uint32_t *>(dst + reloc.offset)) << initValue;
|
||||
}
|
||||
++initValue;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenValidSymbolsAndRelocationsWhenPatchin32bitBinaryThenDataSegmentsAreProperlyPatchedWithLowerPartOfTheAddress) {
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
linkerInput.setPointerSize(NEO::LinkerInput::Traits::PointerSize::Ptr32bit);
|
||||
NEO::Linker linker(linkerInput);
|
||||
|
||||
std::vector<char> globalConstantsSegmentData;
|
||||
globalConstantsSegmentData.resize(128, 7U);
|
||||
|
||||
std::vector<char> globalVariablesSegmentData;
|
||||
globalVariablesSegmentData.resize(256, 13U);
|
||||
|
||||
NEO::Linker::SegmentInfo globalConstantsSegmentInfo, globalVariablesSegmentInfo;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
|
||||
NEO::Linker::PatchableSegment globalConstantsPatchableSegment, globalVariablesPatchableSegment;
|
||||
globalConstantsSegmentInfo.gpuAddress = reinterpret_cast<uintptr_t>(globalConstantsSegmentData.data());
|
||||
globalConstantsSegmentInfo.segmentSize = globalConstantsSegmentData.size();
|
||||
globalConstantsPatchableSegment.hostPointer = globalConstantsSegmentData.data();
|
||||
globalConstantsPatchableSegment.segmentSize = globalConstantsSegmentData.size();
|
||||
|
||||
globalVariablesSegmentInfo.gpuAddress = reinterpret_cast<uintptr_t>(globalVariablesSegmentData.data());
|
||||
globalVariablesSegmentInfo.segmentSize = globalVariablesSegmentData.size();
|
||||
globalVariablesPatchableSegment.hostPointer = globalVariablesSegmentData.data();
|
||||
globalVariablesPatchableSegment.segmentSize = globalVariablesSegmentData.size();
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocationInfo[5];
|
||||
// GlobalVar -> GlobalVar
|
||||
relocationInfo[0].offset = 8U;
|
||||
relocationInfo[0].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[0].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[0].type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
|
||||
// GlobalConst -> GlobalVar
|
||||
relocationInfo[1].offset = 24U;
|
||||
relocationInfo[1].relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocationInfo[1].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[1].type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
|
||||
// GlobalConst -> GlobalConst
|
||||
relocationInfo[2].offset = 40U;
|
||||
relocationInfo[2].relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocationInfo[2].symbolSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocationInfo[2].type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
|
||||
// GlobalVar -> GlobalConst
|
||||
relocationInfo[3].offset = 56U;
|
||||
relocationInfo[3].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[3].symbolSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocationInfo[3].type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
|
||||
// GlobalVar Low -> GlobalVar
|
||||
relocationInfo[4].offset = 72;
|
||||
relocationInfo[4].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[4].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocationInfo[4].type = NEO::LinkerInput::RelocationInfo::Type::AddressLow;
|
||||
|
||||
uint32_t initValue = 0;
|
||||
for (const auto &reloc : relocationInfo) {
|
||||
linkerInput.addDataRelocationInfo(reloc);
|
||||
void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
|
||||
*reinterpret_cast<uint32_t *>(ptrOffset(dstRaw, static_cast<size_t>(reloc.offset))) = initValue * 4; // relocations to global data are currently based on patchIncrement, simulate init data
|
||||
++initValue;
|
||||
}
|
||||
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {},
|
||||
globalVariablesPatchableSegment, globalConstantsPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
EXPECT_TRUE(linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
EXPECT_EQ(7U, *reinterpret_cast<uint8_t *>(globalConstantsPatchableSegment.hostPointer));
|
||||
EXPECT_EQ(13U, *reinterpret_cast<uint8_t *>(globalVariablesPatchableSegment.hostPointer));
|
||||
|
||||
initValue = 0;
|
||||
for (const auto &reloc : relocationInfo) {
|
||||
void *srcRaw = (reloc.symbolSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
|
||||
void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
|
||||
uint8_t *src = reinterpret_cast<uint8_t *>(srcRaw);
|
||||
uint8_t *dst = reinterpret_cast<uint8_t *>(dstRaw);
|
||||
|
||||
// make sure no buffer under/overflow occured
|
||||
EXPECT_EQ(dst[0], dst[reloc.offset - 1]);
|
||||
EXPECT_EQ(dst[0], dst[reloc.offset + sizeof(uint32_t)]);
|
||||
|
||||
// check patch-incremented value
|
||||
EXPECT_EQ(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(src)) + initValue * 4, *reinterpret_cast<uint32_t *>(dst + reloc.offset)) << initValue;
|
||||
++initValue;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfDataSegmentsFails) {
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
NEO::Linker linker(linkerInput);
|
||||
|
||||
NEO::Linker::SegmentInfo emptySegmentInfo;
|
||||
NEO::Linker::PatchableSegment emptyPatchableSegment;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
|
||||
std::vector<char> nonEmptypatchableSegmentData;
|
||||
nonEmptypatchableSegmentData.resize(64, 8U);
|
||||
NEO::Linker::PatchableSegment nonEmptypatchableSegment;
|
||||
nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data();
|
||||
nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size();
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocInfo;
|
||||
relocInfo.offset = 64U;
|
||||
relocInfo.symbolName = "aaa";
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
linkerInput.dataRelocations.push_back(relocInfo);
|
||||
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true;
|
||||
|
||||
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
nonEmptypatchableSegment, emptyPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_FALSE(linkResult);
|
||||
EXPECT_EQ(1U, unresolvedExternals.size());
|
||||
|
||||
linkerInput.dataRelocations[0].offset = 32;
|
||||
unresolvedExternals.clear();
|
||||
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
|
||||
nonEmptypatchableSegment, emptyPatchableSegment, {},
|
||||
unresolvedExternals);
|
||||
|
||||
EXPECT_TRUE(linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
}
|
||||
|
||||
TEST(LinkerErrorMessageTests, whenListOfUnresolvedExternalsIsEmptyThenErrorTypeDefaultsToInternalError) {
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
std::vector<std::string> segmentsNames{"kernel1", "kernel2"};
|
||||
auto err = NEO::constructLinkerErrorMessage(unresolvedExternals, segmentsNames);
|
||||
EXPECT_EQ(std::string("Internal linker error"), err);
|
||||
}
|
||||
|
||||
TEST(LinkerErrorMessageTests, whenUnresolvedExternalsThenSymbolNameInErrorMessage) {
|
||||
TEST(LinkerErrorMessageTests, givenListOfUnresolvedExternalsThenSymbolNameOrSymbolSegmentTypeGetsEmbededInErrorMessage) {
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
std::vector<std::string> segmentsNames{"kernel1", "kernel2"};
|
||||
NEO::Linker::UnresolvedExternal unresolvedExternal = {};
|
||||
@@ -490,6 +950,7 @@ TEST(LinkerErrorMessageTests, whenUnresolvedExternalsThenSymbolNameInErrorMessag
|
||||
unresolvedExternal.internalError = false;
|
||||
unresolvedExternal.unresolvedRelocation.offset = 64;
|
||||
unresolvedExternal.unresolvedRelocation.symbolName = "arrayABC";
|
||||
unresolvedExternal.unresolvedRelocation.relocationSegment = NEO::SegmentType::Instructions;
|
||||
unresolvedExternals.push_back(unresolvedExternal);
|
||||
auto err = NEO::constructLinkerErrorMessage(unresolvedExternals, segmentsNames);
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(unresolvedExternal.unresolvedRelocation.symbolName.c_str()));
|
||||
@@ -509,4 +970,19 @@ TEST(LinkerErrorMessageTests, whenUnresolvedExternalsThenSymbolNameInErrorMessag
|
||||
EXPECT_THAT(err.c_str(), ::testing::Not(::testing::HasSubstr(segmentsNames[unresolvedExternal.instructionsSegmentId].c_str())));
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr("internal linker error"));
|
||||
|
||||
unresolvedExternals[0].unresolvedRelocation.relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
err = NEO::constructLinkerErrorMessage(unresolvedExternals, {});
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(NEO::asString(NEO::SegmentType::GlobalConstants)));
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
|
||||
|
||||
unresolvedExternals[0].unresolvedRelocation.relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
err = NEO::constructLinkerErrorMessage(unresolvedExternals, {});
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(NEO::asString(NEO::SegmentType::GlobalVariables)));
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
|
||||
|
||||
unresolvedExternals[0].unresolvedRelocation.relocationSegment = NEO::SegmentType::Unknown;
|
||||
err = NEO::constructLinkerErrorMessage(unresolvedExternals, {});
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(NEO::asString(NEO::SegmentType::Unknown)));
|
||||
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
|
||||
}
|
||||
|
||||
15
core/unit_tests/program/CMakeLists.txt
Normal file
15
core/unit_tests/program/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
set(NEO_CORE_SRCS_tests_program
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_info_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_info_from_patchtokens_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_initialization_tests.cpp
|
||||
)
|
||||
|
||||
set_property(GLOBAL PROPERTY NEO_CORE_SRCS_tests_program ${NEO_CORE_SRCS_tests_program})
|
||||
add_subdirectories()
|
||||
292
core/unit_tests/program/program_info_from_patchtokens_tests.cpp
Normal file
292
core/unit_tests/program/program_info_from_patchtokens_tests.cpp
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/compiler_interface/linker.h"
|
||||
#include "core/program/program_info.h"
|
||||
#include "core/program/program_info_from_patchtokens.h"
|
||||
#include "core/unit_tests/compiler_interface/linker_mock.h"
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
#include "runtime/program/kernel_info.h"
|
||||
#include "unit_tests/compiler_interface/patchtokens_tests.h"
|
||||
|
||||
#include "RelocationInfo.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, WhenRequiresLocalMemoryWindowVAIsCalledThenReturnsTrueOnlyIfAnyOfKernelsRequireLocalMemoryWindowVA) {
|
||||
NEO::PatchTokenBinary::ProgramFromPatchtokens emptyProgram;
|
||||
EXPECT_FALSE(NEO::requiresLocalMemoryWindowVA(emptyProgram));
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens kernelWithoutRequirementForLocalMemoryWindowWA;
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens kernelWithRequirementForLocalMemoryWindowWA;
|
||||
iOpenCL::SPatchDataParameterBuffer param;
|
||||
kernelWithRequirementForLocalMemoryWindowWA.tokens.crossThreadPayloadArgs.localMemoryStatelessWindowStartAddress = ¶m;
|
||||
|
||||
NEO::PatchTokenBinary::ProgramFromPatchtokens programWithOneKernelWithoutLocalMemWindow;
|
||||
programWithOneKernelWithoutLocalMemWindow.kernels.push_back(kernelWithoutRequirementForLocalMemoryWindowWA);
|
||||
EXPECT_FALSE(NEO::requiresLocalMemoryWindowVA(programWithOneKernelWithoutLocalMemWindow));
|
||||
|
||||
NEO::PatchTokenBinary::ProgramFromPatchtokens programWithOneKernelWithLocalMemWindow;
|
||||
programWithOneKernelWithLocalMemWindow.kernels.push_back(kernelWithRequirementForLocalMemoryWindowWA);
|
||||
EXPECT_TRUE(NEO::requiresLocalMemoryWindowVA(programWithOneKernelWithLocalMemWindow));
|
||||
|
||||
NEO::PatchTokenBinary::ProgramFromPatchtokens programWithTwoKernelsWithLocalMemWindow;
|
||||
programWithTwoKernelsWithLocalMemWindow.kernels.push_back(kernelWithoutRequirementForLocalMemoryWindowWA);
|
||||
programWithTwoKernelsWithLocalMemWindow.kernels.push_back(kernelWithRequirementForLocalMemoryWindowWA);
|
||||
EXPECT_TRUE(NEO::requiresLocalMemoryWindowVA(programWithTwoKernelsWithLocalMemWindow));
|
||||
|
||||
std::swap(programWithTwoKernelsWithLocalMemWindow.kernels[0], programWithTwoKernelsWithLocalMemWindow.kernels[1]);
|
||||
EXPECT_TRUE(NEO::requiresLocalMemoryWindowVA(programWithTwoKernelsWithLocalMemWindow));
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, WhenProgramRequiresGlobalConstantsSurfaceThenGlobalConstantsSectionIsPopulated) {
|
||||
PatchTokensTestData::ValidProgramWithConstantSurface programTokens;
|
||||
NEO::ProgramInfo programInfo;
|
||||
NEO::populateProgramInfo(programInfo, programTokens, {});
|
||||
EXPECT_EQ(programInfo.globalConstants.size, programTokens.programScopeTokens.allocateConstantMemorySurface[0]->InlineDataSize);
|
||||
EXPECT_EQ(programInfo.globalConstants.initData, NEO::PatchTokenBinary::getInlineData(programTokens.programScopeTokens.allocateConstantMemorySurface[0]));
|
||||
EXPECT_TRUE(programInfo.kernelInfos.empty());
|
||||
EXPECT_EQ(nullptr, programInfo.linkerInput);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, WhenProgramRequiresGlobalVariablesSurfaceThenGlobalConstantsSectionIsPopulated) {
|
||||
PatchTokensTestData::ValidProgramWithGlobalSurface programTokens;
|
||||
NEO::ProgramInfo programInfo;
|
||||
NEO::populateProgramInfo(programInfo, programTokens, {});
|
||||
EXPECT_EQ(programInfo.globalVariables.size, programTokens.programScopeTokens.allocateGlobalMemorySurface[0]->InlineDataSize);
|
||||
EXPECT_EQ(programInfo.globalVariables.initData, NEO::PatchTokenBinary::getInlineData(programTokens.programScopeTokens.allocateGlobalMemorySurface[0]));
|
||||
EXPECT_TRUE(programInfo.kernelInfos.empty());
|
||||
EXPECT_EQ(nullptr, programInfo.linkerInput);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, WhenProgramRequiresGlobalConstantsPointersThenLinkerInputContainsProperRelocations) {
|
||||
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer programFromTokens;
|
||||
NEO::ProgramInfo programInfo;
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
EXPECT_TRUE(programInfo.kernelInfos.empty());
|
||||
ASSERT_NE(nullptr, programInfo.linkerInput);
|
||||
ASSERT_EQ(1U, programInfo.linkerInput->getDataRelocations().size());
|
||||
auto relocation = programInfo.linkerInput->getDataRelocations()[0];
|
||||
EXPECT_EQ(programFromTokens.programScopeTokens.constantPointer[0]->ConstantPointerOffset, relocation.offset);
|
||||
EXPECT_TRUE(relocation.symbolName.empty());
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalConstants, relocation.relocationSegment);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalConstants, relocation.symbolSegment);
|
||||
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::Address, relocation.type);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, WhenProgramRequiresGlobalVariablesPointersThenLinkerInputContainsProperRelocations) {
|
||||
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer programFromTokens;
|
||||
NEO::ProgramInfo programInfo;
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
EXPECT_TRUE(programInfo.kernelInfos.empty());
|
||||
ASSERT_NE(nullptr, programInfo.linkerInput);
|
||||
ASSERT_EQ(1U, programInfo.linkerInput->getDataRelocations().size());
|
||||
auto relocation = programInfo.linkerInput->getDataRelocations()[0];
|
||||
EXPECT_EQ(NEO::readMisalignedUint64(&programFromTokens.programScopeTokens.globalPointer[0]->GlobalPointerOffset), relocation.offset);
|
||||
EXPECT_TRUE(relocation.symbolName.empty());
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalVariables, relocation.relocationSegment);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalVariables, relocation.symbolSegment);
|
||||
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::Address, relocation.type);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, WhenProgramRequiresMixedGlobalVarAndConstPointersThenLinkerInputContainsProperRelocations) {
|
||||
PatchTokensTestData::ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers programFromTokens;
|
||||
NEO::ProgramInfo programInfo;
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
EXPECT_TRUE(programInfo.kernelInfos.empty());
|
||||
ASSERT_NE(nullptr, programInfo.linkerInput);
|
||||
|
||||
const NEO::LinkerInput::RelocationInfo *relocationGlobalConst, *relocationGlobalVar;
|
||||
ASSERT_EQ(2U, programInfo.linkerInput->getDataRelocations().size());
|
||||
for (const auto &reloc : programInfo.linkerInput->getDataRelocations()) {
|
||||
switch (reloc.relocationSegment) {
|
||||
default:
|
||||
break;
|
||||
case NEO::SegmentType::GlobalConstants:
|
||||
relocationGlobalConst = &reloc;
|
||||
break;
|
||||
case NEO::SegmentType::GlobalVariables:
|
||||
relocationGlobalVar = &reloc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_NE(nullptr, relocationGlobalConst);
|
||||
EXPECT_EQ(NEO::readMisalignedUint64(&programFromTokens.programScopeTokens.constantPointer[0]->ConstantPointerOffset), relocationGlobalConst->offset);
|
||||
EXPECT_TRUE(relocationGlobalConst->symbolName.empty());
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalConstants, relocationGlobalConst->relocationSegment);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalVariables, relocationGlobalConst->symbolSegment);
|
||||
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::Address, relocationGlobalConst->type);
|
||||
|
||||
ASSERT_NE(nullptr, relocationGlobalVar);
|
||||
EXPECT_EQ(NEO::readMisalignedUint64(&programFromTokens.programScopeTokens.globalPointer[0]->GlobalPointerOffset), relocationGlobalVar->offset);
|
||||
EXPECT_TRUE(relocationGlobalVar->symbolName.empty());
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalVariables, relocationGlobalVar->relocationSegment);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalConstants, relocationGlobalVar->symbolSegment);
|
||||
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::Address, relocationGlobalVar->type);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, GivenProgramWithSpecificPointerSizeThenLinkerIsUpdatedToUseRequiredPointerSize) {
|
||||
PatchTokensTestData::ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers programFromTokens;
|
||||
programFromTokens.headerMutable->GPUPointerSizeInBytes = 8;
|
||||
NEO::ProgramInfo programInfo;
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
ASSERT_NE(nullptr, programInfo.linkerInput);
|
||||
EXPECT_EQ(NEO::LinkerInput::Traits::Ptr64bit, programInfo.linkerInput->getTraits().pointerSize);
|
||||
|
||||
programFromTokens.headerMutable->GPUPointerSizeInBytes = 4;
|
||||
programInfo = {};
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
ASSERT_NE(nullptr, programInfo.linkerInput);
|
||||
EXPECT_EQ(NEO::LinkerInput::Traits::Ptr32bit, programInfo.linkerInput->getTraits().pointerSize);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, GivenProgramWithProgramSymbolTableThenLinkerDecodesAllSymbolsCorrectly) {
|
||||
PatchTokensTestData::ValidEmptyProgram programFromTokens;
|
||||
NEO::ProgramInfo programInfo = {};
|
||||
Mock<NEO::LinkerInput> *mockLinkerInput = new Mock<NEO::LinkerInput>;
|
||||
programInfo.linkerInput.reset(mockLinkerInput);
|
||||
|
||||
vISA::GenSymEntry entry[1] = {};
|
||||
|
||||
iOpenCL::SPatchFunctionTableInfo symbolTable = {};
|
||||
symbolTable.NumEntries = 1;
|
||||
std::vector<uint8_t> symbolTableTokenStorage = {};
|
||||
symbolTableTokenStorage.insert(symbolTableTokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(&symbolTable), reinterpret_cast<uint8_t *>(&symbolTable + 1));
|
||||
symbolTableTokenStorage.insert(symbolTableTokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(entry), reinterpret_cast<uint8_t *>(entry + 1));
|
||||
programFromTokens.programScopeTokens.symbolTable = reinterpret_cast<iOpenCL::SPatchFunctionTableInfo *>(symbolTableTokenStorage.data());
|
||||
|
||||
const void *receivedData = nullptr;
|
||||
uint32_t receivedNumEntries = 0U;
|
||||
mockLinkerInput->decodeGlobalVariablesSymbolTableMockConfig.overrideFunc = [&](Mock<NEO::LinkerInput> *, const void *data, uint32_t numEntries) -> bool {
|
||||
receivedData = data;
|
||||
receivedNumEntries = numEntries;
|
||||
return true;
|
||||
};
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
|
||||
ASSERT_EQ(mockLinkerInput, programInfo.linkerInput.get());
|
||||
EXPECT_EQ(1U, mockLinkerInput->decodeGlobalVariablesSymbolTableMockConfig.timesCalled);
|
||||
EXPECT_EQ(reinterpret_cast<void *>(symbolTableTokenStorage.data() + sizeof(iOpenCL::SPatchFunctionTableInfo)), receivedData);
|
||||
EXPECT_EQ(1U, receivedNumEntries);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, GivenProgramWithKernelsThenKernelInfosIsProperlyPopulated) {
|
||||
PatchTokensTestData::ValidProgramWithKernel programFromTokens;
|
||||
programFromTokens.kernels.push_back(programFromTokens.kernels[0]);
|
||||
programFromTokens.kernels.push_back(programFromTokens.kernels[0]);
|
||||
NEO::ProgramInfo programInfo = {};
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
ASSERT_EQ(3U, programInfo.kernelInfos.size());
|
||||
EXPECT_EQ(programFromTokens.header->GPUPointerSizeInBytes, programInfo.kernelInfos[0]->gpuPointerSize);
|
||||
EXPECT_EQ(programFromTokens.header->GPUPointerSizeInBytes, programInfo.kernelInfos[1]->gpuPointerSize);
|
||||
EXPECT_EQ(programFromTokens.header->GPUPointerSizeInBytes, programInfo.kernelInfos[2]->gpuPointerSize);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, GivenProgramWithKernelsWhenKernelHasSymbolTableThenLinkerIsUpdatedWithAdditionalSymbolInfo) {
|
||||
NEO::ProgramInfo programInfo = {};
|
||||
Mock<NEO::LinkerInput> *mockLinkerInput = new Mock<NEO::LinkerInput>;
|
||||
programInfo.linkerInput.reset(mockLinkerInput);
|
||||
|
||||
PatchTokensTestData::ValidProgramWithKernel programFromTokens;
|
||||
programFromTokens.kernels.push_back(programFromTokens.kernels[0]);
|
||||
|
||||
vISA::GenSymEntry entryA[1] = {};
|
||||
|
||||
iOpenCL::SPatchFunctionTableInfo symbolTableA = {};
|
||||
symbolTableA.NumEntries = 1;
|
||||
std::vector<uint8_t> symbolTableATokenStorage = {};
|
||||
symbolTableATokenStorage.insert(symbolTableATokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(&symbolTableA), reinterpret_cast<uint8_t *>(&symbolTableA + 1));
|
||||
symbolTableATokenStorage.insert(symbolTableATokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(entryA), reinterpret_cast<uint8_t *>(entryA + 1));
|
||||
programFromTokens.kernels[0].tokens.programSymbolTable = reinterpret_cast<iOpenCL::SPatchFunctionTableInfo *>(symbolTableATokenStorage.data());
|
||||
|
||||
vISA::GenSymEntry entryB[2] = {};
|
||||
|
||||
iOpenCL::SPatchFunctionTableInfo symbolTableB = {};
|
||||
symbolTableB.NumEntries = 2;
|
||||
std::vector<uint8_t> symbolTableBTokenStorage = {};
|
||||
symbolTableBTokenStorage.insert(symbolTableBTokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(&symbolTableB), reinterpret_cast<uint8_t *>(&symbolTableB + 1));
|
||||
symbolTableBTokenStorage.insert(symbolTableBTokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(entryB), reinterpret_cast<uint8_t *>(entryB + 2));
|
||||
programFromTokens.kernels[1].tokens.programSymbolTable = reinterpret_cast<iOpenCL::SPatchFunctionTableInfo *>(symbolTableBTokenStorage.data());
|
||||
|
||||
std::vector<const void *> receivedData;
|
||||
std::vector<uint32_t> receivedNumEntries;
|
||||
std::vector<uint32_t> receivedSegmentIds;
|
||||
mockLinkerInput->decodeExportedFunctionsSymbolTableMockConfig.overrideFunc = [&](Mock<NEO::LinkerInput> *, const void *data, uint32_t numEntries, uint32_t instructionsSegmentId) -> bool {
|
||||
receivedData.push_back(data);
|
||||
receivedNumEntries.push_back(numEntries);
|
||||
receivedSegmentIds.push_back(instructionsSegmentId);
|
||||
return true;
|
||||
};
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
ASSERT_EQ(2U, mockLinkerInput->decodeExportedFunctionsSymbolTableMockConfig.timesCalled);
|
||||
ASSERT_EQ(2U, receivedData.size());
|
||||
|
||||
EXPECT_EQ(1U, receivedNumEntries[0]);
|
||||
EXPECT_EQ(2U, receivedNumEntries[1]);
|
||||
EXPECT_EQ(reinterpret_cast<void *>(symbolTableATokenStorage.data() + sizeof(iOpenCL::SPatchFunctionTableInfo)), receivedData[0]);
|
||||
EXPECT_EQ(reinterpret_cast<void *>(symbolTableBTokenStorage.data() + sizeof(iOpenCL::SPatchFunctionTableInfo)), receivedData[1]);
|
||||
EXPECT_EQ(0U, receivedSegmentIds[0]);
|
||||
EXPECT_EQ(1U, receivedSegmentIds[1]);
|
||||
}
|
||||
|
||||
TEST(PopulateProgramInfoFromPatchtokensTests, GivenProgramWithKernelsWhenKernelHasRelocationTableThenLinkerIsUpdatedWithAdditionalRelocationInfo) {
|
||||
NEO::ProgramInfo programInfo = {};
|
||||
Mock<NEO::LinkerInput> *mockLinkerInput = new Mock<NEO::LinkerInput>;
|
||||
programInfo.linkerInput.reset(mockLinkerInput);
|
||||
|
||||
PatchTokensTestData::ValidProgramWithKernel programFromTokens;
|
||||
programFromTokens.kernels.push_back(programFromTokens.kernels[0]);
|
||||
|
||||
vISA::GenRelocEntry entryA[1] = {};
|
||||
|
||||
iOpenCL::SPatchFunctionTableInfo relocationTableA = {};
|
||||
relocationTableA.NumEntries = 1;
|
||||
std::vector<uint8_t> relocationTableATokenStorage = {};
|
||||
relocationTableATokenStorage.insert(relocationTableATokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(&relocationTableA), reinterpret_cast<uint8_t *>(&relocationTableA + 1));
|
||||
relocationTableATokenStorage.insert(relocationTableATokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(entryA), reinterpret_cast<uint8_t *>(entryA + 1));
|
||||
programFromTokens.kernels[0].tokens.programRelocationTable = reinterpret_cast<iOpenCL::SPatchFunctionTableInfo *>(relocationTableATokenStorage.data());
|
||||
|
||||
vISA::GenRelocEntry entryB[2] = {};
|
||||
|
||||
iOpenCL::SPatchFunctionTableInfo relocationTableB = {};
|
||||
relocationTableB.NumEntries = 2;
|
||||
std::vector<uint8_t> relocationTableBTokenStorage = {};
|
||||
relocationTableBTokenStorage.insert(relocationTableBTokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(&relocationTableB), reinterpret_cast<uint8_t *>(&relocationTableB + 1));
|
||||
relocationTableBTokenStorage.insert(relocationTableBTokenStorage.end(),
|
||||
reinterpret_cast<uint8_t *>(entryB), reinterpret_cast<uint8_t *>(entryB + 2));
|
||||
programFromTokens.kernels[1].tokens.programRelocationTable = reinterpret_cast<iOpenCL::SPatchFunctionTableInfo *>(relocationTableBTokenStorage.data());
|
||||
|
||||
std::vector<const void *> receivedData;
|
||||
std::vector<uint32_t> receivedNumEntries;
|
||||
std::vector<uint32_t> receivedSegmentIds;
|
||||
mockLinkerInput->decodeRelocationTableMockConfig.overrideFunc = [&](Mock<NEO::LinkerInput> *, const void *data, uint32_t numEntries, uint32_t instructionsSegmentId) -> bool {
|
||||
receivedData.push_back(data);
|
||||
receivedNumEntries.push_back(numEntries);
|
||||
receivedSegmentIds.push_back(instructionsSegmentId);
|
||||
return true;
|
||||
};
|
||||
NEO::populateProgramInfo(programInfo, programFromTokens, {});
|
||||
ASSERT_EQ(2U, mockLinkerInput->decodeRelocationTableMockConfig.timesCalled);
|
||||
ASSERT_EQ(2U, receivedData.size());
|
||||
|
||||
EXPECT_EQ(1U, receivedNumEntries[0]);
|
||||
EXPECT_EQ(2U, receivedNumEntries[1]);
|
||||
EXPECT_EQ(reinterpret_cast<void *>(relocationTableATokenStorage.data() + sizeof(iOpenCL::SPatchFunctionTableInfo)), receivedData[0]);
|
||||
EXPECT_EQ(reinterpret_cast<void *>(relocationTableBTokenStorage.data() + sizeof(iOpenCL::SPatchFunctionTableInfo)), receivedData[1]);
|
||||
EXPECT_EQ(0U, receivedSegmentIds[0]);
|
||||
EXPECT_EQ(1U, receivedSegmentIds[1]);
|
||||
}
|
||||
21
core/unit_tests/program/program_info_tests.cpp
Normal file
21
core/unit_tests/program/program_info_tests.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/program/program_info.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(ProgramInfoTests, whenPrepareLinkerInputStorageGetsCalledTwiceThenLinkerInputStorageIsReused) {
|
||||
NEO::ProgramInfo programInfo;
|
||||
EXPECT_EQ(nullptr, programInfo.linkerInput);
|
||||
programInfo.prepareLinkerInputStorage();
|
||||
EXPECT_NE(nullptr, programInfo.linkerInput);
|
||||
auto prevLinkerInput = programInfo.linkerInput.get();
|
||||
programInfo.prepareLinkerInputStorage();
|
||||
EXPECT_EQ(prevLinkerInput, programInfo.linkerInput.get());
|
||||
}
|
||||
213
core/unit_tests/program/program_initialization_tests.cpp
Normal file
213
core/unit_tests/program/program_initialization_tests.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/program/program_initialization.h"
|
||||
#include "core/unit_tests/compiler_interface/linker_mock.h"
|
||||
#include "unit_tests/mocks/mock_device.h"
|
||||
#include "unit_tests/mocks/mock_memory_manager.h"
|
||||
#include "unit_tests/mocks/mock_svm_manager.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
TEST(AllocateGlobalSurfaceTest, GivenSvmAllocsManagerWhenGlobalsAreNotExportedThenMemoryIsAllocatedAsNonSvmAllocation) {
|
||||
MockDevice device;
|
||||
if (0 == device.getDeviceInfo().svmCapabilities) {
|
||||
return;
|
||||
}
|
||||
MockSVMAllocsManager svmAllocsManager(device.getMemoryManager());
|
||||
WhiteBox<LinkerInput> emptyLinkerInput;
|
||||
LinkerInput *linkerInput;
|
||||
std::vector<uint8_t> initData;
|
||||
initData.resize(64, 7U);
|
||||
bool constant = true;
|
||||
GraphicsAllocation *alloc = nullptr;
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = true, linkerInput = nullptr, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
|
||||
EXPECT_EQ(GraphicsAllocation::AllocationType::CONSTANT_SURFACE, alloc->getAllocationType());
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = false, linkerInput = nullptr, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
|
||||
EXPECT_EQ(GraphicsAllocation::AllocationType::GLOBAL_SURFACE, alloc->getAllocationType());
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = true, linkerInput = &emptyLinkerInput, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
|
||||
EXPECT_EQ(GraphicsAllocation::AllocationType::CONSTANT_SURFACE, alloc->getAllocationType());
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = false, linkerInput = &emptyLinkerInput, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
|
||||
EXPECT_EQ(GraphicsAllocation::AllocationType::GLOBAL_SURFACE, alloc->getAllocationType());
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
}
|
||||
|
||||
TEST(AllocateGlobalSurfaceTest, GivenSvmAllocsManagerWhenGlobalsAreExportedThenMemoryIsAllocatedAsSvmAllocation) {
|
||||
MockDevice device;
|
||||
if (0 == device.getDeviceInfo().svmCapabilities) {
|
||||
return;
|
||||
}
|
||||
MockMemoryManager memoryManager;
|
||||
MockSVMAllocsManager svmAllocsManager(&memoryManager);
|
||||
WhiteBox<LinkerInput> linkerInputExportGlobalVariables;
|
||||
WhiteBox<LinkerInput> linkerInputExportGlobalConstants;
|
||||
linkerInputExportGlobalVariables.traits.exportsGlobalVariables = true;
|
||||
linkerInputExportGlobalConstants.traits.exportsGlobalConstants = true;
|
||||
LinkerInput *linkerInput;
|
||||
std::vector<uint8_t> initData;
|
||||
initData.resize(64, 7U);
|
||||
bool constant = true;
|
||||
GraphicsAllocation *alloc = nullptr;
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = true, linkerInput = &linkerInputExportGlobalConstants, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
ASSERT_NE(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
|
||||
EXPECT_FALSE(alloc->isMemObjectsAllocationWithWritableFlags());
|
||||
svmAllocsManager.freeSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress())));
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = true, linkerInput = &linkerInputExportGlobalVariables, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = false, linkerInput = &linkerInputExportGlobalConstants, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = false, linkerInput = &linkerInputExportGlobalVariables, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_NE(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
|
||||
EXPECT_TRUE(alloc->isMemObjectsAllocationWithWritableFlags());
|
||||
svmAllocsManager.freeSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress())));
|
||||
}
|
||||
|
||||
TEST(AllocateGlobalSurfaceTest, GivenNullSvmAllocsManagerWhenGlobalsAreExportedThenMemoryIsAllocatedAsNonSvmAllocation) {
|
||||
MockDevice device;
|
||||
WhiteBox<LinkerInput> linkerInputExportGlobalVariables;
|
||||
WhiteBox<LinkerInput> linkerInputExportGlobalConstants;
|
||||
linkerInputExportGlobalVariables.traits.exportsGlobalVariables = true;
|
||||
linkerInputExportGlobalConstants.traits.exportsGlobalConstants = true;
|
||||
LinkerInput *linkerInput;
|
||||
std::vector<uint8_t> initData;
|
||||
initData.resize(64, 7U);
|
||||
bool constant = true;
|
||||
GraphicsAllocation *alloc = nullptr;
|
||||
|
||||
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), constant = true, linkerInput = &linkerInputExportGlobalConstants, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(GraphicsAllocation::AllocationType::CONSTANT_SURFACE, alloc->getAllocationType());
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), constant = true, linkerInput = &linkerInputExportGlobalVariables, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(GraphicsAllocation::AllocationType::CONSTANT_SURFACE, alloc->getAllocationType());
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), constant = false, linkerInput = &linkerInputExportGlobalConstants, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(GraphicsAllocation::AllocationType::GLOBAL_SURFACE, alloc->getAllocationType());
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), constant = false, linkerInput = &linkerInputExportGlobalVariables, initData.data());
|
||||
ASSERT_NE(nullptr, alloc);
|
||||
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
|
||||
EXPECT_EQ(GraphicsAllocation::AllocationType::GLOBAL_SURFACE, alloc->getAllocationType());
|
||||
device.getMemoryManager()->freeGraphicsMemory(alloc);
|
||||
}
|
||||
|
||||
TEST(AllocateGlobalSurfaceTest, WhenGlobalsAreNotExportedAndAllocationFailsThenGracefullyReturnsNullptr) {
|
||||
MockDevice device;
|
||||
auto memoryManager = std::make_unique<MockMemoryManager>();
|
||||
memoryManager->failInAllocateWithSizeAndAlignment = true;
|
||||
device.injectMemoryManager(memoryManager.release());
|
||||
MockSVMAllocsManager mockSvmAllocsManager(device.getMemoryManager());
|
||||
WhiteBox<LinkerInput> emptyLinkerInput;
|
||||
LinkerInput *linkerInput;
|
||||
SVMAllocsManager *svmAllocsManager = &mockSvmAllocsManager;
|
||||
std::vector<uint8_t> initData;
|
||||
initData.resize(64, 7U);
|
||||
bool constant = true;
|
||||
GraphicsAllocation *alloc = nullptr;
|
||||
|
||||
alloc = allocateGlobalsSurface(svmAllocsManager = &mockSvmAllocsManager, device, initData.size(), constant = true, linkerInput = nullptr, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(svmAllocsManager = &mockSvmAllocsManager, device, initData.size(), constant = false, linkerInput = nullptr, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(svmAllocsManager = &mockSvmAllocsManager, device, initData.size(), constant = true, linkerInput = &emptyLinkerInput, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(svmAllocsManager = &mockSvmAllocsManager, device, initData.size(), constant = false, linkerInput = &emptyLinkerInput, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(svmAllocsManager = nullptr, device, initData.size(), constant = true, linkerInput = nullptr, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(svmAllocsManager = nullptr, device, initData.size(), constant = false, linkerInput = nullptr, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(svmAllocsManager = nullptr, device, initData.size(), constant = true, linkerInput = &emptyLinkerInput, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(svmAllocsManager = nullptr, device, initData.size(), constant = false, linkerInput = &emptyLinkerInput, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
}
|
||||
|
||||
TEST(AllocateGlobalSurfaceTest, WhenGlobalsAreExportedAndAllocationFailsThenGracefullyReturnsNullptr) {
|
||||
MockDevice device;
|
||||
MockMemoryManager memoryManager;
|
||||
MockSVMAllocsManager svmAllocsManager(&memoryManager);
|
||||
memoryManager.failInAllocateWithSizeAndAlignment = true;
|
||||
WhiteBox<LinkerInput> linkerInputExportGlobalVariables;
|
||||
WhiteBox<LinkerInput> linkerInputExportGlobalConstants;
|
||||
linkerInputExportGlobalVariables.traits.exportsGlobalVariables = true;
|
||||
linkerInputExportGlobalConstants.traits.exportsGlobalConstants = true;
|
||||
LinkerInput *linkerInput;
|
||||
std::vector<uint8_t> initData;
|
||||
initData.resize(64, 7U);
|
||||
bool constant = true;
|
||||
GraphicsAllocation *alloc = nullptr;
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = true, linkerInput = &linkerInputExportGlobalConstants, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
|
||||
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), constant = false, linkerInput = &linkerInputExportGlobalVariables, initData.data());
|
||||
EXPECT_EQ(nullptr, alloc);
|
||||
}
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "runtime/helpers/queue_helpers.h"
|
||||
#include "runtime/helpers/validators.h"
|
||||
#include "runtime/kernel/kernel.h"
|
||||
#include "runtime/kernel/kernel_info_cl.h"
|
||||
#include "runtime/mem_obj/buffer.h"
|
||||
#include "runtime/mem_obj/image.h"
|
||||
#include "runtime/mem_obj/mem_obj_helper.h"
|
||||
@@ -1576,11 +1577,6 @@ cl_kernel CL_API_CALL clCreateKernel(cl_program clProgram,
|
||||
break;
|
||||
}
|
||||
|
||||
if (pKernelInfo->isValid == false) {
|
||||
retVal = CL_INVALID_PROGRAM_EXECUTABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
kernel = Kernel::create(
|
||||
pProgram,
|
||||
*pKernelInfo,
|
||||
@@ -1592,9 +1588,7 @@ cl_kernel CL_API_CALL clCreateKernel(cl_program clProgram,
|
||||
if (errcodeRet) {
|
||||
*errcodeRet = retVal;
|
||||
}
|
||||
if (kernel != nullptr) {
|
||||
gtpinNotifyKernelCreate(kernel);
|
||||
}
|
||||
gtpinNotifyKernelCreate(kernel);
|
||||
TRACING_EXIT(clCreateKernel, &kernel);
|
||||
return kernel;
|
||||
}
|
||||
@@ -1621,17 +1615,14 @@ cl_int CL_API_CALL clCreateKernelsInProgram(cl_program clProgram,
|
||||
return retVal;
|
||||
}
|
||||
|
||||
for (unsigned int ordinal = 0; ordinal < numKernelsInProgram; ++ordinal) {
|
||||
const auto kernelInfo = program->getKernelInfo(ordinal);
|
||||
for (unsigned int i = 0; i < numKernelsInProgram; ++i) {
|
||||
const auto kernelInfo = program->getKernelInfo(i);
|
||||
DEBUG_BREAK_IF(kernelInfo == nullptr);
|
||||
DEBUG_BREAK_IF(!kernelInfo->isValid);
|
||||
kernels[ordinal] = Kernel::create(
|
||||
kernels[i] = Kernel::create(
|
||||
program,
|
||||
*kernelInfo,
|
||||
nullptr);
|
||||
if (kernels[ordinal] != nullptr) {
|
||||
gtpinNotifyKernelCreate(kernels[ordinal]);
|
||||
}
|
||||
gtpinNotifyKernelCreate(kernels[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4367,7 +4358,7 @@ cl_int CL_API_CALL clSetKernelArgSVMPointer(cl_kernel kernel,
|
||||
return retVal;
|
||||
}
|
||||
|
||||
cl_int kernelArgAddressQualifier = pKernel->getKernelArgAddressQualifier(argIndex);
|
||||
cl_int kernelArgAddressQualifier = asClKernelArgAddressQualifier(pKernel->getKernelInfo().kernelArgInfo[argIndex].metadata.addressQualifier);
|
||||
if ((kernelArgAddressQualifier != CL_KERNEL_ARG_ADDRESS_GLOBAL) &&
|
||||
(kernelArgAddressQualifier != CL_KERNEL_ARG_ADDRESS_CONSTANT)) {
|
||||
retVal = CL_INVALID_ARG_VALUE;
|
||||
@@ -5140,7 +5131,7 @@ cl_int CL_API_CALL clGetDeviceGlobalVariablePointerINTEL(
|
||||
Program *pProgram = (Program *)(program);
|
||||
const auto &symbols = pProgram->getSymbols();
|
||||
auto symbolIt = symbols.find(globalVariableName);
|
||||
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.type == NEO::SymbolInfo::Function)) {
|
||||
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.segment == NEO::SegmentType::Instructions)) {
|
||||
retVal = CL_INVALID_ARG_VALUE;
|
||||
} else {
|
||||
if (globalVariableSizeRet != nullptr) {
|
||||
@@ -5172,7 +5163,7 @@ cl_int CL_API_CALL clGetDeviceFunctionPointerINTEL(
|
||||
Program *pProgram = (Program *)(program);
|
||||
const auto &symbols = pProgram->getSymbols();
|
||||
auto symbolIt = symbols.find(functionName);
|
||||
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.type != NEO::SymbolInfo::Function)) {
|
||||
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.segment != NEO::SegmentType::Instructions)) {
|
||||
retVal = CL_INVALID_ARG_VALUE;
|
||||
} else {
|
||||
*functionPointerRet = static_cast<cl_ulong>(symbolIt->second.gpuAddress);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 Intel Corporation
|
||||
* Copyright (C) 2018-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -84,9 +84,7 @@ class BuiltinDispatchInfoBuilder {
|
||||
template <typename KernelNameT, typename... KernelsDescArgsT>
|
||||
void grabKernels(KernelNameT &&kernelName, Kernel *&kernelDst, KernelsDescArgsT &&... kernelsDesc) {
|
||||
const KernelInfo *kernelInfo = prog->getKernelInfo(kernelName);
|
||||
if (!kernelInfo) {
|
||||
return;
|
||||
}
|
||||
UNRECOVERABLE_IF(nullptr == kernelInfo);
|
||||
cl_int err = 0;
|
||||
kernelDst = Kernel::create(prog.get(), *kernelInfo, &err);
|
||||
kernelDst->isBuiltIn = true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "patch_shared.h"
|
||||
#include "program_debug_data.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "core/helpers/hw_info.h"
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
#include "runtime/program/kernel_arg_info.h"
|
||||
|
||||
#include "igfxfmid.h"
|
||||
|
||||
@@ -90,6 +91,11 @@ inline ValidatorError validate(const ProgramFromPatchtokens &decodedProgram,
|
||||
return ValidatorError::InvalidBinary;
|
||||
}
|
||||
|
||||
if ((decodedProgram.header->GPUPointerSizeInBytes != 4U) && (decodedProgram.header->GPUPointerSizeInBytes != 8U)) {
|
||||
outErrReason = "Invalid pointer size";
|
||||
return ValidatorError::InvalidBinary;
|
||||
}
|
||||
|
||||
if (false == isDeviceSupported(static_cast<GFXCORE_FAMILY>(decodedProgram.header->Device))) {
|
||||
outErrReason = "Unsupported device binary, device GFXCORE_FAMILY : " + std::to_string(decodedProgram.header->Device);
|
||||
return ValidatorError::InvalidBinary;
|
||||
@@ -107,6 +113,25 @@ inline ValidatorError validate(const ProgramFromPatchtokens &decodedProgram,
|
||||
return ValidatorError::InvalidBinary;
|
||||
}
|
||||
|
||||
if (nullptr == decodedKernel.tokens.executionEnvironment) {
|
||||
outErrReason = "Missing execution environment";
|
||||
return ValidatorError::InvalidBinary;
|
||||
} else {
|
||||
switch (decodedKernel.tokens.executionEnvironment->LargestCompiledSIMDSize) {
|
||||
case 1:
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
case 16:
|
||||
break;
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
outErrReason = "Invalid LargestCompiledSIMDSize";
|
||||
return ValidatorError::InvalidBinary;
|
||||
}
|
||||
}
|
||||
|
||||
if (decodedKernel.tokens.allocateLocalSurface) {
|
||||
if (sharedLocalMemorySize < decodedKernel.tokens.allocateLocalSurface->TotalInlineLocalMemorySize) {
|
||||
outErrReason = "KernelFromPatchtokens requires too much SLM";
|
||||
@@ -114,6 +139,24 @@ inline ValidatorError validate(const ProgramFromPatchtokens &decodedProgram,
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &kernelArg : decodedKernel.tokens.kernelArgs) {
|
||||
if (kernelArg.argInfo == nullptr) {
|
||||
outErrReason = "Missing kernelArgInfo";
|
||||
return ValidatorError::InvalidBinary;
|
||||
}
|
||||
auto argInfoInlineData = getInlineData(kernelArg.argInfo);
|
||||
auto accessQualifier = KernelArgMetadata::parseAccessQualifier(parseLimitedString(argInfoInlineData.accessQualifier.begin(), argInfoInlineData.accessQualifier.size()));
|
||||
if (KernelArgMetadata::AccessQualifier::Unknown == accessQualifier) {
|
||||
outErrReason = "Unhandled access qualifier";
|
||||
return ValidatorError::InvalidBinary;
|
||||
}
|
||||
auto addressQualifier = KernelArgMetadata::parseAddressSpace(parseLimitedString(argInfoInlineData.addressQualifier.begin(), argInfoInlineData.addressQualifier.size()));
|
||||
if (KernelArgMetadata::AddressSpaceQualifier::Unknown == addressQualifier) {
|
||||
outErrReason = "Unhandled address qualifier";
|
||||
return ValidatorError::InvalidBinary;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &unhandledToken : decodedKernel.unhandledTokens) {
|
||||
if (false == tokenValidator.isSafeToSkipUnhandledToken(unhandledToken->Token)) {
|
||||
outErrReason = "Unhandled required kernel-scope Patch Token : " + std::to_string(unhandledToken->Token);
|
||||
|
||||
@@ -58,6 +58,9 @@ void gtpinNotifyContextDestroy(cl_context context) {
|
||||
}
|
||||
|
||||
void gtpinNotifyKernelCreate(cl_kernel kernel) {
|
||||
if (nullptr == kernel) {
|
||||
return;
|
||||
}
|
||||
if (isGTPinInitialized) {
|
||||
auto pKernel = castToObjectOrAbort<Kernel>(kernel);
|
||||
size_t gtpinBTI = pKernel->getNumberOfBindingTableStates();
|
||||
|
||||
@@ -14,6 +14,7 @@ set(RUNTIME_SRCS_KERNEL
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_execution_type.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_info_cl.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/kernel_extra.cpp
|
||||
)
|
||||
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_KERNEL})
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "runtime/helpers/surface_formats.h"
|
||||
#include "runtime/kernel/image_transformer.h"
|
||||
#include "runtime/kernel/kernel.inl"
|
||||
#include "runtime/kernel/kernel_info_cl.h"
|
||||
#include "runtime/mem_obj/buffer.h"
|
||||
#include "runtime/mem_obj/image.h"
|
||||
#include "runtime/mem_obj/pipe.h"
|
||||
@@ -337,22 +338,20 @@ cl_int Kernel::initialize() {
|
||||
|
||||
// set the argument handler
|
||||
auto &argInfo = kernelInfo.kernelArgInfo[i];
|
||||
if (argInfo.addressQualifier == CL_KERNEL_ARG_ADDRESS_LOCAL) {
|
||||
if (argInfo.metadata.addressQualifier == KernelArgMetadata::AddressSpaceQualifier::Local) {
|
||||
kernelArgHandlers[i] = &Kernel::setArgLocal;
|
||||
} else if (argInfo.isAccelerator) {
|
||||
kernelArgHandlers[i] = &Kernel::setArgAccelerator;
|
||||
} else if (argInfo.typeQualifierStr.find("pipe") != std::string::npos) {
|
||||
} else if (argInfo.metadata.typeQualifiers.pipeQual) {
|
||||
kernelArgHandlers[i] = &Kernel::setArgPipe;
|
||||
kernelArguments[i].type = PIPE_OBJ;
|
||||
} else if (argInfo.isImage) {
|
||||
kernelArgHandlers[i] = &Kernel::setArgImage;
|
||||
kernelArguments[i].type = IMAGE_OBJ;
|
||||
usingImages = true;
|
||||
DEBUG_BREAK_IF(argInfo.typeStr.find("image") == std::string::npos);
|
||||
} else if (argInfo.isSampler) {
|
||||
kernelArgHandlers[i] = &Kernel::setArgSampler;
|
||||
kernelArguments[i].type = SAMPLER_OBJ;
|
||||
DEBUG_BREAK_IF(!(*argInfo.typeStr.c_str() == '\0' || argInfo.typeStr.find("sampler") != std::string::npos));
|
||||
} else if (argInfo.isBuffer) {
|
||||
kernelArgHandlers[i] = &Kernel::setArgBuffer;
|
||||
kernelArguments[i].type = BUFFER_OBJ;
|
||||
@@ -506,37 +505,44 @@ cl_int Kernel::getArgInfo(cl_uint argIndx, cl_kernel_arg_info paramName, size_t
|
||||
const void *pSrc = nullptr;
|
||||
size_t srcSize = 0;
|
||||
auto numArgs = (cl_uint)kernelInfo.kernelArgInfo.size();
|
||||
auto argInfoIdx = kernelInfo.kernelArgInfo[argIndx];
|
||||
const auto &argInfo = kernelInfo.kernelArgInfo[argIndx];
|
||||
|
||||
if (argIndx >= numArgs) {
|
||||
retVal = CL_INVALID_ARG_INDEX;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
cl_kernel_arg_address_qualifier addressQualifier;
|
||||
cl_kernel_arg_access_qualifier accessQualifier;
|
||||
cl_kernel_arg_type_qualifier typeQualifier;
|
||||
|
||||
switch (paramName) {
|
||||
case CL_KERNEL_ARG_ADDRESS_QUALIFIER:
|
||||
srcSize = sizeof(cl_uint);
|
||||
pSrc = &argInfoIdx.addressQualifier;
|
||||
addressQualifier = asClKernelArgAddressQualifier(argInfo.metadata.addressQualifier);
|
||||
srcSize = sizeof(addressQualifier);
|
||||
pSrc = &addressQualifier;
|
||||
break;
|
||||
|
||||
case CL_KERNEL_ARG_ACCESS_QUALIFIER:
|
||||
srcSize = sizeof(cl_uint);
|
||||
pSrc = &argInfoIdx.accessQualifier;
|
||||
break;
|
||||
|
||||
case CL_KERNEL_ARG_TYPE_NAME:
|
||||
srcSize = argInfoIdx.typeStr.length() + 1;
|
||||
pSrc = argInfoIdx.typeStr.c_str();
|
||||
accessQualifier = asClKernelArgAccessQualifier(argInfo.metadata.accessQualifier);
|
||||
srcSize = sizeof(accessQualifier);
|
||||
pSrc = &accessQualifier;
|
||||
break;
|
||||
|
||||
case CL_KERNEL_ARG_TYPE_QUALIFIER:
|
||||
srcSize = sizeof(argInfoIdx.typeQualifier);
|
||||
pSrc = &argInfoIdx.typeQualifier;
|
||||
typeQualifier = asClKernelArgTypeQualifier(argInfo.metadata.typeQualifiers);
|
||||
srcSize = sizeof(typeQualifier);
|
||||
pSrc = &typeQualifier;
|
||||
break;
|
||||
|
||||
case CL_KERNEL_ARG_TYPE_NAME:
|
||||
srcSize = argInfo.metadataExtended->type.length() + 1;
|
||||
pSrc = argInfo.metadataExtended->type.c_str();
|
||||
break;
|
||||
|
||||
case CL_KERNEL_ARG_NAME:
|
||||
srcSize = argInfoIdx.name.length() + 1;
|
||||
pSrc = argInfoIdx.name.c_str();
|
||||
srcSize = argInfo.metadataExtended->argName.length() + 1;
|
||||
pSrc = argInfo.metadataExtended->argName.c_str();
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2290,10 +2296,10 @@ cl_int Kernel::checkCorrectImageAccessQualifier(cl_uint argIndex,
|
||||
MemObj *pMemObj = nullptr;
|
||||
WithCastToInternal(mem, &pMemObj);
|
||||
if (pMemObj) {
|
||||
cl_kernel_arg_access_qualifier accessQualifier = getKernelInfo().kernelArgInfo[argIndex].accessQualifier;
|
||||
auto accessQualifier = getKernelInfo().kernelArgInfo[argIndex].metadata.accessQualifier;
|
||||
cl_mem_flags flags = pMemObj->getMemoryPropertiesFlags();
|
||||
if ((accessQualifier == CL_KERNEL_ARG_ACCESS_READ_ONLY && ((flags | CL_MEM_WRITE_ONLY) == flags)) ||
|
||||
(accessQualifier == CL_KERNEL_ARG_ACCESS_WRITE_ONLY && ((flags | CL_MEM_READ_ONLY) == flags))) {
|
||||
if ((accessQualifier == KernelArgMetadata::AccessQualifier::ReadOnly && ((flags | CL_MEM_WRITE_ONLY) == flags)) ||
|
||||
(accessQualifier == KernelArgMetadata::AccessQualifier::WriteOnly && ((flags | CL_MEM_READ_ONLY) == flags))) {
|
||||
return CL_INVALID_ARG_VALUE;
|
||||
}
|
||||
} else {
|
||||
@@ -2341,7 +2347,7 @@ void Kernel::fillWithBuffersForAuxTranslation(MemObjsForAuxTranslation &memObjsF
|
||||
auto &context = this->program->getContext();
|
||||
if (context.isProvidingPerformanceHints()) {
|
||||
context.providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL, KERNEL_ARGUMENT_AUX_TRANSLATION,
|
||||
kernelInfo.name.c_str(), i, kernelInfo.kernelArgInfo.at(i).name.c_str());
|
||||
kernelInfo.name.c_str(), i, kernelInfo.kernelArgInfo.at(i).metadataExtended->argName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,15 +72,12 @@ class Kernel : public BaseObject<_cl_kernel> {
|
||||
const void *argVal);
|
||||
|
||||
template <typename kernel_t = Kernel, typename program_t = Program>
|
||||
static kernel_t *create(Program *program, const KernelInfo &kernelInfo, cl_int *errcodeRet) {
|
||||
static kernel_t *create(program_t *program, const KernelInfo &kernelInfo, cl_int *errcodeRet) {
|
||||
cl_int retVal;
|
||||
kernel_t *pKernel = nullptr;
|
||||
|
||||
do {
|
||||
// copy the kernel data into our new allocation
|
||||
pKernel = new kernel_t(program, kernelInfo, program->getDevice(0));
|
||||
retVal = pKernel->initialize();
|
||||
} while (false);
|
||||
pKernel = new kernel_t(program, kernelInfo, program->getDevice(0));
|
||||
retVal = pKernel->initialize();
|
||||
|
||||
if (retVal != CL_SUCCESS) {
|
||||
delete pKernel;
|
||||
@@ -179,10 +176,6 @@ class Kernel : public BaseObject<_cl_kernel> {
|
||||
return kernelInfo.kernelArgInfo.size();
|
||||
}
|
||||
|
||||
uint32_t getKernelArgAddressQualifier(uint32_t argIndex) const {
|
||||
return kernelInfo.kernelArgInfo[argIndex].addressQualifier;
|
||||
}
|
||||
|
||||
bool requiresSshForBuffers() const {
|
||||
return kernelInfo.requiresSshForBuffers;
|
||||
}
|
||||
|
||||
57
runtime/kernel/kernel_info_cl.h
Normal file
57
runtime/kernel/kernel_info_cl.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "runtime/program/kernel_arg_info.h"
|
||||
|
||||
#include "CL/cl.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
constexpr cl_kernel_arg_access_qualifier asClKernelArgAccessQualifier(KernelArgMetadata::AccessQualifier accessQualifier) {
|
||||
using namespace KernelArgMetadata;
|
||||
switch (accessQualifier) {
|
||||
default:
|
||||
return 0U;
|
||||
case AccessQualifier::None:
|
||||
return CL_KERNEL_ARG_ACCESS_NONE;
|
||||
case AccessQualifier::ReadOnly:
|
||||
return CL_KERNEL_ARG_ACCESS_READ_ONLY;
|
||||
case AccessQualifier::WriteOnly:
|
||||
return CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
|
||||
case AccessQualifier::ReadWrite:
|
||||
return CL_KERNEL_ARG_ACCESS_READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr cl_kernel_arg_address_qualifier asClKernelArgAddressQualifier(KernelArgMetadata::AddressSpaceQualifier addressQualifier) {
|
||||
using namespace KernelArgMetadata;
|
||||
switch (addressQualifier) {
|
||||
default:
|
||||
return 0U;
|
||||
case AddressSpaceQualifier::Global:
|
||||
return CL_KERNEL_ARG_ADDRESS_GLOBAL;
|
||||
case AddressSpaceQualifier::Local:
|
||||
return CL_KERNEL_ARG_ADDRESS_LOCAL;
|
||||
case AddressSpaceQualifier::Private:
|
||||
return CL_KERNEL_ARG_ADDRESS_PRIVATE;
|
||||
case AddressSpaceQualifier::Constant:
|
||||
return CL_KERNEL_ARG_ADDRESS_CONSTANT;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr cl_kernel_arg_type_qualifier asClKernelArgTypeQualifier(KernelArgMetadata::TypeQualifiers typeQualifiers) {
|
||||
using namespace KernelArgMetadata;
|
||||
cl_kernel_arg_type_qualifier ret = 0U;
|
||||
ret |= (typeQualifiers.constQual) ? CL_KERNEL_ARG_TYPE_CONST : 0U;
|
||||
ret |= (typeQualifiers.volatileQual) ? CL_KERNEL_ARG_TYPE_VOLATILE : 0U;
|
||||
ret |= (typeQualifiers.restrictQual) ? CL_KERNEL_ARG_TYPE_RESTRICT : 0U;
|
||||
ret |= (typeQualifiers.pipeQual) ? CL_KERNEL_ARG_TYPE_PIPE : 0U;
|
||||
return ret;
|
||||
}
|
||||
} // namespace NEO
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "runtime/device/device.h"
|
||||
#include "runtime/helpers/base_object.h"
|
||||
#include "runtime/helpers/validators.h"
|
||||
#include "runtime/program/kernel_info.h"
|
||||
|
||||
#include "program.h"
|
||||
|
||||
@@ -56,7 +57,7 @@ cl_int Program::getInfo(cl_program_info paramName, size_t paramValueSize,
|
||||
break;
|
||||
|
||||
case CL_PROGRAM_KERNEL_NAMES:
|
||||
kernelNamesString = getKernelNamesString();
|
||||
kernelNamesString = concatenateKernelNames(kernelInfoArray);
|
||||
pSrc = kernelNamesString.c_str();
|
||||
retSize = srcSize = kernelNamesString.length() + 1;
|
||||
|
||||
|
||||
@@ -1,16 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CL/cl.h"
|
||||
|
||||
#include "core/compiler_interface/compiler_options/compiler_options_base.h"
|
||||
#include "core/utilities/const_stringref.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
namespace KernelArgMetadata {
|
||||
|
||||
enum class AccessQualifier : uint8_t {
|
||||
Unknown,
|
||||
None,
|
||||
ReadOnly,
|
||||
WriteOnly,
|
||||
ReadWrite,
|
||||
};
|
||||
|
||||
namespace AccessQualifierStrings {
|
||||
constexpr ConstStringRef none = "NONE";
|
||||
constexpr ConstStringRef readOnly = "read_only";
|
||||
constexpr ConstStringRef writeOnly = "write_only";
|
||||
constexpr ConstStringRef readWrite = "read_write";
|
||||
constexpr ConstStringRef underscoreReadOnly = "__read_only";
|
||||
constexpr ConstStringRef underscoreWriteOnly = "__write_only";
|
||||
constexpr ConstStringRef underscoreReadWrite = "__read_write";
|
||||
} // namespace AccessQualifierStrings
|
||||
|
||||
enum class AddressSpaceQualifier : uint8_t {
|
||||
Unknown,
|
||||
Global,
|
||||
Local,
|
||||
Private,
|
||||
Constant
|
||||
};
|
||||
|
||||
namespace AddressSpaceQualifierStrings {
|
||||
constexpr ConstStringRef addrGlobal = "__global";
|
||||
constexpr ConstStringRef addrLocal = "__local";
|
||||
constexpr ConstStringRef addrPrivate = "__private";
|
||||
constexpr ConstStringRef addrConstant = "__constant";
|
||||
constexpr ConstStringRef addrNotSpecified = "not_specified";
|
||||
} // namespace AddressSpaceQualifierStrings
|
||||
|
||||
constexpr AccessQualifier parseAccessQualifier(ConstStringRef str) {
|
||||
using namespace AccessQualifierStrings;
|
||||
if (str.empty() || (none == str)) {
|
||||
return AccessQualifier::None;
|
||||
}
|
||||
|
||||
if (str.length() < 3) {
|
||||
return AccessQualifier::Unknown;
|
||||
}
|
||||
|
||||
ConstStringRef strNoUnderscore = ('_' == str[0]) ? ConstStringRef(str.data() + 2, str.length() - 2) : str;
|
||||
static_assert(writeOnly[0] != readOnly[0], "");
|
||||
static_assert(writeOnly[0] != readWrite[0], "");
|
||||
if (strNoUnderscore[0] == writeOnly[0]) {
|
||||
return (writeOnly == strNoUnderscore) ? AccessQualifier::WriteOnly : AccessQualifier::Unknown;
|
||||
}
|
||||
|
||||
if (readOnly == strNoUnderscore) {
|
||||
return AccessQualifier::ReadOnly;
|
||||
}
|
||||
|
||||
return (readWrite == strNoUnderscore) ? AccessQualifier::ReadWrite : AccessQualifier::Unknown;
|
||||
}
|
||||
|
||||
constexpr AddressSpaceQualifier parseAddressSpace(ConstStringRef str) {
|
||||
using namespace AddressSpaceQualifierStrings;
|
||||
if (str.empty()) {
|
||||
return AddressSpaceQualifier::Global;
|
||||
}
|
||||
|
||||
if (str.length() < 3) {
|
||||
return AddressSpaceQualifier::Unknown;
|
||||
}
|
||||
|
||||
switch (str[2]) {
|
||||
default:
|
||||
return AddressSpaceQualifier::Unknown;
|
||||
case addrNotSpecified[2]:
|
||||
return (str == addrNotSpecified) ? AddressSpaceQualifier::Private : AddressSpaceQualifier::Unknown;
|
||||
case addrGlobal[2]:
|
||||
return (str == addrGlobal) ? AddressSpaceQualifier::Global : AddressSpaceQualifier::Unknown;
|
||||
case addrLocal[2]:
|
||||
return (str == addrLocal) ? AddressSpaceQualifier::Local : AddressSpaceQualifier::Unknown;
|
||||
case addrPrivate[2]:
|
||||
return (str == addrPrivate) ? AddressSpaceQualifier::Private : AddressSpaceQualifier::Unknown;
|
||||
case addrConstant[2]:
|
||||
return (str == addrConstant) ? AddressSpaceQualifier::Constant : AddressSpaceQualifier::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
union TypeQualifiers {
|
||||
uint8_t packed = 0U;
|
||||
struct {
|
||||
bool constQual : 1;
|
||||
bool volatileQual : 1;
|
||||
bool restrictQual : 1;
|
||||
bool pipeQual : 1;
|
||||
bool unknownQual : 1;
|
||||
};
|
||||
bool empty() const {
|
||||
return 0U == packed;
|
||||
}
|
||||
};
|
||||
|
||||
namespace TypeQualifierStrings {
|
||||
constexpr ConstStringRef qualConst = "const";
|
||||
constexpr ConstStringRef qualVolatile = "volatile";
|
||||
constexpr ConstStringRef qualRestrict = "restrict";
|
||||
constexpr ConstStringRef qualPipe = "pipe";
|
||||
} // namespace TypeQualifierStrings
|
||||
|
||||
inline TypeQualifiers parseTypeQualifiers(ConstStringRef str) {
|
||||
using namespace TypeQualifierStrings;
|
||||
TypeQualifiers ret = {};
|
||||
auto tokenized = CompilerOptions::tokenize(str);
|
||||
for (const auto &tok : tokenized) {
|
||||
bool knownQualifier = true;
|
||||
switch (tok[0]) {
|
||||
default:
|
||||
knownQualifier = false;
|
||||
break;
|
||||
case qualConst[0]:
|
||||
knownQualifier = (qualConst == tok);
|
||||
ret.constQual |= knownQualifier;
|
||||
break;
|
||||
case qualVolatile[0]:
|
||||
knownQualifier = (qualVolatile == tok);
|
||||
ret.volatileQual |= knownQualifier;
|
||||
break;
|
||||
case qualRestrict[0]:
|
||||
knownQualifier = (qualRestrict == tok);
|
||||
ret.restrictQual |= knownQualifier;
|
||||
break;
|
||||
case qualPipe[0]:
|
||||
knownQualifier = (qualPipe == tok);
|
||||
ret.pipeQual |= knownQualifier;
|
||||
break;
|
||||
}
|
||||
ret.unknownQual |= !knownQualifier;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace KernelArgMetadata
|
||||
|
||||
inline std::string parseLimitedString(const char *str, size_t maxSize) {
|
||||
std::string ret{str, str + maxSize};
|
||||
size_t minSize = strlen(ret.c_str());
|
||||
ret.assign(str, minSize);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ArgTypeMetadata {
|
||||
uint32_t argByValSize = 0U;
|
||||
KernelArgMetadata::AccessQualifier accessQualifier = {};
|
||||
KernelArgMetadata::AddressSpaceQualifier addressQualifier = {};
|
||||
KernelArgMetadata::TypeQualifiers typeQualifiers = {};
|
||||
};
|
||||
static_assert(sizeof(ArgTypeMetadata) <= 8, "");
|
||||
|
||||
struct ArgTypeMetadataExtended {
|
||||
std::string argName;
|
||||
std::string type;
|
||||
std::string accessQualifier;
|
||||
std::string addressQualifier;
|
||||
std::string typeQualifiers;
|
||||
};
|
||||
|
||||
struct KernelArgPatchInfo {
|
||||
uint32_t crossthreadOffset = 0;
|
||||
uint32_t size = 0;
|
||||
@@ -18,15 +188,18 @@ struct KernelArgPatchInfo {
|
||||
};
|
||||
|
||||
struct KernelArgInfo {
|
||||
KernelArgInfo() = default;
|
||||
~KernelArgInfo() = default;
|
||||
KernelArgInfo(const KernelArgInfo &rhs) = delete;
|
||||
KernelArgInfo &operator=(const KernelArgInfo &) = delete;
|
||||
KernelArgInfo(KernelArgInfo &&) = default;
|
||||
KernelArgInfo &operator=(KernelArgInfo &&) = default;
|
||||
|
||||
static constexpr uint32_t undefinedOffset = (uint32_t)-1;
|
||||
|
||||
std::string name;
|
||||
std::string typeStr;
|
||||
std::string accessQualifierStr;
|
||||
std::string addressQualifierStr;
|
||||
std::string typeQualifierStr;
|
||||
uint32_t offsetHeap = 0;
|
||||
std::vector<KernelArgPatchInfo> kernelArgPatchInfoVector;
|
||||
ArgTypeMetadata metadata;
|
||||
std::unique_ptr<ArgTypeMetadataExtended> metadataExtended;
|
||||
|
||||
uint32_t slmAlignment = 0;
|
||||
bool isImage = false;
|
||||
bool isMediaImage = false;
|
||||
@@ -37,6 +210,11 @@ struct KernelArgInfo {
|
||||
bool isBuffer = false;
|
||||
bool pureStatefulBufferAccess = false;
|
||||
bool isReadOnly = false;
|
||||
bool needPatch = false;
|
||||
bool isTransformable = false;
|
||||
|
||||
uint32_t offsetHeap = 0;
|
||||
std::vector<KernelArgPatchInfo> kernelArgPatchInfoVector;
|
||||
uint32_t samplerArgumentType = 0;
|
||||
uint32_t offsetImgWidth = undefinedOffset;
|
||||
uint32_t offsetImgHeight = undefinedOffset;
|
||||
@@ -59,13 +237,6 @@ struct KernelArgInfo {
|
||||
uint32_t offsetFlatWidth = undefinedOffset;
|
||||
uint32_t offsetFlatHeight = undefinedOffset;
|
||||
uint32_t offsetFlatPitch = undefinedOffset;
|
||||
|
||||
bool needPatch = false;
|
||||
bool isTransformable = false;
|
||||
|
||||
cl_kernel_arg_access_qualifier accessQualifier = CL_KERNEL_ARG_ACCESS_NONE;
|
||||
cl_kernel_arg_address_qualifier addressQualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL;
|
||||
cl_kernel_arg_type_qualifier typeQualifier = CL_KERNEL_ARG_TYPE_NONE;
|
||||
|
||||
KernelArgInfo() = default;
|
||||
};
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -26,41 +26,11 @@
|
||||
|
||||
namespace NEO {
|
||||
|
||||
const uint32_t WorkloadInfo::undefinedOffset = (uint32_t)-1;
|
||||
const uint32_t WorkloadInfo::invalidParentEvent = (uint32_t)-1;
|
||||
|
||||
std::unordered_map<std::string, uint32_t> accessQualifierMap = {
|
||||
{"", CL_KERNEL_ARG_ACCESS_NONE},
|
||||
{"NONE", CL_KERNEL_ARG_ACCESS_NONE},
|
||||
{"read_only", CL_KERNEL_ARG_ACCESS_READ_ONLY},
|
||||
{"__read_only", CL_KERNEL_ARG_ACCESS_READ_ONLY},
|
||||
{"write_only", CL_KERNEL_ARG_ACCESS_WRITE_ONLY},
|
||||
{"__write_only", CL_KERNEL_ARG_ACCESS_WRITE_ONLY},
|
||||
{"read_write", CL_KERNEL_ARG_ACCESS_READ_WRITE},
|
||||
{"__read_write", CL_KERNEL_ARG_ACCESS_READ_WRITE},
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, uint32_t> addressQualifierMap = {
|
||||
{"", CL_KERNEL_ARG_ADDRESS_GLOBAL},
|
||||
{"__global", CL_KERNEL_ARG_ADDRESS_GLOBAL},
|
||||
{"__local", CL_KERNEL_ARG_ADDRESS_LOCAL},
|
||||
{"__private", CL_KERNEL_ARG_ADDRESS_PRIVATE},
|
||||
{"__constant", CL_KERNEL_ARG_ADDRESS_CONSTANT},
|
||||
{"not_specified", CL_KERNEL_ARG_ADDRESS_PRIVATE},
|
||||
};
|
||||
|
||||
struct KernelArgumentType {
|
||||
const char *argTypeQualifier;
|
||||
uint64_t argTypeQualifierValue;
|
||||
};
|
||||
|
||||
constexpr KernelArgumentType typeQualifiers[] = {
|
||||
{"const", CL_KERNEL_ARG_TYPE_CONST},
|
||||
{"volatile", CL_KERNEL_ARG_TYPE_VOLATILE},
|
||||
{"restrict", CL_KERNEL_ARG_TYPE_RESTRICT},
|
||||
{"pipe", CL_KERNEL_ARG_TYPE_PIPE},
|
||||
};
|
||||
|
||||
std::map<std::string, size_t> typeSizeMap = {
|
||||
{"char", sizeof(cl_char)},
|
||||
{"char2", sizeof(cl_char2)},
|
||||
@@ -235,26 +205,12 @@ void KernelInfo::storePatchToken(const SPatchExecutionEnvironment *execEnv) {
|
||||
}
|
||||
}
|
||||
|
||||
void KernelInfo::storeArgInfo(const SPatchKernelArgumentInfo *pkernelArgInfo) {
|
||||
if (pkernelArgInfo == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t argNum = pkernelArgInfo->ArgumentNumber;
|
||||
void KernelInfo::storeArgInfo(uint32_t argNum, ArgTypeMetadata metadata, std::unique_ptr<ArgTypeMetadataExtended> metadataExtended) {
|
||||
resizeKernelArgInfoAndRegisterParameter(argNum);
|
||||
|
||||
auto inlineData = PatchTokenBinary::getInlineData(pkernelArgInfo);
|
||||
|
||||
kernelArgInfo[argNum].addressQualifierStr = std::string(inlineData.addressQualifier.begin(), inlineData.addressQualifier.end()).c_str();
|
||||
kernelArgInfo[argNum].accessQualifierStr = std::string(inlineData.accessQualifier.begin(), inlineData.accessQualifier.end()).c_str();
|
||||
kernelArgInfo[argNum].name = std::string(inlineData.argName.begin(), inlineData.argName.end()).c_str();
|
||||
|
||||
auto argTypeDelim = strchr(inlineData.typeName.begin(), ';');
|
||||
DEBUG_BREAK_IF(argTypeDelim == nullptr);
|
||||
kernelArgInfo[argNum].typeStr = std::string(inlineData.typeName.begin(), ptrDiff(argTypeDelim, inlineData.typeName.begin())).c_str();
|
||||
kernelArgInfo[argNum].typeQualifierStr = std::string(inlineData.typeQualifiers.begin(), inlineData.typeQualifiers.end()).c_str();
|
||||
|
||||
patchInfo.kernelArgumentInfo.push_back(pkernelArgInfo);
|
||||
auto &argInfo = kernelArgInfo[argNum];
|
||||
argInfo.metadata = metadata;
|
||||
argInfo.metadataExtended = std::move(metadataExtended);
|
||||
argInfo.isReadOnly |= argInfo.metadata.typeQualifiers.constQual;
|
||||
}
|
||||
|
||||
void KernelInfo::storeKernelArgument(
|
||||
@@ -295,9 +251,11 @@ void KernelInfo::storeKernelArgument(
|
||||
kernelArgInfo[argNum].isMediaBlockImage = true;
|
||||
}
|
||||
|
||||
kernelArgInfo[argNum].accessQualifier = pImageMemObjKernelArg->Writeable
|
||||
? CL_KERNEL_ARG_ACCESS_READ_WRITE
|
||||
: CL_KERNEL_ARG_ACCESS_READ_ONLY;
|
||||
kernelArgInfo[argNum].metadata.accessQualifier = pImageMemObjKernelArg->Writeable
|
||||
? KernelArgMetadata::AccessQualifier::ReadWrite
|
||||
: KernelArgMetadata::AccessQualifier::ReadOnly;
|
||||
|
||||
kernelArgInfo[argNum].metadata.argByValSize = sizeof(cl_mem);
|
||||
|
||||
kernelArgInfo[argNum].isTransformable = pImageMemObjKernelArg->Transformable != 0;
|
||||
patchInfo.imageMemObjKernelArgs.push_back(pImageMemObjKernelArg);
|
||||
@@ -311,8 +269,6 @@ void KernelInfo::storeKernelArgument(
|
||||
usesSsh |= true;
|
||||
storeKernelArgPatchInfo(argNum, 0, 0, 0, offsetSurfaceState);
|
||||
kernelArgInfo[argNum].isBuffer = true;
|
||||
|
||||
patchInfo.globalMemObjKernelArgs.push_back(pGlobalMemObjKernelArg);
|
||||
}
|
||||
|
||||
void KernelInfo::storeKernelArgument(
|
||||
@@ -417,43 +373,6 @@ void KernelInfo::storePatchToken(const SPatchAllocateSyncBuffer *pAllocateSyncBu
|
||||
patchInfo.pAllocateSyncBuffer = pAllocateSyncBuffer;
|
||||
}
|
||||
|
||||
cl_int KernelInfo::resolveKernelInfo() {
|
||||
cl_int retVal = CL_SUCCESS;
|
||||
std::unordered_map<std::string, uint32_t>::iterator iterUint;
|
||||
std::unordered_map<std::string, size_t>::iterator iterSizeT;
|
||||
|
||||
for (auto &argInfo : kernelArgInfo) {
|
||||
iterUint = accessQualifierMap.find(argInfo.accessQualifierStr);
|
||||
if (iterUint != accessQualifierMap.end()) {
|
||||
argInfo.accessQualifier = iterUint->second;
|
||||
} else {
|
||||
retVal = CL_INVALID_BINARY;
|
||||
break;
|
||||
}
|
||||
|
||||
iterUint = addressQualifierMap.find(argInfo.addressQualifierStr);
|
||||
if (iterUint != addressQualifierMap.end()) {
|
||||
argInfo.addressQualifier = iterUint->second;
|
||||
} else {
|
||||
retVal = CL_INVALID_BINARY;
|
||||
break;
|
||||
}
|
||||
|
||||
auto qualifierCount = sizeof(typeQualifiers) / sizeof(typeQualifiers[0]);
|
||||
|
||||
for (auto qualifierId = 0u; qualifierId < qualifierCount; qualifierId++) {
|
||||
if (strstr(argInfo.typeQualifierStr.c_str(), typeQualifiers[qualifierId].argTypeQualifier) != nullptr) {
|
||||
argInfo.typeQualifier |= typeQualifiers[qualifierId].argTypeQualifierValue;
|
||||
if (argInfo.typeQualifier == CL_KERNEL_ARG_TYPE_CONST) {
|
||||
argInfo.isReadOnly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void KernelInfo::storeKernelArgPatchInfo(uint32_t argNum, uint32_t dataSize, uint32_t dataOffset, uint32_t sourceOffset, uint32_t offsetSSH) {
|
||||
resizeKernelArgInfoAndRegisterParameter(argNum);
|
||||
|
||||
@@ -505,4 +424,17 @@ bool KernelInfo::createKernelAllocation(uint32_t rootDeviceIndex, MemoryManager
|
||||
return memoryManager->copyMemoryToAllocation(kernelAllocation, heapInfo.pKernelHeap, kernelIsaSize);
|
||||
}
|
||||
|
||||
std::string concatenateKernelNames(ArrayRef<KernelInfo *> kernelInfos) {
|
||||
std::string semiColonDelimitedKernelNameStr;
|
||||
|
||||
for (const auto &kernelInfo : kernelInfos) {
|
||||
if (!semiColonDelimitedKernelNameStr.empty()) {
|
||||
semiColonDelimitedKernelNameStr += ';';
|
||||
}
|
||||
semiColonDelimitedKernelNameStr += kernelInfo->name;
|
||||
}
|
||||
|
||||
return semiColonDelimitedKernelNameStr;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
#pragma once
|
||||
#include "core/helpers/hw_info.h"
|
||||
#include "core/utilities/arrayref.h"
|
||||
#include "core/utilities/const_stringref.h"
|
||||
#include "runtime/program/heap_info.h"
|
||||
#include "runtime/program/kernel_arg_info.h"
|
||||
|
||||
#include "CL/cl.h"
|
||||
#include "ocl_igc_shared/gtpin/gtpin_driver_common.h"
|
||||
#include "patch_info.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -23,6 +23,10 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace gtpin {
|
||||
typedef struct igc_info_s igc_info_t;
|
||||
}
|
||||
|
||||
namespace NEO {
|
||||
class BuiltinDispatchInfoBuilder;
|
||||
class Device;
|
||||
@@ -33,13 +37,11 @@ struct KernelArgumentType;
|
||||
class GraphicsAllocation;
|
||||
class MemoryManager;
|
||||
|
||||
extern std::unordered_map<std::string, uint32_t> accessQualifierMap;
|
||||
extern std::unordered_map<std::string, uint32_t> addressQualifierMap;
|
||||
extern std::map<std::string, size_t> typeSizeMap;
|
||||
|
||||
struct WorkloadInfo {
|
||||
static const uint32_t undefinedOffset;
|
||||
static const uint32_t invalidParentEvent;
|
||||
enum : uint32_t { undefinedOffset = std::numeric_limits<uint32_t>::max() };
|
||||
enum : uint32_t { invalidParentEvent = std::numeric_limits<uint32_t>::max() };
|
||||
|
||||
uint32_t globalWorkOffsetOffsets[3] = {undefinedOffset, undefinedOffset, undefinedOffset};
|
||||
uint32_t globalWorkSizeOffsets[3] = {undefinedOffset, undefinedOffset, undefinedOffset};
|
||||
@@ -90,6 +92,13 @@ struct DebugData {
|
||||
const char *genIsa = nullptr;
|
||||
};
|
||||
|
||||
struct DeviceInfoKernelPayloadConstants {
|
||||
void *slmWindow = nullptr;
|
||||
uint32_t slmWindowSize = 0U;
|
||||
uint32_t computeUnitsUsedForScratch = 0U;
|
||||
uint32_t maxWorkGroupSize = 0U;
|
||||
};
|
||||
|
||||
struct KernelInfo {
|
||||
public:
|
||||
KernelInfo() = default;
|
||||
@@ -97,7 +106,7 @@ struct KernelInfo {
|
||||
KernelInfo &operator=(const KernelInfo &) = delete;
|
||||
~KernelInfo();
|
||||
|
||||
void storeArgInfo(const SPatchKernelArgumentInfo *pkernelArgInfo);
|
||||
void storeArgInfo(uint32_t argNum, ArgTypeMetadata metadata, std::unique_ptr<ArgTypeMetadataExtended> metadataExtended);
|
||||
void storeKernelArgument(const SPatchDataParameterBuffer *pDataParameterKernelArg);
|
||||
void storeKernelArgument(const SPatchStatelessGlobalMemoryObjectKernelArgument *pStatelessGlobalKernelArg);
|
||||
void storeKernelArgument(const SPatchImageMemoryObjectKernelArgument *pImageMemObjKernelArg);
|
||||
@@ -117,7 +126,6 @@ struct KernelInfo {
|
||||
void storePatchToken(const SPatchAllocateSystemThreadSurface *pSystemThreadSurface);
|
||||
void storePatchToken(const SPatchAllocateSyncBuffer *pAllocateSyncBuffer);
|
||||
GraphicsAllocation *getGraphicsAllocation() const { return this->kernelAllocation; }
|
||||
cl_int resolveKernelInfo();
|
||||
void resizeKernelArgInfoAndRegisterParameter(uint32_t argCount) {
|
||||
if (kernelArgInfo.size() <= argCount) {
|
||||
kernelArgInfo.resize(argCount + 1);
|
||||
@@ -171,7 +179,7 @@ struct KernelInfo {
|
||||
int32_t getArgNumByName(const char *name) const {
|
||||
int32_t argNum = 0;
|
||||
for (auto &arg : kernelArgInfo) {
|
||||
if (arg.name == name) {
|
||||
if (arg.metadataExtended && (arg.metadataExtended->argName == name)) {
|
||||
return argNum;
|
||||
}
|
||||
++argNum;
|
||||
@@ -191,7 +199,6 @@ struct KernelInfo {
|
||||
std::vector<std::pair<uint32_t, uint32_t>> childrenKernelsIdOffset;
|
||||
bool usesSsh = false;
|
||||
bool requiresSshForBuffers = false;
|
||||
bool isValid = false;
|
||||
bool isVmeWorkload = false;
|
||||
char *crossThreadData = nullptr;
|
||||
size_t reqdWorkGroupSize[3] = {WorkloadInfo::undefinedOffset, WorkloadInfo::undefinedOffset, WorkloadInfo::undefinedOffset};
|
||||
@@ -210,4 +217,7 @@ struct KernelInfo {
|
||||
bool computeMode = false;
|
||||
const gtpin::igc_info_t *igcInfoForGtpin = nullptr;
|
||||
};
|
||||
|
||||
std::string concatenateKernelNames(ArrayRef<KernelInfo *> kernelInfos);
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
#include "runtime/program/kernel_info.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
using namespace iOpenCL;
|
||||
@@ -29,14 +31,42 @@ inline uint32_t getOffset(T *token) {
|
||||
return WorkloadInfo::undefinedOffset;
|
||||
}
|
||||
|
||||
void populateKernelInfoArgMetadata(KernelInfo &dstKernelInfoArg, const SPatchKernelArgumentInfo *src) {
|
||||
if (nullptr == src) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t argNum = src->ArgumentNumber;
|
||||
|
||||
auto inlineData = PatchTokenBinary::getInlineData(src);
|
||||
|
||||
auto metadataExtended = std::make_unique<ArgTypeMetadataExtended>();
|
||||
metadataExtended->addressQualifier = parseLimitedString(inlineData.addressQualifier.begin(), inlineData.addressQualifier.size());
|
||||
metadataExtended->accessQualifier = parseLimitedString(inlineData.accessQualifier.begin(), inlineData.accessQualifier.size());
|
||||
metadataExtended->argName = parseLimitedString(inlineData.argName.begin(), inlineData.argName.size());
|
||||
|
||||
auto argTypeFull = parseLimitedString(inlineData.typeName.begin(), inlineData.typeName.size());
|
||||
const char *argTypeDelim = strchr(argTypeFull.data(), ';');
|
||||
if (nullptr == argTypeDelim) {
|
||||
argTypeDelim = argTypeFull.data() + argTypeFull.size();
|
||||
}
|
||||
metadataExtended->type = std::string(argTypeFull.data(), argTypeDelim).c_str();
|
||||
metadataExtended->typeQualifiers = parseLimitedString(inlineData.typeQualifiers.begin(), inlineData.typeQualifiers.size());
|
||||
|
||||
ArgTypeMetadata metadata = {};
|
||||
metadata.accessQualifier = KernelArgMetadata::parseAccessQualifier(metadataExtended->accessQualifier);
|
||||
metadata.addressQualifier = KernelArgMetadata::parseAddressSpace(metadataExtended->addressQualifier);
|
||||
metadata.typeQualifiers = KernelArgMetadata::parseTypeQualifiers(metadataExtended->typeQualifiers);
|
||||
|
||||
dstKernelInfoArg.storeArgInfo(argNum, metadata, std::move(metadataExtended));
|
||||
}
|
||||
|
||||
void populateKernelInfoArg(KernelInfo &dstKernelInfo, KernelArgInfo &dstKernelInfoArg, const PatchTokenBinary::KernelArgFromPatchtokens &src) {
|
||||
dstKernelInfoArg.needPatch = true;
|
||||
dstKernelInfo.storeArgInfo(src.argInfo);
|
||||
populateKernelInfoArgMetadata(dstKernelInfo, src.argInfo);
|
||||
if (src.objectArg != nullptr) {
|
||||
switch (src.objectArg->Token) {
|
||||
default:
|
||||
UNRECOVERABLE_IF(true);
|
||||
case PATCH_TOKEN_IMAGE_MEMORY_OBJECT_KERNEL_ARGUMENT:
|
||||
UNRECOVERABLE_IF(PATCH_TOKEN_IMAGE_MEMORY_OBJECT_KERNEL_ARGUMENT != src.objectArg->Token);
|
||||
dstKernelInfo.storeKernelArgument(reinterpret_cast<const SPatchImageMemoryObjectKernelArgument *>(src.objectArg));
|
||||
break;
|
||||
case PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT:
|
||||
@@ -111,7 +141,9 @@ void populateKernelInfoArg(KernelInfo &dstKernelInfo, KernelArgInfo &dstKernelIn
|
||||
dstKernelInfoArg.offsetObjectId = getOffset(src.objectId);
|
||||
}
|
||||
|
||||
void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatchtokens &src) {
|
||||
void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatchtokens &src, uint32_t gpuPointerSizeInBytes,
|
||||
const DeviceInfoKernelPayloadConstants &constants) {
|
||||
UNRECOVERABLE_IF(nullptr == src.header);
|
||||
dst.heapInfo.pKernelHeader = src.header;
|
||||
dst.name = std::string(src.name.begin(), src.name.end()).c_str();
|
||||
dst.heapInfo.pKernelHeap = src.isa.begin();
|
||||
@@ -132,9 +164,7 @@ void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatch
|
||||
dst.patchInfo.threadPayload = src.tokens.threadPayload;
|
||||
dst.patchInfo.dataParameterStream = src.tokens.dataParameterStream;
|
||||
|
||||
dst.patchInfo.kernelArgumentInfo.reserve(src.tokens.kernelArgs.size());
|
||||
dst.kernelArgInfo.resize(src.tokens.kernelArgs.size());
|
||||
dst.argumentsToPatchNum = static_cast<uint32_t>(src.tokens.kernelArgs.size());
|
||||
|
||||
for (size_t i = 0U; i < src.tokens.kernelArgs.size(); ++i) {
|
||||
auto &decodedKernelArg = src.tokens.kernelArgs[i];
|
||||
@@ -184,7 +214,38 @@ void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatch
|
||||
dst.igcInfoForGtpin = reinterpret_cast<const gtpin::igc_info_t *>(src.tokens.gtpinInfo + 1);
|
||||
}
|
||||
|
||||
dst.isValid = (false == NEO::PatchTokenBinary::hasInvalidChecksum(src));
|
||||
dst.gpuPointerSize = gpuPointerSizeInBytes;
|
||||
|
||||
if (dst.patchInfo.dataParameterStream && dst.patchInfo.dataParameterStream->DataParameterStreamSize) {
|
||||
uint32_t crossThreadDataSize = dst.patchInfo.dataParameterStream->DataParameterStreamSize;
|
||||
dst.crossThreadData = new char[crossThreadDataSize];
|
||||
memset(dst.crossThreadData, 0x00, crossThreadDataSize);
|
||||
|
||||
uint32_t privateMemoryStatelessSizeOffset = dst.workloadInfo.privateMemoryStatelessSizeOffset;
|
||||
uint32_t localMemoryStatelessWindowSizeOffset = dst.workloadInfo.localMemoryStatelessWindowSizeOffset;
|
||||
uint32_t localMemoryStatelessWindowStartAddressOffset = dst.workloadInfo.localMemoryStatelessWindowStartAddressOffset;
|
||||
|
||||
if (localMemoryStatelessWindowStartAddressOffset != WorkloadInfo::undefinedOffset) {
|
||||
*(uintptr_t *)&(dst.crossThreadData[localMemoryStatelessWindowStartAddressOffset]) = reinterpret_cast<uintptr_t>(constants.slmWindow);
|
||||
}
|
||||
|
||||
if (localMemoryStatelessWindowSizeOffset != WorkloadInfo::undefinedOffset) {
|
||||
*(uint32_t *)&(dst.crossThreadData[localMemoryStatelessWindowSizeOffset]) = constants.slmWindowSize;
|
||||
}
|
||||
|
||||
uint32_t privateMemorySize = 0U;
|
||||
if (dst.patchInfo.pAllocateStatelessPrivateSurface) {
|
||||
privateMemorySize = dst.patchInfo.pAllocateStatelessPrivateSurface->PerThreadPrivateMemorySize * constants.computeUnitsUsedForScratch * dst.getMaxSimdSize();
|
||||
}
|
||||
|
||||
if (privateMemoryStatelessSizeOffset != WorkloadInfo::undefinedOffset) {
|
||||
*(uint32_t *)&(dst.crossThreadData[privateMemoryStatelessSizeOffset]) = privateMemorySize;
|
||||
}
|
||||
|
||||
if (dst.workloadInfo.maxWorkGroupSizeOffset != WorkloadInfo::undefinedOffset) {
|
||||
*(uint32_t *)&(dst.crossThreadData[dst.workloadInfo.maxWorkGroupSizeOffset]) = constants.maxWorkGroupSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -7,14 +7,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
struct DeviceInfoKernelPayloadConstants;
|
||||
struct KernelInfo;
|
||||
|
||||
namespace PatchTokenBinary {
|
||||
struct KernelFromPatchtokens;
|
||||
}
|
||||
|
||||
void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatchtokens &src);
|
||||
void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatchtokens &src, uint32_t gpuPointerSizeInBytes,
|
||||
const DeviceInfoKernelPayloadConstants &constant);
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -60,8 +60,6 @@ struct PatchInfo {
|
||||
statelessGlobalMemObjKernelArgs;
|
||||
::std::vector<const SPatchImageMemoryObjectKernelArgument *>
|
||||
imageMemObjKernelArgs;
|
||||
::std::vector<const SPatchGlobalMemoryObjectKernelArgument *>
|
||||
globalMemObjKernelArgs;
|
||||
const SPatchDataParameterStream *dataParameterStream = nullptr;
|
||||
const SPatchThreadPayload *threadPayload = nullptr;
|
||||
const SPatchExecutionEnvironment *executionEnvironment = nullptr;
|
||||
@@ -75,7 +73,6 @@ struct PatchInfo {
|
||||
const SPatchAllocateStatelessDefaultDeviceQueueSurface *pAllocateStatelessDefaultDeviceQueueSurface = nullptr;
|
||||
const SPatchAllocateSystemThreadSurface *pAllocateSystemThreadSurface = nullptr;
|
||||
::std::unordered_map<uint32_t, std::string> stringDataMap;
|
||||
::std::vector<const SPatchKernelArgumentInfo *> kernelArgumentInfo;
|
||||
};
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#include "core/helpers/ptr_math.h"
|
||||
#include "core/helpers/string.h"
|
||||
#include "core/memory_manager/unified_memory_manager.h"
|
||||
#include "core/program/program_info.h"
|
||||
#include "core/program/program_info_from_patchtokens.h"
|
||||
#include "core/program/program_initialization.h"
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
#include "runtime/compiler_interface/patchtokens_dumper.h"
|
||||
#include "runtime/compiler_interface/patchtokens_validator.inl"
|
||||
@@ -53,124 +56,6 @@ const KernelInfo *Program::getKernelInfo(size_t ordinal) const {
|
||||
return kernelInfoArray[ordinal];
|
||||
}
|
||||
|
||||
std::string Program::getKernelNamesString() const {
|
||||
std::string semiColonDelimitedKernelNameStr;
|
||||
|
||||
for (auto kernelInfo : kernelInfoArray) {
|
||||
if (!semiColonDelimitedKernelNameStr.empty()) {
|
||||
semiColonDelimitedKernelNameStr += ';';
|
||||
}
|
||||
semiColonDelimitedKernelNameStr += kernelInfo->name;
|
||||
}
|
||||
|
||||
return semiColonDelimitedKernelNameStr;
|
||||
}
|
||||
|
||||
void Program::populateKernelInfo(
|
||||
const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram,
|
||||
uint32_t kernelNum,
|
||||
cl_int &retVal) {
|
||||
|
||||
auto kernelInfo = std::make_unique<KernelInfo>();
|
||||
const PatchTokenBinary::KernelFromPatchtokens &decodedKernel = decodedProgram.kernels[kernelNum];
|
||||
|
||||
NEO::populateKernelInfo(*kernelInfo, decodedKernel);
|
||||
retVal = kernelInfo->resolveKernelInfo();
|
||||
if (retVal != CL_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
kernelInfo->gpuPointerSize = decodedProgram.header->GPUPointerSizeInBytes;
|
||||
|
||||
if (decodedKernel.tokens.programSymbolTable) {
|
||||
prepareLinkerInputStorage();
|
||||
linkerInput->decodeExportedFunctionsSymbolTable(decodedKernel.tokens.programSymbolTable + 1, decodedKernel.tokens.programSymbolTable->NumEntries, kernelNum);
|
||||
}
|
||||
|
||||
if (decodedKernel.tokens.programRelocationTable) {
|
||||
prepareLinkerInputStorage();
|
||||
linkerInput->decodeRelocationTable(decodedKernel.tokens.programRelocationTable + 1, decodedKernel.tokens.programRelocationTable->NumEntries, kernelNum);
|
||||
}
|
||||
|
||||
if (kernelInfo->patchInfo.dataParameterStream && kernelInfo->patchInfo.dataParameterStream->DataParameterStreamSize) {
|
||||
uint32_t crossThreadDataSize = kernelInfo->patchInfo.dataParameterStream->DataParameterStreamSize;
|
||||
kernelInfo->crossThreadData = new char[crossThreadDataSize];
|
||||
memset(kernelInfo->crossThreadData, 0x00, crossThreadDataSize);
|
||||
|
||||
uint32_t privateMemoryStatelessSizeOffset = kernelInfo->workloadInfo.privateMemoryStatelessSizeOffset;
|
||||
uint32_t localMemoryStatelessWindowSizeOffset = kernelInfo->workloadInfo.localMemoryStatelessWindowSizeOffset;
|
||||
uint32_t localMemoryStatelessWindowStartAddressOffset = kernelInfo->workloadInfo.localMemoryStatelessWindowStartAddressOffset;
|
||||
|
||||
if (localMemoryStatelessWindowStartAddressOffset != 0xFFffFFff) {
|
||||
*(uintptr_t *)&(kernelInfo->crossThreadData[localMemoryStatelessWindowStartAddressOffset]) = reinterpret_cast<uintptr_t>(this->executionEnvironment.memoryManager->getReservedMemory(MemoryConstants::slmWindowSize, MemoryConstants::slmWindowAlignment));
|
||||
}
|
||||
|
||||
if (localMemoryStatelessWindowSizeOffset != 0xFFffFFff) {
|
||||
*(uint32_t *)&(kernelInfo->crossThreadData[localMemoryStatelessWindowSizeOffset]) = (uint32_t)this->pDevice->getDeviceInfo().localMemSize;
|
||||
}
|
||||
|
||||
if (kernelInfo->patchInfo.pAllocateStatelessPrivateSurface && (privateMemoryStatelessSizeOffset != 0xFFffFFff)) {
|
||||
*(uint32_t *)&(kernelInfo->crossThreadData[privateMemoryStatelessSizeOffset]) = kernelInfo->patchInfo.pAllocateStatelessPrivateSurface->PerThreadPrivateMemorySize * this->getDevice(0).getDeviceInfo().computeUnitsUsedForScratch * kernelInfo->getMaxSimdSize();
|
||||
}
|
||||
|
||||
if (kernelInfo->workloadInfo.maxWorkGroupSizeOffset != WorkloadInfo::undefinedOffset) {
|
||||
*(uint32_t *)&(kernelInfo->crossThreadData[kernelInfo->workloadInfo.maxWorkGroupSizeOffset]) = (uint32_t)this->getDevice(0).getDeviceInfo().maxWorkGroupSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (kernelInfo->heapInfo.pKernelHeader->KernelHeapSize && this->pDevice) {
|
||||
retVal = kernelInfo->createKernelAllocation(this->pDevice->getRootDeviceIndex(), this->pDevice->getMemoryManager()) ? CL_SUCCESS : CL_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
DEBUG_BREAK_IF(kernelInfo->heapInfo.pKernelHeader->KernelHeapSize && !this->pDevice);
|
||||
if (retVal != CL_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (kernelInfo->hasDeviceEnqueue()) {
|
||||
parentKernelInfoArray.push_back(kernelInfo.get());
|
||||
}
|
||||
if (kernelInfo->requiresSubgroupIndependentForwardProgress()) {
|
||||
subgroupKernelInfoArray.push_back(kernelInfo.get());
|
||||
}
|
||||
kernelInfoArray.push_back(kernelInfo.release());
|
||||
}
|
||||
|
||||
inline uint64_t readMisalignedUint64(const uint64_t *address) {
|
||||
const uint32_t *addressBits = reinterpret_cast<const uint32_t *>(address);
|
||||
return static_cast<uint64_t>(static_cast<uint64_t>(addressBits[1]) << 32) | addressBits[0];
|
||||
}
|
||||
|
||||
GraphicsAllocation *allocateGlobalsSurface(NEO::Context *ctx, NEO::ClDevice *device, size_t size, bool constant, bool globalsAreExported, const void *initData) {
|
||||
UNRECOVERABLE_IF(device == nullptr);
|
||||
if (globalsAreExported && (ctx != nullptr) && (ctx->getSVMAllocsManager() != nullptr)) {
|
||||
NEO::SVMAllocsManager::SvmAllocationProperties svmProps = {};
|
||||
svmProps.coherent = false;
|
||||
svmProps.readOnly = constant;
|
||||
svmProps.hostPtrReadOnly = constant;
|
||||
auto ptr = ctx->getSVMAllocsManager()->createSVMAlloc(device->getRootDeviceIndex(), size, svmProps);
|
||||
DEBUG_BREAK_IF(ptr == nullptr);
|
||||
if (ptr == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto svmAlloc = ctx->getSVMAllocsManager()->getSVMAlloc(ptr);
|
||||
UNRECOVERABLE_IF(svmAlloc == nullptr);
|
||||
auto gpuAlloc = svmAlloc->gpuAllocation;
|
||||
UNRECOVERABLE_IF(gpuAlloc == nullptr);
|
||||
device->getMemoryManager()->copyMemoryToAllocation(gpuAlloc, initData, static_cast<uint32_t>(size));
|
||||
return ctx->getSVMAllocsManager()->getSVMAlloc(ptr)->gpuAllocation;
|
||||
} else {
|
||||
auto allocationType = constant ? GraphicsAllocation::AllocationType::CONSTANT_SURFACE : GraphicsAllocation::AllocationType::GLOBAL_SURFACE;
|
||||
auto gpuAlloc = device->getMemoryManager()->allocateGraphicsMemoryWithProperties({device->getRootDeviceIndex(), size, allocationType});
|
||||
DEBUG_BREAK_IF(gpuAlloc == nullptr);
|
||||
if (gpuAlloc == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
memcpy_s(gpuAlloc->getUnderlyingBuffer(), gpuAlloc->getUnderlyingBufferSize(), initData, size);
|
||||
return gpuAlloc;
|
||||
}
|
||||
}
|
||||
|
||||
cl_int Program::isHandled(const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram) const {
|
||||
std::string validatorErrMessage;
|
||||
std::string validatorWarnings;
|
||||
@@ -191,76 +76,27 @@ cl_int Program::isHandled(const PatchTokenBinary::ProgramFromPatchtokens &decode
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
void Program::processProgramScopeMetadata(const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram) {
|
||||
if (decodedProgram.programScopeTokens.symbolTable != nullptr) {
|
||||
const auto patch = decodedProgram.programScopeTokens.symbolTable;
|
||||
this->prepareLinkerInputStorage();
|
||||
this->linkerInput->decodeGlobalVariablesSymbolTable(patch + 1, patch->NumEntries);
|
||||
}
|
||||
|
||||
if (decodedProgram.programScopeTokens.allocateConstantMemorySurface.size() != 0) {
|
||||
pDevice->getMemoryManager()->freeGraphicsMemory(this->constantSurface);
|
||||
|
||||
auto exportsGlobals = (linkerInput && linkerInput->getTraits().exportsGlobalConstants);
|
||||
size_t globalConstantsSurfaceSize = decodedProgram.programScopeTokens.allocateConstantMemorySurface[0]->InlineDataSize;
|
||||
const void *globalConstantsInitData = NEO::PatchTokenBinary::getInlineData(decodedProgram.programScopeTokens.allocateConstantMemorySurface[0]);
|
||||
this->constantSurface = allocateGlobalsSurface(context, pDevice, globalConstantsSurfaceSize, true, exportsGlobals, globalConstantsInitData);
|
||||
}
|
||||
|
||||
if (decodedProgram.programScopeTokens.allocateGlobalMemorySurface.size() != 0) {
|
||||
pDevice->getMemoryManager()->freeGraphicsMemory(this->globalSurface);
|
||||
|
||||
auto exportsGlobals = (linkerInput && linkerInput->getTraits().exportsGlobalVariables);
|
||||
size_t globalVariablesSurfaceSize = decodedProgram.programScopeTokens.allocateGlobalMemorySurface[0]->InlineDataSize;
|
||||
const void *globalVariablesInitData = NEO::PatchTokenBinary::getInlineData(decodedProgram.programScopeTokens.allocateGlobalMemorySurface[0]);
|
||||
this->globalVarTotalSize = globalVariablesSurfaceSize;
|
||||
this->globalSurface = allocateGlobalsSurface(context, pDevice, globalVariablesSurfaceSize, false, exportsGlobals, globalVariablesInitData);
|
||||
}
|
||||
|
||||
for (const auto &globalConstantPointerToken : decodedProgram.programScopeTokens.constantPointer) {
|
||||
NEO::GraphicsAllocation *srcSurface = this->constantSurface;
|
||||
if (globalConstantPointerToken->BufferType != PROGRAM_SCOPE_CONSTANT_BUFFER) {
|
||||
UNRECOVERABLE_IF(globalConstantPointerToken->BufferType != PROGRAM_SCOPE_GLOBAL_BUFFER);
|
||||
srcSurface = this->globalSurface;
|
||||
}
|
||||
UNRECOVERABLE_IF(srcSurface == nullptr);
|
||||
UNRECOVERABLE_IF(this->constantSurface == nullptr);
|
||||
auto offset = readMisalignedUint64(&globalConstantPointerToken->ConstantPointerOffset);
|
||||
UNRECOVERABLE_IF(this->constantSurface->getUnderlyingBufferSize() < ((offset + constantSurface->is32BitAllocation()) ? 4 : sizeof(uintptr_t)));
|
||||
void *patchOffset = ptrOffset(this->constantSurface->getUnderlyingBuffer(), static_cast<size_t>(offset));
|
||||
patchIncrement(patchOffset, constantSurface->is32BitAllocation() ? 4 : sizeof(uintptr_t), srcSurface->getGpuAddressToPatch());
|
||||
}
|
||||
|
||||
for (const auto &globalVariablePointerToken : decodedProgram.programScopeTokens.globalPointer) {
|
||||
NEO::GraphicsAllocation *srcSurface = this->globalSurface;
|
||||
if (globalVariablePointerToken->BufferType != PROGRAM_SCOPE_GLOBAL_BUFFER) {
|
||||
UNRECOVERABLE_IF(globalVariablePointerToken->BufferType != PROGRAM_SCOPE_CONSTANT_BUFFER);
|
||||
srcSurface = this->constantSurface;
|
||||
}
|
||||
UNRECOVERABLE_IF(srcSurface == nullptr);
|
||||
UNRECOVERABLE_IF(this->globalSurface == nullptr);
|
||||
auto offset = readMisalignedUint64(&globalVariablePointerToken->GlobalPointerOffset);
|
||||
UNRECOVERABLE_IF(this->globalSurface->getUnderlyingBufferSize() < ((offset + globalSurface->is32BitAllocation()) ? 4 : sizeof(uintptr_t)));
|
||||
void *patchOffset = ptrOffset(this->globalSurface->getUnderlyingBuffer(), static_cast<size_t>(offset));
|
||||
patchIncrement(patchOffset, globalSurface->is32BitAllocation() ? 4 : sizeof(uintptr_t), srcSurface->getGpuAddressToPatch());
|
||||
}
|
||||
}
|
||||
|
||||
cl_int Program::linkBinary() {
|
||||
if (linkerInput == nullptr) {
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
Linker linker(*linkerInput);
|
||||
Linker::Segment globals;
|
||||
Linker::Segment constants;
|
||||
Linker::Segment exportedFunctions;
|
||||
Linker::SegmentInfo globals;
|
||||
Linker::SegmentInfo constants;
|
||||
Linker::SegmentInfo exportedFunctions;
|
||||
Linker::PatchableSegment globalsForPatching;
|
||||
Linker::PatchableSegment constantsForPatching;
|
||||
if (this->globalSurface != nullptr) {
|
||||
globals.gpuAddress = static_cast<uintptr_t>(this->globalSurface->getGpuAddress());
|
||||
globals.segmentSize = this->globalSurface->getUnderlyingBufferSize();
|
||||
globalsForPatching.hostPointer = this->globalSurface->getUnderlyingBuffer();
|
||||
globalsForPatching.segmentSize = this->globalSurface->getUnderlyingBufferSize();
|
||||
}
|
||||
if (this->constantSurface != nullptr) {
|
||||
constants.gpuAddress = static_cast<uintptr_t>(this->constantSurface->getGpuAddress());
|
||||
constants.segmentSize = this->constantSurface->getUnderlyingBufferSize();
|
||||
constantsForPatching.hostPointer = this->constantSurface->getUnderlyingBuffer();
|
||||
constantsForPatching.segmentSize = this->constantSurface->getUnderlyingBufferSize();
|
||||
}
|
||||
if (this->linkerInput->getExportedFunctionsSegmentId() >= 0) {
|
||||
// Exported functions reside in instruction heap of one of kernels
|
||||
@@ -283,6 +119,7 @@ cl_int Program::linkBinary() {
|
||||
|
||||
Linker::UnresolvedExternals unresolvedExternalsInfo;
|
||||
bool linkSuccess = linker.link(globals, constants, exportedFunctions,
|
||||
globalsForPatching, constantsForPatching,
|
||||
isaSegmentsForPatching, unresolvedExternalsInfo);
|
||||
this->symbols = linker.extractRelocatedSymbols();
|
||||
if (false == linkSuccess) {
|
||||
@@ -295,6 +132,9 @@ cl_int Program::linkBinary() {
|
||||
return CL_INVALID_BINARY;
|
||||
} else if (linkerInput->getTraits().requiresPatchingOfInstructionSegments) {
|
||||
for (const auto &kernelInfo : this->kernelInfoArray) {
|
||||
if (nullptr == kernelInfo->getGraphicsAllocation()) {
|
||||
continue;
|
||||
}
|
||||
auto &kernHeapInfo = kernelInfo->heapInfo;
|
||||
auto segmentId = &kernelInfo - &this->kernelInfoArray[0];
|
||||
this->pDevice->getMemoryManager()->copyMemoryToAllocation(kernelInfo->getGraphicsAllocation(),
|
||||
@@ -307,30 +147,83 @@ cl_int Program::linkBinary() {
|
||||
|
||||
cl_int Program::processGenBinary() {
|
||||
cleanCurrentKernelInfo();
|
||||
if (this->constantSurface || this->globalSurface) {
|
||||
pDevice->getMemoryManager()->freeGraphicsMemory(this->constantSurface);
|
||||
pDevice->getMemoryManager()->freeGraphicsMemory(this->globalSurface);
|
||||
this->constantSurface = nullptr;
|
||||
this->globalSurface = nullptr;
|
||||
}
|
||||
|
||||
auto blob = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(genBinary.get()), genBinarySize);
|
||||
ProgramInfo programInfo;
|
||||
auto ret = this->processPatchTokensBinary(blob, programInfo);
|
||||
if (CL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return this->processProgramInfo(programInfo);
|
||||
}
|
||||
|
||||
cl_int Program::processPatchTokensBinary(ArrayRef<const uint8_t> src, ProgramInfo &dst) {
|
||||
NEO::PatchTokenBinary::ProgramFromPatchtokens decodedProgram = {};
|
||||
NEO::PatchTokenBinary::decodeProgramFromPatchtokensBlob(blob, decodedProgram);
|
||||
NEO::PatchTokenBinary::decodeProgramFromPatchtokensBlob(src, decodedProgram);
|
||||
DBG_LOG(LogPatchTokens, NEO::PatchTokenBinary::asString(decodedProgram).c_str());
|
||||
cl_int retVal = this->isHandled(decodedProgram);
|
||||
if (CL_SUCCESS != retVal) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
auto numKernels = decodedProgram.header->NumberOfKernels;
|
||||
for (uint32_t i = 0; i < numKernels && retVal == CL_SUCCESS; i++) {
|
||||
populateKernelInfo(decodedProgram, i, retVal);
|
||||
NEO::DeviceInfoKernelPayloadConstants deviceInfoConstants;
|
||||
if (this->pDevice) {
|
||||
deviceInfoConstants.maxWorkGroupSize = (uint32_t)this->pDevice->getDeviceInfo().maxWorkGroupSize;
|
||||
deviceInfoConstants.computeUnitsUsedForScratch = this->pDevice->getDeviceInfo().computeUnitsUsedForScratch;
|
||||
deviceInfoConstants.slmWindowSize = (uint32_t)this->pDevice->getDeviceInfo().localMemSize;
|
||||
if (requiresLocalMemoryWindowVA(decodedProgram)) {
|
||||
deviceInfoConstants.slmWindow = this->executionEnvironment.memoryManager->getReservedMemory(MemoryConstants::slmWindowSize, MemoryConstants::slmWindowAlignment);
|
||||
}
|
||||
}
|
||||
|
||||
if (retVal != CL_SUCCESS) {
|
||||
return retVal;
|
||||
NEO::populateProgramInfo(dst, decodedProgram, deviceInfoConstants);
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
cl_int Program::processProgramInfo(ProgramInfo &src) {
|
||||
this->linkerInput = std::move(src.linkerInput);
|
||||
this->kernelInfoArray = std::move(src.kernelInfos);
|
||||
auto svmAllocsManager = context ? context->getSVMAllocsManager() : nullptr;
|
||||
if (src.globalConstants.size != 0) {
|
||||
UNRECOVERABLE_IF(nullptr == pDevice);
|
||||
this->constantSurface = allocateGlobalsSurface(svmAllocsManager, pDevice->getDevice(), src.globalConstants.size, true, linkerInput.get(), src.globalConstants.initData);
|
||||
}
|
||||
|
||||
processProgramScopeMetadata(decodedProgram);
|
||||
if (src.globalVariables.size != 0) {
|
||||
UNRECOVERABLE_IF(nullptr == pDevice);
|
||||
this->globalSurface = allocateGlobalsSurface(svmAllocsManager, pDevice->getDevice(), src.globalVariables.size, false, linkerInput.get(), src.globalVariables.initData);
|
||||
}
|
||||
|
||||
retVal = linkBinary();
|
||||
this->globalVarTotalSize = src.globalVariables.size;
|
||||
|
||||
return retVal;
|
||||
for (auto &kernelInfo : this->kernelInfoArray) {
|
||||
cl_int retVal = CL_SUCCESS;
|
||||
if (kernelInfo->heapInfo.pKernelHeader->KernelHeapSize && this->pDevice) {
|
||||
retVal = kernelInfo->createKernelAllocation(this->pDevice->getRootDeviceIndex(), this->pDevice->getMemoryManager()) ? CL_SUCCESS : CL_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
DEBUG_BREAK_IF(kernelInfo->heapInfo.pKernelHeader->KernelHeapSize && !this->pDevice);
|
||||
if (retVal != CL_SUCCESS) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
if (kernelInfo->hasDeviceEnqueue()) {
|
||||
parentKernelInfoArray.push_back(kernelInfo);
|
||||
}
|
||||
if (kernelInfo->requiresSubgroupIndependentForwardProgress()) {
|
||||
subgroupKernelInfoArray.push_back(kernelInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return linkBinary();
|
||||
}
|
||||
|
||||
bool Program::validateGenBinaryDevice(GFXCORE_FAMILY device) const {
|
||||
|
||||
@@ -456,9 +456,4 @@ void Program::updateNonUniformFlag(const Program **inputPrograms, size_t numInpu
|
||||
this->allowNonUniform = allowNonUniform;
|
||||
}
|
||||
|
||||
void Program::prepareLinkerInputStorage() {
|
||||
if (this->linkerInput == nullptr) {
|
||||
this->linkerInput = std::make_unique<LinkerInput>();
|
||||
}
|
||||
}
|
||||
} // namespace NEO
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "core/compiler_interface/compiler_interface.h"
|
||||
#include "core/compiler_interface/linker.h"
|
||||
#include "core/elf/writer.h"
|
||||
#include "core/program/program_info.h"
|
||||
#include "core/utilities/const_stringref.h"
|
||||
#include "runtime/api/cl_types.h"
|
||||
#include "runtime/helpers/base_object.h"
|
||||
@@ -131,6 +132,8 @@ class Program : public BaseObject<_cl_program> {
|
||||
std::unordered_map<std::string, BuiltinDispatchInfoBuilder *> &builtinsMap);
|
||||
|
||||
MOCKABLE_VIRTUAL cl_int processGenBinary();
|
||||
MOCKABLE_VIRTUAL cl_int processPatchTokensBinary(ArrayRef<const uint8_t> src, ProgramInfo &dst);
|
||||
MOCKABLE_VIRTUAL cl_int processProgramInfo(ProgramInfo &dst);
|
||||
|
||||
cl_int compile(cl_uint numDevices, const cl_device_id *deviceList, const char *buildOptions,
|
||||
cl_uint numInputHeaders, const cl_program *inputHeaders, const char **headerIncludeNames,
|
||||
@@ -269,16 +272,12 @@ class Program : public BaseObject<_cl_program> {
|
||||
MOCKABLE_VIRTUAL cl_int linkBinary();
|
||||
|
||||
MOCKABLE_VIRTUAL cl_int isHandled(const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram) const;
|
||||
void processProgramScopeMetadata(const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram);
|
||||
void populateKernelInfo(const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram, uint32_t kernelNum, cl_int &retVal);
|
||||
|
||||
MOCKABLE_VIRTUAL cl_int rebuildProgramFromIr();
|
||||
|
||||
bool validateGenBinaryDevice(GFXCORE_FAMILY device) const;
|
||||
bool validateGenBinaryHeader(const iOpenCL::SProgramBinaryHeader *pGenBinaryHeader) const;
|
||||
|
||||
std::string getKernelNamesString() const;
|
||||
|
||||
void separateBlockKernels();
|
||||
|
||||
void updateNonUniformFlag();
|
||||
@@ -292,8 +291,6 @@ class Program : public BaseObject<_cl_program> {
|
||||
MOCKABLE_VIRTUAL bool appendKernelDebugOptions();
|
||||
void notifyDebuggerWithSourceCode(std::string &filename);
|
||||
|
||||
void prepareLinkerInputStorage();
|
||||
|
||||
static const std::string clOptNameClVer;
|
||||
|
||||
cl_program_binary_type programBinaryType;
|
||||
@@ -354,6 +351,4 @@ class Program : public BaseObject<_cl_program> {
|
||||
bool kernelDebugEnabled = false;
|
||||
};
|
||||
|
||||
GraphicsAllocation *allocateGlobalsSurface(NEO::Context *ctx, NEO::ClDevice *device, size_t size, bool constant, bool globalsAreExported, const void *initData);
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -178,9 +178,9 @@ void FileLogger<DebugLevel>::dumpKernelArgs(const Kernel *kernel) {
|
||||
|
||||
auto &argInfo = kernel->getKernelInfo().kernelArgInfo[i];
|
||||
|
||||
if (argInfo.addressQualifier == CL_KERNEL_ARG_ADDRESS_LOCAL) {
|
||||
if (argInfo.metadata.addressQualifier == KernelArgMetadata::AddressSpaceQualifier::Local) {
|
||||
type = "local";
|
||||
} else if (argInfo.typeStr.find("image") != std::string::npos) {
|
||||
} else if (argInfo.isImage) {
|
||||
type = "image";
|
||||
auto clMem = (const cl_mem)kernel->getKernelArg(i);
|
||||
auto memObj = castToObject<MemObj>(clMem);
|
||||
@@ -189,9 +189,9 @@ void FileLogger<DebugLevel>::dumpKernelArgs(const Kernel *kernel) {
|
||||
size = memObj->getSize();
|
||||
flags = memObj->getMemoryPropertiesFlags();
|
||||
}
|
||||
} else if (argInfo.typeStr.find("sampler") != std::string::npos) {
|
||||
} else if (argInfo.isSampler) {
|
||||
type = "sampler";
|
||||
} else if (argInfo.typeStr.find("*") != std::string::npos) {
|
||||
} else if (argInfo.isBuffer) {
|
||||
type = "buffer";
|
||||
auto clMem = (const cl_mem)kernel->getKernelArg(i);
|
||||
auto memObj = castToObject<MemObj>(clMem);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -172,7 +172,7 @@ TEST_F(clBuildProgramTests, GivenProgramCreatedFromBinaryWhenBuildProgramWithOpt
|
||||
TEST_F(clBuildProgramTests, GivenSpirAsInputWhenCreatingProgramFromBinaryThenProgramBuildSucceeds) {
|
||||
cl_program pProgram = nullptr;
|
||||
cl_int binaryStatus = CL_SUCCESS;
|
||||
unsigned char llvm[16] = "BC\xc0\xde";
|
||||
unsigned char llvm[16] = "BC\xc0\xde_unique";
|
||||
size_t binarySize = sizeof(llvm);
|
||||
|
||||
const unsigned char *binaries[1] = {llvm};
|
||||
@@ -193,6 +193,7 @@ TEST_F(clBuildProgramTests, GivenSpirAsInputWhenCreatingProgramFromBinaryThenPro
|
||||
progBin.Magic = iOpenCL::MAGIC_CL;
|
||||
progBin.Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
progBin.Device = pContext->getDevice(0)->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
progBin.GPUPointerSizeInBytes = sizeof(uintptr_t);
|
||||
igcDebugVars.binaryToReturn = &progBin;
|
||||
igcDebugVars.binaryToReturnSize = sizeof(progBin);
|
||||
auto prevDebugVars = getIgcDebugVars();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -73,24 +73,6 @@ TEST_F(clCreateKernelTests, GivenCorrectKernelInProgramWhenCreatingNewKernelThen
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
}
|
||||
|
||||
TEST_F(clCreateKernelTests, GivenInvalidKernelWhenCreatingNewKernelThenInvalidProgramExecutableErrorIsReturned) {
|
||||
cl_kernel kernel = nullptr;
|
||||
KernelInfo *pKernelInfo = new KernelInfo();
|
||||
pKernelInfo->isValid = false;
|
||||
|
||||
std::unique_ptr<MockProgram> pMockProg = std::make_unique<MockProgram>(*pPlatform->peekExecutionEnvironment(), pContext, false);
|
||||
pMockProg->addKernelInfo(pKernelInfo);
|
||||
pMockProg->SetBuildStatus(CL_BUILD_SUCCESS);
|
||||
|
||||
kernel = clCreateKernel(
|
||||
pMockProg.get(),
|
||||
"",
|
||||
&retVal);
|
||||
|
||||
EXPECT_EQ(CL_INVALID_PROGRAM_EXECUTABLE, retVal);
|
||||
EXPECT_EQ(nullptr, kernel);
|
||||
}
|
||||
|
||||
TEST_F(clCreateKernelTests, GivenInvalidKernelNameWhenCreatingNewKernelThenInvalidKernelNameErrorIsReturned) {
|
||||
cl_kernel kernel = nullptr;
|
||||
cl_program pProgram = nullptr;
|
||||
@@ -157,7 +139,6 @@ TEST_F(clCreateKernelTests, GivenNullProgramWhenCreatingNewKernelThenInvalidProg
|
||||
TEST_F(clCreateKernelTests, GivenNullKernelNameWhenCreatingNewKernelThenInvalidValueErrorIsReturned) {
|
||||
cl_kernel kernel = nullptr;
|
||||
KernelInfo *pKernelInfo = new KernelInfo();
|
||||
pKernelInfo->isValid = true;
|
||||
|
||||
std::unique_ptr<MockProgram> pMockProg = std::make_unique<MockProgram>(*pPlatform->peekExecutionEnvironment(), pContext, false);
|
||||
pMockProg->addKernelInfo(pKernelInfo);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -17,7 +17,7 @@ using clGetDeviceFunctionPointer = api_tests;
|
||||
TEST_F(clGetDeviceGlobalVariablePointer, GivenNullMandatoryArgumentsThenReturnInvalidArgError) {
|
||||
this->pProgram->symbols["A"].gpuAddress = 7U;
|
||||
this->pProgram->symbols["A"].symbol.size = 64U;
|
||||
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::GlobalVariable;
|
||||
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
|
||||
|
||||
void *globalRet = 0;
|
||||
auto ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr, &globalRet);
|
||||
@@ -37,7 +37,7 @@ TEST_F(clGetDeviceGlobalVariablePointer, GivenNullMandatoryArgumentsThenReturnIn
|
||||
TEST_F(clGetDeviceGlobalVariablePointer, GivenValidSymbolNameThenReturnProperAddressAndSize) {
|
||||
this->pProgram->symbols["A"].gpuAddress = 7U;
|
||||
this->pProgram->symbols["A"].symbol.size = 64U;
|
||||
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::GlobalVariable;
|
||||
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
|
||||
|
||||
void *globalRet = 0;
|
||||
size_t sizeRet = 0;
|
||||
@@ -50,7 +50,7 @@ TEST_F(clGetDeviceGlobalVariablePointer, GivenValidSymbolNameThenReturnProperAdd
|
||||
TEST_F(clGetDeviceGlobalVariablePointer, GivenFunctionSymbolNameThenReturnInvalidArgError) {
|
||||
this->pProgram->symbols["A"].gpuAddress = 7U;
|
||||
this->pProgram->symbols["A"].symbol.size = 64U;
|
||||
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::Function;
|
||||
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
|
||||
|
||||
void *globalRet = 0;
|
||||
auto ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr, &globalRet);
|
||||
@@ -66,7 +66,7 @@ TEST_F(clGetDeviceGlobalVariablePointer, GivenUnknownSymbolNameThenReturnInvalid
|
||||
TEST_F(clGetDeviceFunctionPointer, GivenNullMandatoryArgumentsThenReturnInvalidArgError) {
|
||||
this->pProgram->symbols["A"].gpuAddress = 7U;
|
||||
this->pProgram->symbols["A"].symbol.size = 64U;
|
||||
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::Function;
|
||||
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
|
||||
|
||||
cl_ulong fptrRet = 0;
|
||||
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
|
||||
@@ -86,7 +86,7 @@ TEST_F(clGetDeviceFunctionPointer, GivenNullMandatoryArgumentsThenReturnInvalidA
|
||||
TEST_F(clGetDeviceFunctionPointer, GivenValidSymbolNameThenReturnProperAddress) {
|
||||
this->pProgram->symbols["A"].gpuAddress = 7U;
|
||||
this->pProgram->symbols["A"].symbol.size = 64U;
|
||||
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::Function;
|
||||
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
|
||||
|
||||
cl_ulong fptrRet = 0;
|
||||
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
|
||||
@@ -97,10 +97,10 @@ TEST_F(clGetDeviceFunctionPointer, GivenValidSymbolNameThenReturnProperAddress)
|
||||
TEST_F(clGetDeviceFunctionPointer, GivenGlobalSymbolNameThenReturnInvalidArgError) {
|
||||
this->pProgram->symbols["A"].gpuAddress = 7U;
|
||||
this->pProgram->symbols["A"].symbol.size = 64U;
|
||||
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::GlobalVariable;
|
||||
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
|
||||
this->pProgram->symbols["B"].gpuAddress = 7U;
|
||||
this->pProgram->symbols["B"].symbol.size = 64U;
|
||||
this->pProgram->symbols["B"].symbol.type = NEO::SymbolInfo::GlobalConstant;
|
||||
this->pProgram->symbols["B"].symbol.segment = NEO::SegmentType::GlobalConstants;
|
||||
|
||||
cl_ulong fptrRet = 0;
|
||||
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
|
||||
|
||||
@@ -42,8 +42,7 @@ class KernelArgSvmFixture : public ApiFixture, public DeviceFixture {
|
||||
|
||||
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset = 0x30;
|
||||
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].size = (uint32_t)sizeof(void *);
|
||||
pKernelInfo->kernelArgInfo[0].typeStr = "char *";
|
||||
pKernelInfo->kernelArgInfo[0].addressQualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL;
|
||||
pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Global;
|
||||
|
||||
pMockKernel = new MockKernel(pProgram, *pKernelInfo, *this->pClDevice);
|
||||
ASSERT_EQ(CL_SUCCESS, pMockKernel->initialize());
|
||||
@@ -88,7 +87,7 @@ TEST_F(clSetKernelArgSVMPointerTests, GivenInvalidArgIndexWhenSettingKernelArgTh
|
||||
}
|
||||
|
||||
TEST_F(clSetKernelArgSVMPointerTests, GivenLocalAddressAndNullArgValueWhenSettingKernelArgThenInvalidArgValueErrorIsReturned) {
|
||||
pKernelInfo->kernelArgInfo[0].addressQualifier = CL_KERNEL_ARG_ADDRESS_LOCAL;
|
||||
pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Local;
|
||||
|
||||
auto retVal = clSetKernelArgSVMPointer(
|
||||
pMockKernel, // cl_kernel kernel
|
||||
@@ -148,7 +147,7 @@ TEST_F(clSetKernelArgSVMPointerTests, GivenSvmAndConstantAddressWhenSettingKerne
|
||||
void *ptrSvm = clSVMAlloc(pContext, CL_MEM_READ_WRITE, 256, 4);
|
||||
EXPECT_NE(nullptr, ptrSvm);
|
||||
|
||||
pKernelInfo->kernelArgInfo[0].addressQualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT;
|
||||
pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Constant;
|
||||
|
||||
auto retVal = clSetKernelArgSVMPointer(
|
||||
pMockKernel, // cl_kernel kernel
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -199,7 +199,8 @@ TEST(KernelDecoder, GivenValidEmptyKernelThenDecodingOfHeaderSucceeds) {
|
||||
EXPECT_EQ(0U, decodedKernel.isa.size());
|
||||
EXPECT_TRUE(hasEmptyHeaps(decodedKernel));
|
||||
EXPECT_EQ(0U, decodedKernel.unhandledTokens.size());
|
||||
EXPECT_TRUE(hasEmptyTokensInfo(decodedKernel));
|
||||
EXPECT_FALSE(hasEmptyTokensInfo(decodedKernel));
|
||||
EXPECT_NE(nullptr, decodedKernel.tokens.executionEnvironment);
|
||||
}
|
||||
|
||||
TEST(KernelDecoder, GivenEmptyKernelWhenBlobSmallerThanKernelHeaderThenDecodingFails) {
|
||||
@@ -220,6 +221,8 @@ TEST(KernelDecoder, GivenValidKernelWithHeapsThenDecodingSucceedsAndHeapsAreProp
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
auto kernelExecEnv = *reinterpret_cast<const iOpenCL::SPatchExecutionEnvironment *>(kernelToEncode.blobs.patchList.begin());
|
||||
storage.resize(storage.size() - sizeof(kernelExecEnv));
|
||||
|
||||
size_t isaOffset = storage.size();
|
||||
kernelHeader->KernelHeapSize = 16U;
|
||||
@@ -237,6 +240,9 @@ TEST(KernelDecoder, GivenValidKernelWithHeapsThenDecodingSucceedsAndHeapsAreProp
|
||||
kernelHeader->SurfaceStateHeapSize = 32U;
|
||||
storage.resize(storage.size() + kernelHeader->SurfaceStateHeapSize);
|
||||
|
||||
// patchlist needs to come after heaps
|
||||
storage.insert(storage.end(), reinterpret_cast<uint8_t *>(&kernelExecEnv), reinterpret_cast<uint8_t *>(&kernelExecEnv + 1));
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
EXPECT_TRUE(decodeSuccess);
|
||||
@@ -244,7 +250,8 @@ TEST(KernelDecoder, GivenValidKernelWithHeapsThenDecodingSucceedsAndHeapsAreProp
|
||||
|
||||
EXPECT_EQ(kernelToEncode.header, decodedKernel.header);
|
||||
EXPECT_EQ(0U, decodedKernel.unhandledTokens.size());
|
||||
EXPECT_TRUE(hasEmptyTokensInfo(decodedKernel));
|
||||
EXPECT_FALSE(hasEmptyTokensInfo(decodedKernel));
|
||||
EXPECT_NE(nullptr, decodedKernel.tokens.executionEnvironment);
|
||||
|
||||
EXPECT_EQ(kernelToEncode.name, decodedKernel.name);
|
||||
EXPECT_EQ(ArrayRef<const uint8_t>(storage.data() + isaOffset, kernelHeader->KernelHeapSize), decodedKernel.isa);
|
||||
@@ -308,7 +315,7 @@ TEST(KernelDecoder, GivenKernelWithValidKernelPatchtokensThenDecodingSucceedsAnd
|
||||
storage.reserve(1024);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
auto samplerStateArrayOff = pushBackToken<SPatchSamplerStateArray>(PATCH_TOKEN_SAMPLER_STATE_ARRAY, storage);
|
||||
auto bindingTableStateOff = pushBackToken<SPatchBindingTableState>(PATCH_TOKEN_BINDING_TABLE_STATE, storage);
|
||||
auto allocateLocalSurfaceOff = pushBackToken<SPatchAllocateLocalSurface>(PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE, storage);
|
||||
@@ -335,7 +342,7 @@ TEST(KernelDecoder, GivenKernelWithValidKernelPatchtokensThenDecodingSucceedsAnd
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -379,14 +386,14 @@ TEST(KernelDecoder, GivenKernelWithValidStringPatchtokensThenDecodingSucceedsAnd
|
||||
iOpenCL::SPatchString stringTok = {};
|
||||
stringTok.Token = iOpenCL::PATCH_TOKEN::PATCH_TOKEN_STRING;
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
auto string1Off = PatchTokensTestData::pushBackStringToken("str1", 1, storage);
|
||||
auto string2Off = PatchTokensTestData::pushBackStringToken("str2", 2, storage);
|
||||
auto string0Off = PatchTokensTestData::pushBackStringToken("str0", 0, storage);
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -409,7 +416,7 @@ TEST(KernelDecoder, GivenKernelWithValidArgInfoPatchtokensThenDecodingSucceedsAn
|
||||
iOpenCL::SPatchKernelArgumentInfo argInfoTok = {};
|
||||
argInfoTok.Token = iOpenCL::PATCH_TOKEN::PATCH_TOKEN_KERNEL_ARGUMENT_INFO;
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
|
||||
auto arg1Off = static_cast<uint32_t>(storage.size());
|
||||
argInfoTok.ArgumentNumber = 1;
|
||||
@@ -434,7 +441,7 @@ TEST(KernelDecoder, GivenKernelWithValidArgInfoPatchtokensThenDecodingSucceedsAn
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -454,7 +461,7 @@ TEST(KernelDecoder, GivenKernelWithValidObjectArgPatchtokensThenDecodingSucceeds
|
||||
storage.reserve(512);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
|
||||
iOpenCL::SPatchSamplerKernelArgument samplerTok = {};
|
||||
samplerTok.Token = iOpenCL::PATCH_TOKEN::PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT;
|
||||
@@ -495,7 +502,7 @@ TEST(KernelDecoder, GivenKernelWithValidObjectArgPatchtokensThenDecodingSucceeds
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -544,7 +551,7 @@ TEST(KernelDecoder, GivenKernelWithValidNonArgCrossThreadDataPatchtokensThenDeco
|
||||
storage.reserve(2048);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
auto localWorkSize0Off = pushBackDataParameterToken(DATA_PARAMETER_LOCAL_WORK_SIZE, storage, 0U);
|
||||
auto localWorkSize20Off = pushBackDataParameterToken(DATA_PARAMETER_LOCAL_WORK_SIZE, storage, 0U);
|
||||
auto localWorkSize1Off = pushBackDataParameterToken(DATA_PARAMETER_LOCAL_WORK_SIZE, storage, 1U);
|
||||
@@ -577,7 +584,7 @@ TEST(KernelDecoder, GivenKernelWithValidNonArgCrossThreadDataPatchtokensThenDeco
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -623,7 +630,7 @@ TEST(KernelDecoder, GivenKernelWithArgCrossThreadDataPatchtokensWhenSourceIndexI
|
||||
storage.reserve(128);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
|
||||
auto localWorkSize3Off = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_LOCAL_WORK_SIZE, storage, 3U);
|
||||
auto globalWorkOffset3Off = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_GLOBAL_WORK_OFFSET, storage, 3U);
|
||||
@@ -632,7 +639,7 @@ TEST(KernelDecoder, GivenKernelWithArgCrossThreadDataPatchtokensWhenSourceIndexI
|
||||
auto numWorkGroups3Off = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_NUM_WORK_GROUPS, storage, 3U);
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -653,12 +660,12 @@ TEST(KernelDecoder, GivenKernelWithUnkownPatchtokensThenDecodingSucceedsButToken
|
||||
storage.reserve(128);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
auto unknownTokOff = pushBackToken<iOpenCL::SPatchItemHeader>(iOpenCL::NUM_PATCH_TOKENS, storage);
|
||||
auto unknownCrossThreadTokOff = pushBackDataParameterToken(iOpenCL::NUM_DATA_PARAMETER_TOKENS, storage);
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -676,7 +683,7 @@ TEST(KernelDecoder, GivenKernelWithValidObjectArgMetadataPatchtokensThenDecoding
|
||||
storage.reserve(1024);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
|
||||
auto arg0ObjectIdOff = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_OBJECT_ID, storage, 0U, 0U);
|
||||
auto arg0BufferOffsetOff = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_BUFFER_OFFSET, storage, 0U, 0U);
|
||||
@@ -704,7 +711,7 @@ TEST(KernelDecoder, GivenKernelWithValidObjectArgMetadataPatchtokensThenDecoding
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -754,7 +761,7 @@ TEST(KernelDecoder, GivenKernelWithMismatchedArgMetadataPatchtokensThenDecodingF
|
||||
storage.reserve(128);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
|
||||
auto arg0Metadata0Off = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_BUFFER_STATEFUL, storage, 0U, 0U);
|
||||
auto arg0Metadata1Off = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_BUFFER_OFFSET, storage, 0U, 0U);
|
||||
@@ -764,7 +771,7 @@ TEST(KernelDecoder, GivenKernelWithMismatchedArgMetadataPatchtokensThenDecodingF
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -862,7 +869,7 @@ TEST(KernelDecoder, GivenKernelWithMismatchedArgMetadataPatchtokensThenDecodingF
|
||||
storage.reserve(128);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
|
||||
pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_BUFFER_STATEFUL, storage, 0U, 0U);
|
||||
pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_IMAGE_DEPTH, storage, 0U, 0U);
|
||||
@@ -871,7 +878,7 @@ TEST(KernelDecoder, GivenKernelWithMismatchedArgMetadataPatchtokensThenDecodingF
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -885,7 +892,7 @@ TEST(KernelDecoder, GivenKernelWithByValArgMetadataPatchtokensThenDecodingSuccee
|
||||
storage.reserve(128);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
|
||||
auto arg0Val0Off = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_KERNEL_ARGUMENT, storage, 0U, 0U);
|
||||
auto arg0Val1Off = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_KERNEL_ARGUMENT, storage, 0U, 0U);
|
||||
@@ -893,7 +900,7 @@ TEST(KernelDecoder, GivenKernelWithByValArgMetadataPatchtokensThenDecodingSuccee
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -919,7 +926,7 @@ TEST(KernelDecoder, GivenKernelWithVmeMetadataPatchtokensThenDecodingSucceedsAnd
|
||||
storage.reserve(128);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
|
||||
auto arg0VmeBlockTypeOff = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_VME_MB_BLOCK_TYPE, storage, 0U, 0U);
|
||||
auto arg0VmeSubpixelModeOff = pushBackDataParameterToken(iOpenCL::DATA_PARAMETER_VME_SUBPIXEL_MODE, storage, 0U, 0U);
|
||||
@@ -928,7 +935,7 @@ TEST(KernelDecoder, GivenKernelWithVmeMetadataPatchtokensThenDecodingSucceedsAnd
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(storage, decodedKernel);
|
||||
@@ -953,12 +960,12 @@ TEST(KernelDecoder, GivenKernelWithOutOfBoundsTokenThenDecodingFails) {
|
||||
storage.reserve(128);
|
||||
auto kernelToEncode = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
auto patchListOffset = static_cast<uint32_t>(storage.size());
|
||||
auto patchListOffset = ptrDiff(kernelToEncode.blobs.patchList.begin(), storage.data());
|
||||
pushBackToken<iOpenCL::SPatchSamplerStateArray>(iOpenCL::PATCH_TOKEN_SAMPLER_STATE_ARRAY, storage);
|
||||
|
||||
ASSERT_EQ(storage.data(), kernelToEncode.blobs.kernelInfo.begin());
|
||||
auto kernelHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(storage.data());
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size()) - patchListOffset;
|
||||
kernelHeader->PatchListSize = static_cast<uint32_t>(storage.size() - patchListOffset);
|
||||
kernelHeader->PatchListSize -= 1;
|
||||
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens decodedKernel;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -128,7 +128,7 @@ TEST(ProgramDumper, GivenProgramWithPatchtokensThenProperlyCreatesDump) {
|
||||
std::string generated = NEO::PatchTokenBinary::asString(progWithConst);
|
||||
std::stringstream expected;
|
||||
expected <<
|
||||
R"===(Program of size : 200 decoded successfully
|
||||
R"===(Program of size : )===" << progWithConst.blobs.programInfo.size() << R"===( decoded successfully
|
||||
struct SProgramBinaryHeader {
|
||||
uint32_t Magic; // = 1229870147
|
||||
uint32_t Version; // = )==="
|
||||
@@ -136,27 +136,32 @@ struct SProgramBinaryHeader {
|
||||
|
||||
uint32_t Device; // = )==="
|
||||
<< renderCoreFamily << R"===(
|
||||
uint32_t GPUPointerSizeInBytes; // = 0
|
||||
uint32_t GPUPointerSizeInBytes; // = )==="
|
||||
<< progWithConst.header->GPUPointerSizeInBytes << R"===(
|
||||
|
||||
uint32_t NumberOfKernels; // = 0
|
||||
|
||||
uint32_t SteppingId; // = 0
|
||||
|
||||
uint32_t PatchListSize; // = 172
|
||||
uint32_t PatchListSize; // = )==="
|
||||
<< progWithConst.header->PatchListSize << R"===(
|
||||
};
|
||||
Program-scope tokens section size : 172
|
||||
Program-scope tokens section size : )==="
|
||||
<< progWithConst.blobs.patchList.size() << R"===(
|
||||
WARNING : Unhandled program-scope tokens detected [2] :
|
||||
+ [0]:
|
||||
| struct SPatchItemHeader {
|
||||
| uint32_t Token;// = )==="
|
||||
<< NUM_PATCH_TOKENS << R"===(
|
||||
| uint32_t Size;// = 28
|
||||
| uint32_t Size;// = )==="
|
||||
<< progWithConst.unhandledTokens[0]->Size << R"===(
|
||||
| };
|
||||
+ [1]:
|
||||
| struct SPatchItemHeader {
|
||||
| uint32_t Token;// = )==="
|
||||
<< (NUM_PATCH_TOKENS) << R"===(
|
||||
| uint32_t Size;// = 28
|
||||
| uint32_t Size;// = )==="
|
||||
<< progWithConst.unhandledTokens[1]->Size << R"===(
|
||||
| };
|
||||
Inline Costant Surface(s) [2] :
|
||||
+ [0]:
|
||||
@@ -262,7 +267,7 @@ TEST(ProgramDumper, GivenProgramWithKernelThenProperlyCreatesDump) {
|
||||
std::string generated = NEO::PatchTokenBinary::asString(program);
|
||||
std::stringstream expected;
|
||||
expected <<
|
||||
R"===(Program of size : 96 decoded successfully
|
||||
R"===(Program of size : )===" << program.blobs.programInfo.size() << R"===( decoded successfully
|
||||
struct SProgramBinaryHeader {
|
||||
uint32_t Magic; // = 1229870147
|
||||
uint32_t Version; // = )==="
|
||||
@@ -270,7 +275,8 @@ struct SProgramBinaryHeader {
|
||||
|
||||
uint32_t Device; // = )==="
|
||||
<< renderCoreFamily << R"===(
|
||||
uint32_t GPUPointerSizeInBytes; // = 0
|
||||
uint32_t GPUPointerSizeInBytes; // = )==="
|
||||
<< program.header->GPUPointerSizeInBytes << R"===(
|
||||
|
||||
uint32_t NumberOfKernels; // = 1
|
||||
|
||||
@@ -281,14 +287,46 @@ struct SProgramBinaryHeader {
|
||||
Program-scope tokens section size : 0
|
||||
Kernels section size : 0
|
||||
kernel[0] test_kernel:
|
||||
Kernel of size : 68 decoded successfully
|
||||
Kernel of size : )==="
|
||||
<< program.kernels[0].blobs.kernelInfo.size() << R"===( decoded successfully
|
||||
struct SKernelBinaryHeader {
|
||||
uint32_t CheckSum;// = 2446215414
|
||||
uint32_t CheckSum;// = )==="
|
||||
<< program.kernels[0].header->CheckSum << R"===(
|
||||
uint64_t ShaderHashCode;// = 0
|
||||
uint32_t KernelNameSize;// = 12
|
||||
uint32_t PatchListSize;// = 16
|
||||
uint32_t PatchListSize;// = )==="
|
||||
<< program.kernels[0].header->PatchListSize << R"===(
|
||||
};
|
||||
Kernel-scope tokens section size : 16
|
||||
Kernel-scope tokens section size : )==="
|
||||
<< program.kernels[0].blobs.patchList.size() << R"===(
|
||||
struct SPatchExecutionEnvironment :
|
||||
SPatchItemHeader (Token=23(PATCH_TOKEN_EXECUTION_ENVIRONMENT), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchExecutionEnvironment) << R"===()
|
||||
{
|
||||
uint32_t RequiredWorkGroupSizeX;// = 0
|
||||
uint32_t RequiredWorkGroupSizeY;// = 0
|
||||
uint32_t RequiredWorkGroupSizeZ;// = 0
|
||||
uint32_t LargestCompiledSIMDSize;// = 32
|
||||
uint32_t CompiledSubGroupsNumber;// = 0
|
||||
uint32_t HasBarriers;// = 0
|
||||
uint32_t DisableMidThreadPreemption;// = 0
|
||||
uint32_t CompiledSIMD8;// = 0
|
||||
uint32_t CompiledSIMD16;// = 0
|
||||
uint32_t CompiledSIMD32;// = 1
|
||||
uint32_t HasDeviceEnqueue;// = 0
|
||||
uint32_t MayAccessUndeclaredResource;// = 0
|
||||
uint32_t UsesFencesForReadWriteImages;// = 0
|
||||
uint32_t UsesStatelessSpillFill;// = 0
|
||||
uint32_t UsesMultiScratchSpaces;// = 0
|
||||
uint32_t IsCoherent;// = 0
|
||||
uint32_t IsInitializer;// = 0
|
||||
uint32_t IsFinalizer;// = 0
|
||||
uint32_t SubgroupIndependentForwardProgressRequired;// = 0
|
||||
uint32_t CompiledForGreaterThan4GBBuffers;// = 0
|
||||
uint32_t NumGRFRequired;// = 0
|
||||
uint32_t WorkgroupWalkOrderDims;// = 0
|
||||
uint32_t HasGlobalAtomics;// = 0
|
||||
}
|
||||
struct SPatchAllocateLocalSurface :
|
||||
SPatchItemHeader (Token=15(PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchAllocateLocalSurface) << R"===()
|
||||
@@ -311,7 +349,7 @@ TEST(ProgramDumper, GivenProgramWithMultipleKerneslThenProperlyCreatesDump) {
|
||||
std::string generated = NEO::PatchTokenBinary::asString(program);
|
||||
std::stringstream expected;
|
||||
expected <<
|
||||
R"===(Program of size : 96 decoded successfully
|
||||
R"===(Program of size : )===" << program.blobs.programInfo.size() << R"===( decoded successfully
|
||||
struct SProgramBinaryHeader {
|
||||
uint32_t Magic; // = 1229870147
|
||||
uint32_t Version; // = )==="
|
||||
@@ -319,7 +357,8 @@ struct SProgramBinaryHeader {
|
||||
|
||||
uint32_t Device; // = )==="
|
||||
<< renderCoreFamily << R"===(
|
||||
uint32_t GPUPointerSizeInBytes; // = 0
|
||||
uint32_t GPUPointerSizeInBytes; // = )==="
|
||||
<< program.header->GPUPointerSizeInBytes << R"===(
|
||||
|
||||
uint32_t NumberOfKernels; // = 1
|
||||
|
||||
@@ -330,14 +369,46 @@ struct SProgramBinaryHeader {
|
||||
Program-scope tokens section size : 0
|
||||
Kernels section size : 0
|
||||
kernel[0] test_kernel:
|
||||
Kernel of size : 68 decoded successfully
|
||||
Kernel of size : )==="
|
||||
<< program.kernels[0].blobs.kernelInfo.size() << R"===( decoded successfully
|
||||
struct SKernelBinaryHeader {
|
||||
uint32_t CheckSum;// = 2446215414
|
||||
uint32_t CheckSum;// = )==="
|
||||
<< program.kernels[0].header->CheckSum << R"===(
|
||||
uint64_t ShaderHashCode;// = 0
|
||||
uint32_t KernelNameSize;// = 12
|
||||
uint32_t PatchListSize;// = 16
|
||||
uint32_t PatchListSize;// = )==="
|
||||
<< program.kernels[0].header->PatchListSize << R"===(
|
||||
};
|
||||
Kernel-scope tokens section size : 16
|
||||
Kernel-scope tokens section size : )==="
|
||||
<< program.kernels[0].blobs.patchList.size() << R"===(
|
||||
struct SPatchExecutionEnvironment :
|
||||
SPatchItemHeader (Token=23(PATCH_TOKEN_EXECUTION_ENVIRONMENT), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchExecutionEnvironment) << R"===()
|
||||
{
|
||||
uint32_t RequiredWorkGroupSizeX;// = 0
|
||||
uint32_t RequiredWorkGroupSizeY;// = 0
|
||||
uint32_t RequiredWorkGroupSizeZ;// = 0
|
||||
uint32_t LargestCompiledSIMDSize;// = 32
|
||||
uint32_t CompiledSubGroupsNumber;// = 0
|
||||
uint32_t HasBarriers;// = 0
|
||||
uint32_t DisableMidThreadPreemption;// = 0
|
||||
uint32_t CompiledSIMD8;// = 0
|
||||
uint32_t CompiledSIMD16;// = 0
|
||||
uint32_t CompiledSIMD32;// = 1
|
||||
uint32_t HasDeviceEnqueue;// = 0
|
||||
uint32_t MayAccessUndeclaredResource;// = 0
|
||||
uint32_t UsesFencesForReadWriteImages;// = 0
|
||||
uint32_t UsesStatelessSpillFill;// = 0
|
||||
uint32_t UsesMultiScratchSpaces;// = 0
|
||||
uint32_t IsCoherent;// = 0
|
||||
uint32_t IsInitializer;// = 0
|
||||
uint32_t IsFinalizer;// = 0
|
||||
uint32_t SubgroupIndependentForwardProgressRequired;// = 0
|
||||
uint32_t CompiledForGreaterThan4GBBuffers;// = 0
|
||||
uint32_t NumGRFRequired;// = 0
|
||||
uint32_t WorkgroupWalkOrderDims;// = 0
|
||||
uint32_t HasGlobalAtomics;// = 0
|
||||
}
|
||||
struct SPatchAllocateLocalSurface :
|
||||
SPatchItemHeader (Token=15(PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchAllocateLocalSurface) << R"===()
|
||||
@@ -346,23 +417,87 @@ Kernel-scope tokens section size : 16
|
||||
uint32_t TotalInlineLocalMemorySize;// = 16
|
||||
}
|
||||
kernel[1] different_kernel:
|
||||
Kernel of size : 68 decoded successfully
|
||||
Kernel of size : )==="
|
||||
<< program.kernels[1].blobs.kernelInfo.size() << R"===( decoded successfully
|
||||
struct SKernelBinaryHeader {
|
||||
uint32_t CheckSum;// = 2446215414
|
||||
uint32_t CheckSum;// = )==="
|
||||
<< program.kernels[1].header->CheckSum << R"===(
|
||||
uint64_t ShaderHashCode;// = 0
|
||||
uint32_t KernelNameSize;// = 12
|
||||
uint32_t PatchListSize;// = 16
|
||||
uint32_t PatchListSize;// = )==="
|
||||
<< program.kernels[1].header->PatchListSize << R"===(
|
||||
};
|
||||
Kernel-scope tokens section size : 0
|
||||
Kernel-scope tokens section size : )==="
|
||||
<< program.kernels[1].blobs.patchList.size() << R"===(
|
||||
struct SPatchExecutionEnvironment :
|
||||
SPatchItemHeader (Token=23(PATCH_TOKEN_EXECUTION_ENVIRONMENT), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchExecutionEnvironment) << R"===()
|
||||
{
|
||||
uint32_t RequiredWorkGroupSizeX;// = 0
|
||||
uint32_t RequiredWorkGroupSizeY;// = 0
|
||||
uint32_t RequiredWorkGroupSizeZ;// = 0
|
||||
uint32_t LargestCompiledSIMDSize;// = 32
|
||||
uint32_t CompiledSubGroupsNumber;// = 0
|
||||
uint32_t HasBarriers;// = 0
|
||||
uint32_t DisableMidThreadPreemption;// = 0
|
||||
uint32_t CompiledSIMD8;// = 0
|
||||
uint32_t CompiledSIMD16;// = 0
|
||||
uint32_t CompiledSIMD32;// = 1
|
||||
uint32_t HasDeviceEnqueue;// = 0
|
||||
uint32_t MayAccessUndeclaredResource;// = 0
|
||||
uint32_t UsesFencesForReadWriteImages;// = 0
|
||||
uint32_t UsesStatelessSpillFill;// = 0
|
||||
uint32_t UsesMultiScratchSpaces;// = 0
|
||||
uint32_t IsCoherent;// = 0
|
||||
uint32_t IsInitializer;// = 0
|
||||
uint32_t IsFinalizer;// = 0
|
||||
uint32_t SubgroupIndependentForwardProgressRequired;// = 0
|
||||
uint32_t CompiledForGreaterThan4GBBuffers;// = 0
|
||||
uint32_t NumGRFRequired;// = 0
|
||||
uint32_t WorkgroupWalkOrderDims;// = 0
|
||||
uint32_t HasGlobalAtomics;// = 0
|
||||
}
|
||||
kernel[2] <UNNAMED>:
|
||||
Kernel of size : 68 decoded successfully
|
||||
Kernel of size : )==="
|
||||
<< program.kernels[2].blobs.kernelInfo.size() << R"===( decoded successfully
|
||||
struct SKernelBinaryHeader {
|
||||
uint32_t CheckSum;// = 2446215414
|
||||
uint32_t CheckSum;// = )==="
|
||||
<< program.kernels[2].header->CheckSum << R"===(
|
||||
uint64_t ShaderHashCode;// = 0
|
||||
uint32_t KernelNameSize;// = 12
|
||||
uint32_t PatchListSize;// = 16
|
||||
uint32_t PatchListSize;// = )==="
|
||||
<< program.kernels[2].header->PatchListSize << R"===(
|
||||
};
|
||||
Kernel-scope tokens section size : 0
|
||||
Kernel-scope tokens section size : )==="
|
||||
<< program.kernels[2].blobs.patchList.size() << R"===(
|
||||
struct SPatchExecutionEnvironment :
|
||||
SPatchItemHeader (Token=23(PATCH_TOKEN_EXECUTION_ENVIRONMENT), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchExecutionEnvironment) << R"===()
|
||||
{
|
||||
uint32_t RequiredWorkGroupSizeX;// = 0
|
||||
uint32_t RequiredWorkGroupSizeY;// = 0
|
||||
uint32_t RequiredWorkGroupSizeZ;// = 0
|
||||
uint32_t LargestCompiledSIMDSize;// = 32
|
||||
uint32_t CompiledSubGroupsNumber;// = 0
|
||||
uint32_t HasBarriers;// = 0
|
||||
uint32_t DisableMidThreadPreemption;// = 0
|
||||
uint32_t CompiledSIMD8;// = 0
|
||||
uint32_t CompiledSIMD16;// = 0
|
||||
uint32_t CompiledSIMD32;// = 1
|
||||
uint32_t HasDeviceEnqueue;// = 0
|
||||
uint32_t MayAccessUndeclaredResource;// = 0
|
||||
uint32_t UsesFencesForReadWriteImages;// = 0
|
||||
uint32_t UsesStatelessSpillFill;// = 0
|
||||
uint32_t UsesMultiScratchSpaces;// = 0
|
||||
uint32_t IsCoherent;// = 0
|
||||
uint32_t IsInitializer;// = 0
|
||||
uint32_t IsFinalizer;// = 0
|
||||
uint32_t SubgroupIndependentForwardProgressRequired;// = 0
|
||||
uint32_t CompiledForGreaterThan4GBBuffers;// = 0
|
||||
uint32_t NumGRFRequired;// = 0
|
||||
uint32_t WorkgroupWalkOrderDims;// = 0
|
||||
uint32_t HasGlobalAtomics;// = 0
|
||||
}
|
||||
)===";
|
||||
EXPECT_STREQ(expected.str().c_str(), generated.c_str());
|
||||
}
|
||||
@@ -428,14 +563,17 @@ TEST(KernelDumper, GivenKernelWithNonCrossthreadDataPatchtokensThenProperlyCreat
|
||||
std::string generated = NEO::PatchTokenBinary::asString(kernel);
|
||||
std::stringstream expected;
|
||||
expected <<
|
||||
R"===(Kernel of size : 52 decoded successfully
|
||||
R"===(Kernel of size : )===" << kernel.blobs.kernelInfo.size() << R"===( decoded successfully
|
||||
struct SKernelBinaryHeader {
|
||||
uint32_t CheckSum;// = 3223116527
|
||||
uint32_t CheckSum;// = )==="
|
||||
<< kernel.header->CheckSum << R"===(
|
||||
uint64_t ShaderHashCode;// = 0
|
||||
uint32_t KernelNameSize;// = 12
|
||||
uint32_t PatchListSize;// = 0
|
||||
uint32_t PatchListSize;// = )==="
|
||||
<< kernel.header->PatchListSize << R"===(
|
||||
};
|
||||
Kernel-scope tokens section size : 0
|
||||
Kernel-scope tokens section size : )==="
|
||||
<< kernel.blobs.patchList.size() << R"===(
|
||||
WARNING : Unhandled kernel-scope tokens detected [2] :
|
||||
+ [0]:
|
||||
| struct SPatchItemHeader {
|
||||
@@ -613,7 +751,8 @@ Kernel-scope tokens section size : 0
|
||||
}
|
||||
struct SPatchItemHeader {
|
||||
uint32_t Token;// = 50(PATCH_TOKEN_INLINE_VME_SAMPLER_INFO)
|
||||
uint32_t Size;// = 8
|
||||
uint32_t Size;// = )==="
|
||||
<< sizeof(SPatchItemHeader) << R"===(
|
||||
};
|
||||
struct SPatchGtpinFreeGRFInfo :
|
||||
SPatchItemHeader (Token=51(PATCH_TOKEN_GTPIN_FREE_GRF_INFO), Size=)==="
|
||||
@@ -637,7 +776,8 @@ Kernel-scope tokens section size : 0
|
||||
}
|
||||
struct SPatchItemHeader {
|
||||
uint32_t Token;// = 52(PATCH_TOKEN_GTPIN_INFO)
|
||||
uint32_t Size;// = 8
|
||||
uint32_t Size;// = )==="
|
||||
<< sizeof(SPatchItemHeader) << R"===(
|
||||
};
|
||||
struct SPatchFunctionTableInfo :
|
||||
SPatchItemHeader (Token=53(PATCH_TOKEN_PROGRAM_SYMBOL_TABLE), Size=)==="
|
||||
@@ -679,14 +819,45 @@ TEST(KernelDumper, GivenKernelWithStringPatchTokensThenProperlyCreatesDump) {
|
||||
kernel.tokens.strings.push_back(reinterpret_cast<iOpenCL::SPatchString *>(strTokStream.data() + string2Off));
|
||||
std::string generated = NEO::PatchTokenBinary::asString(kernel);
|
||||
std::stringstream expected;
|
||||
expected << R"===(Kernel of size : 52 decoded successfully
|
||||
expected << R"===(Kernel of size : )===" << kernel.blobs.kernelInfo.size() << R"===( decoded successfully
|
||||
struct SKernelBinaryHeader {
|
||||
uint32_t CheckSum;// = 3223116527
|
||||
uint32_t CheckSum;// = )==="
|
||||
<< kernel.header->CheckSum << R"===(
|
||||
uint64_t ShaderHashCode;// = 0
|
||||
uint32_t KernelNameSize;// = 12
|
||||
uint32_t PatchListSize;// = 0
|
||||
uint32_t PatchListSize;// = )==="
|
||||
<< kernel.header->PatchListSize << R"===(
|
||||
};
|
||||
Kernel-scope tokens section size : 0
|
||||
Kernel-scope tokens section size : )==="
|
||||
<< kernel.blobs.patchList.size() << R"===(
|
||||
struct SPatchExecutionEnvironment :
|
||||
SPatchItemHeader (Token=23(PATCH_TOKEN_EXECUTION_ENVIRONMENT), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchExecutionEnvironment) << R"===()
|
||||
{
|
||||
uint32_t RequiredWorkGroupSizeX;// = 0
|
||||
uint32_t RequiredWorkGroupSizeY;// = 0
|
||||
uint32_t RequiredWorkGroupSizeZ;// = 0
|
||||
uint32_t LargestCompiledSIMDSize;// = 32
|
||||
uint32_t CompiledSubGroupsNumber;// = 0
|
||||
uint32_t HasBarriers;// = 0
|
||||
uint32_t DisableMidThreadPreemption;// = 0
|
||||
uint32_t CompiledSIMD8;// = 0
|
||||
uint32_t CompiledSIMD16;// = 0
|
||||
uint32_t CompiledSIMD32;// = 1
|
||||
uint32_t HasDeviceEnqueue;// = 0
|
||||
uint32_t MayAccessUndeclaredResource;// = 0
|
||||
uint32_t UsesFencesForReadWriteImages;// = 0
|
||||
uint32_t UsesStatelessSpillFill;// = 0
|
||||
uint32_t UsesMultiScratchSpaces;// = 0
|
||||
uint32_t IsCoherent;// = 0
|
||||
uint32_t IsInitializer;// = 0
|
||||
uint32_t IsFinalizer;// = 0
|
||||
uint32_t SubgroupIndependentForwardProgressRequired;// = 0
|
||||
uint32_t CompiledForGreaterThan4GBBuffers;// = 0
|
||||
uint32_t NumGRFRequired;// = 0
|
||||
uint32_t WorkgroupWalkOrderDims;// = 0
|
||||
uint32_t HasGlobalAtomics;// = 0
|
||||
}
|
||||
String literals [3] :
|
||||
+ [0]:
|
||||
| struct SPatchString :
|
||||
@@ -787,14 +958,17 @@ TEST(KernelDumper, GivenKernelWithNonArgCrossThreadDataPatchtokensThenProperlyCr
|
||||
std::string generated = NEO::PatchTokenBinary::asString(kernel);
|
||||
static constexpr auto tokenSize = sizeof(SPatchDataParameterBuffer);
|
||||
std::stringstream expected;
|
||||
expected << R"===(Kernel of size : 52 decoded successfully
|
||||
expected << R"===(Kernel of size : )===" << kernel.blobs.kernelInfo.size() << R"===( decoded successfully
|
||||
struct SKernelBinaryHeader {
|
||||
uint32_t CheckSum;// = 3223116527
|
||||
uint32_t CheckSum;// = )==="
|
||||
<< kernel.header->CheckSum << R"===(
|
||||
uint64_t ShaderHashCode;// = 0
|
||||
uint32_t KernelNameSize;// = 12
|
||||
uint32_t PatchListSize;// = 0
|
||||
uint32_t PatchListSize;// = )==="
|
||||
<< kernel.header->PatchListSize << R"===(
|
||||
};
|
||||
Kernel-scope tokens section size : 0
|
||||
Kernel-scope tokens section size : )==="
|
||||
<< kernel.blobs.patchList.size() << R"===(
|
||||
WARNING : Unhandled kernel-scope tokens detected [2] :
|
||||
+ [0]:
|
||||
| struct SPatchDataParameterBuffer :
|
||||
@@ -826,6 +1000,34 @@ Kernel-scope tokens section size : 0
|
||||
| uint32_t LocationIndex2;// = 0
|
||||
| uint32_t IsEmulationArgument;// = 0
|
||||
| }
|
||||
struct SPatchExecutionEnvironment :
|
||||
SPatchItemHeader (Token=23(PATCH_TOKEN_EXECUTION_ENVIRONMENT), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchExecutionEnvironment) << R"===()
|
||||
{
|
||||
uint32_t RequiredWorkGroupSizeX;// = 0
|
||||
uint32_t RequiredWorkGroupSizeY;// = 0
|
||||
uint32_t RequiredWorkGroupSizeZ;// = 0
|
||||
uint32_t LargestCompiledSIMDSize;// = 32
|
||||
uint32_t CompiledSubGroupsNumber;// = 0
|
||||
uint32_t HasBarriers;// = 0
|
||||
uint32_t DisableMidThreadPreemption;// = 0
|
||||
uint32_t CompiledSIMD8;// = 0
|
||||
uint32_t CompiledSIMD16;// = 0
|
||||
uint32_t CompiledSIMD32;// = 1
|
||||
uint32_t HasDeviceEnqueue;// = 0
|
||||
uint32_t MayAccessUndeclaredResource;// = 0
|
||||
uint32_t UsesFencesForReadWriteImages;// = 0
|
||||
uint32_t UsesStatelessSpillFill;// = 0
|
||||
uint32_t UsesMultiScratchSpaces;// = 0
|
||||
uint32_t IsCoherent;// = 0
|
||||
uint32_t IsInitializer;// = 0
|
||||
uint32_t IsFinalizer;// = 0
|
||||
uint32_t SubgroupIndependentForwardProgressRequired;// = 0
|
||||
uint32_t CompiledForGreaterThan4GBBuffers;// = 0
|
||||
uint32_t NumGRFRequired;// = 0
|
||||
uint32_t WorkgroupWalkOrderDims;// = 0
|
||||
uint32_t HasGlobalAtomics;// = 0
|
||||
}
|
||||
localWorkSize [3] :
|
||||
+ [0]:
|
||||
| struct SPatchDataParameterBuffer :
|
||||
@@ -1188,14 +1390,45 @@ TEST(KernelDumper, GivenKernelWithArgThenProperlyCreatesDump) {
|
||||
kernel.tokens.kernelArgs.push_back(kernel.tokens.kernelArgs[0]);
|
||||
auto generated = NEO::PatchTokenBinary::asString(kernel);
|
||||
std::stringstream expected;
|
||||
expected << R"===(Kernel of size : 52 decoded successfully
|
||||
expected << R"===(Kernel of size : )===" << kernel.blobs.kernelInfo.size() << R"===( decoded successfully
|
||||
struct SKernelBinaryHeader {
|
||||
uint32_t CheckSum;// = 3223116527
|
||||
uint32_t CheckSum;// = )==="
|
||||
<< kernel.header->CheckSum << R"===(
|
||||
uint64_t ShaderHashCode;// = 0
|
||||
uint32_t KernelNameSize;// = 12
|
||||
uint32_t PatchListSize;// = 0
|
||||
uint32_t PatchListSize;// = )==="
|
||||
<< kernel.header->PatchListSize << R"===(
|
||||
};
|
||||
Kernel-scope tokens section size : 0
|
||||
Kernel-scope tokens section size : )==="
|
||||
<< kernel.blobs.patchList.size() << R"===(
|
||||
struct SPatchExecutionEnvironment :
|
||||
SPatchItemHeader (Token=23(PATCH_TOKEN_EXECUTION_ENVIRONMENT), Size=)==="
|
||||
<< sizeof(iOpenCL::SPatchExecutionEnvironment) << R"===()
|
||||
{
|
||||
uint32_t RequiredWorkGroupSizeX;// = 0
|
||||
uint32_t RequiredWorkGroupSizeY;// = 0
|
||||
uint32_t RequiredWorkGroupSizeZ;// = 0
|
||||
uint32_t LargestCompiledSIMDSize;// = 32
|
||||
uint32_t CompiledSubGroupsNumber;// = 0
|
||||
uint32_t HasBarriers;// = 0
|
||||
uint32_t DisableMidThreadPreemption;// = 0
|
||||
uint32_t CompiledSIMD8;// = 0
|
||||
uint32_t CompiledSIMD16;// = 0
|
||||
uint32_t CompiledSIMD32;// = 1
|
||||
uint32_t HasDeviceEnqueue;// = 0
|
||||
uint32_t MayAccessUndeclaredResource;// = 0
|
||||
uint32_t UsesFencesForReadWriteImages;// = 0
|
||||
uint32_t UsesStatelessSpillFill;// = 0
|
||||
uint32_t UsesMultiScratchSpaces;// = 0
|
||||
uint32_t IsCoherent;// = 0
|
||||
uint32_t IsInitializer;// = 0
|
||||
uint32_t IsFinalizer;// = 0
|
||||
uint32_t SubgroupIndependentForwardProgressRequired;// = 0
|
||||
uint32_t CompiledForGreaterThan4GBBuffers;// = 0
|
||||
uint32_t NumGRFRequired;// = 0
|
||||
uint32_t WorkgroupWalkOrderDims;// = 0
|
||||
uint32_t HasGlobalAtomics;// = 0
|
||||
}
|
||||
Kernel arguments [2] :
|
||||
+ kernelArg[0]:
|
||||
| Kernel argument of type unspecified
|
||||
@@ -1831,13 +2064,14 @@ TEST(PatchTokenDumper, GivenAnyTokenThenDumpingIsHandled) {
|
||||
iOpenCL::SPatchItemHeader *kernelToken = nullptr;
|
||||
auto kernelToDecode = PatchTokensTestData::ValidEmptyKernel::create(kernelToDecodeStorage);
|
||||
{
|
||||
auto kernelPatchListOffset = kernelToDecodeStorage.size();
|
||||
auto kernelPatchListOffset = ptrDiff(kernelToDecode.blobs.patchList.begin(), kernelToDecodeStorage.data());
|
||||
kernelToDecodeStorage.resize(kernelToDecodeStorage.size() + maxTokenSize, 0U);
|
||||
kernelToDecode.blobs.kernelInfo = ArrayRef<const uint8_t>(kernelToDecodeStorage.data(), kernelToDecodeStorage.data() + kernelToDecodeStorage.size());
|
||||
kernelToDecode.blobs.patchList = ArrayRef<const uint8_t>(kernelToDecodeStorage.data() + kernelPatchListOffset, kernelToDecodeStorage.data() + kernelToDecodeStorage.size());
|
||||
auto kernelHeaderMutable = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(&*(kernelToDecodeStorage.begin()));
|
||||
kernelHeaderMutable->PatchListSize = static_cast<uint32_t>(kernelToDecode.blobs.patchList.size());
|
||||
kernelToken = reinterpret_cast<iOpenCL::SPatchItemHeader *>(kernelToDecodeStorage.data() + kernelPatchListOffset);
|
||||
kernelToDecode.tokens.executionEnvironment = reinterpret_cast<iOpenCL::SPatchExecutionEnvironment *>(kernelToDecodeStorage.data() + kernelPatchListOffset);
|
||||
kernelToken = reinterpret_cast<iOpenCL::SPatchItemHeader *>(kernelToDecodeStorage.data() + kernelPatchListOffset + sizeof(iOpenCL::SPatchExecutionEnvironment));
|
||||
}
|
||||
kernelToken->Size = maxTokenSize;
|
||||
|
||||
|
||||
@@ -8,17 +8,81 @@
|
||||
#pragma once
|
||||
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
#include "test.h"
|
||||
|
||||
#include "igfxfmid.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
extern GFXCORE_FAMILY renderCoreFamily;
|
||||
|
||||
namespace PatchTokensTestData {
|
||||
template <typename TokenT>
|
||||
inline TokenT initToken(iOpenCL::PATCH_TOKEN tok) {
|
||||
TokenT ret = {};
|
||||
ret.Size = sizeof(TokenT);
|
||||
ret.Token = tok;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline iOpenCL::SPatchDataParameterBuffer initDataParameterBufferToken(iOpenCL::DATA_PARAMETER_TOKEN type, uint32_t sourceIndex = 0, uint32_t argNum = 0) {
|
||||
iOpenCL::SPatchDataParameterBuffer tok = {};
|
||||
tok.Size = static_cast<uint32_t>(sizeof(iOpenCL::SPatchDataParameterBuffer));
|
||||
tok.Token = iOpenCL::PATCH_TOKEN_DATA_PARAMETER_BUFFER;
|
||||
tok.Type = type;
|
||||
tok.SourceOffset = sourceIndex * sizeof(uint32_t);
|
||||
tok.ArgumentNumber = argNum;
|
||||
return tok;
|
||||
}
|
||||
|
||||
inline uint32_t pushBackString(const std::string &str, std::vector<uint8_t> &storage) {
|
||||
auto offset = storage.size();
|
||||
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(str.c_str()), reinterpret_cast<const uint8_t *>(str.c_str()) + str.size());
|
||||
return static_cast<uint32_t>(offset);
|
||||
}
|
||||
|
||||
inline uint32_t pushBackStringToken(const std::string &str, uint32_t stringIndex, std::vector<uint8_t> &outStream) {
|
||||
auto off = outStream.size();
|
||||
outStream.reserve(outStream.size() + sizeof(iOpenCL::SPatchString) + str.length());
|
||||
outStream.resize(outStream.size() + sizeof(iOpenCL::SPatchString));
|
||||
iOpenCL::SPatchString *tok = reinterpret_cast<iOpenCL::SPatchString *>(outStream.data() + off);
|
||||
*tok = initToken<iOpenCL::SPatchString>(iOpenCL::PATCH_TOKEN::PATCH_TOKEN_STRING);
|
||||
tok->StringSize = static_cast<uint32_t>(str.length());
|
||||
tok->Size += tok->StringSize;
|
||||
tok->Index = stringIndex;
|
||||
pushBackString(str, outStream);
|
||||
return static_cast<uint32_t>(off);
|
||||
};
|
||||
|
||||
inline uint32_t pushBackArgInfoToken(std::vector<uint8_t> &outStream,
|
||||
uint32_t argNum = 0,
|
||||
const std::string &addressQualifier = "__global", const std::string &accessQualifier = "read_write",
|
||||
const std::string &argName = "custom_arg", const std::string &typeName = "int*;", std::string typeQualifier = "const") {
|
||||
auto off = outStream.size();
|
||||
iOpenCL::SPatchKernelArgumentInfo tok = {};
|
||||
tok.Token = iOpenCL::PATCH_TOKEN_KERNEL_ARGUMENT_INFO;
|
||||
tok.AddressQualifierSize = static_cast<uint32_t>(addressQualifier.size());
|
||||
tok.AccessQualifierSize = static_cast<uint32_t>(accessQualifier.size());
|
||||
tok.ArgumentNameSize = static_cast<uint32_t>(argName.size());
|
||||
tok.TypeNameSize = static_cast<uint32_t>(typeName.size());
|
||||
tok.TypeQualifierSize = static_cast<uint32_t>(typeQualifier.size());
|
||||
tok.Size = sizeof(iOpenCL::SPatchKernelArgumentInfo) + tok.AddressQualifierSize + tok.AccessQualifierSize + tok.ArgumentNameSize + tok.TypeNameSize + tok.TypeQualifierSize;
|
||||
|
||||
outStream.insert(outStream.end(), reinterpret_cast<const uint8_t *>(&tok), reinterpret_cast<const uint8_t *>(&tok) + sizeof(tok));
|
||||
pushBackString(addressQualifier, outStream);
|
||||
pushBackString(accessQualifier, outStream);
|
||||
pushBackString(argName, outStream);
|
||||
pushBackString(typeName, outStream);
|
||||
pushBackString(typeQualifier, outStream);
|
||||
return static_cast<uint32_t>(off);
|
||||
}
|
||||
|
||||
struct ValidEmptyProgram : NEO::PatchTokenBinary::ProgramFromPatchtokens {
|
||||
ValidEmptyProgram() {
|
||||
iOpenCL::SProgramBinaryHeader headerTok = {};
|
||||
headerTok.Magic = iOpenCL::MAGIC_CL;
|
||||
headerTok.Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
headerTok.Device = renderCoreFamily;
|
||||
headerTok.GPUPointerSizeInBytes = sizeof(uintptr_t);
|
||||
this->decodeStatus = NEO::PatchTokenBinary::DecoderError::Success;
|
||||
|
||||
storage.insert(storage.end(), reinterpret_cast<uint8_t *>(&headerTok), reinterpret_cast<uint8_t *>((&headerTok) + 1));
|
||||
@@ -160,6 +224,10 @@ struct ValidEmptyKernel {
|
||||
static NEO::PatchTokenBinary::KernelFromPatchtokens create(std::vector<uint8_t> &storage) {
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens ret;
|
||||
iOpenCL::SKernelBinaryHeaderCommon headerTokInl = {};
|
||||
auto execEnvTokInl = initToken<iOpenCL::SPatchExecutionEnvironment>(iOpenCL::PATCH_TOKEN_EXECUTION_ENVIRONMENT);
|
||||
execEnvTokInl.LargestCompiledSIMDSize = 32U;
|
||||
execEnvTokInl.CompiledSIMD32 = 1U;
|
||||
headerTokInl.PatchListSize = sizeof(execEnvTokInl);
|
||||
ret.decodeStatus = NEO::PatchTokenBinary::DecoderError::Success;
|
||||
ret.name = "test_kernel";
|
||||
headerTokInl.KernelNameSize = static_cast<uint32_t>(ret.name.size());
|
||||
@@ -170,8 +238,12 @@ struct ValidEmptyKernel {
|
||||
auto headerTok = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(&*(storage.begin() + kernOffset));
|
||||
ret.NEO::PatchTokenBinary::KernelFromPatchtokens::header = headerTok;
|
||||
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(ret.name.begin()), reinterpret_cast<const uint8_t *>(ret.name.end()));
|
||||
ret.blobs.kernelInfo = ArrayRef<const uint8_t>(storage.data() + kernOffset, storage.data() + storage.size());
|
||||
auto execEnvOffset = storage.size();
|
||||
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&execEnvTokInl), reinterpret_cast<const uint8_t *>((&execEnvTokInl) + 1));
|
||||
ret.blobs.kernelInfo = ArrayRef<const uint8_t>(storage.data() + kernOffset, storage.data() + kernOffset + storage.size());
|
||||
headerTok->CheckSum = NEO::PatchTokenBinary::calcKernelChecksum(ret.blobs.kernelInfo);
|
||||
ret.blobs.patchList = ArrayRef<const uint8_t>(storage.data() + execEnvOffset, storage.data() + storage.size());
|
||||
ret.tokens.executionEnvironment = reinterpret_cast<iOpenCL::SPatchExecutionEnvironment *>(storage.data() + execEnvOffset);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
@@ -182,6 +254,7 @@ struct ValidProgramWithKernel : ValidEmptyProgram {
|
||||
kernOffset = storage.size();
|
||||
this->kernels.push_back(ValidEmptyKernel::create(storage));
|
||||
this->kernels[0].decodeStatus = NEO::PatchTokenBinary::DecoderError::Success;
|
||||
kernExecEnvOffset = ptrDiff(this->kernels[0].blobs.patchList.begin(), storage.data());
|
||||
recalcTokPtr();
|
||||
}
|
||||
|
||||
@@ -190,16 +263,25 @@ struct ValidProgramWithKernel : ValidEmptyProgram {
|
||||
this->kernels[0].blobs.kernelInfo = ArrayRef<const uint8_t>(storage.data() + kernOffset, storage.data() + storage.size());
|
||||
kernelHeaderMutable = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(&*(storage.begin() + kernOffset));
|
||||
this->kernels[0].header = kernelHeaderMutable;
|
||||
char *name = reinterpret_cast<char *>(storage.data() + kernOffset + sizeof(iOpenCL::SKernelBinaryHeaderCommon));
|
||||
this->kernels[0].name = ArrayRef<const char>(name, name + kernelHeaderMutable->KernelNameSize);
|
||||
kernelExecEnvMutable = reinterpret_cast<iOpenCL::SPatchExecutionEnvironment *>(&*(storage.begin() + kernExecEnvOffset));
|
||||
this->kernels[0].tokens.executionEnvironment = kernelExecEnvMutable;
|
||||
|
||||
this->kernels[0].blobs.patchList = ArrayRef<const uint8_t>(storage.data() + kernExecEnvOffset, storage.data() + storage.size());
|
||||
this->kernelHeaderMutable->PatchListSize = static_cast<uint32_t>(this->kernels[0].blobs.patchList.size());
|
||||
kernelHeaderMutable->CheckSum = NEO::PatchTokenBinary::calcKernelChecksum(this->kernels[0].blobs.kernelInfo);
|
||||
}
|
||||
|
||||
size_t kernOffset = 0U;
|
||||
size_t kernExecEnvOffset = 0U;
|
||||
iOpenCL::SKernelBinaryHeaderCommon *kernelHeaderMutable = nullptr;
|
||||
iOpenCL::SPatchExecutionEnvironment *kernelExecEnvMutable = nullptr;
|
||||
};
|
||||
|
||||
struct ValidProgramWithKernelUsingSlm : ValidProgramWithKernel {
|
||||
ValidProgramWithKernelUsingSlm() {
|
||||
patchlistOffset = storage.size();
|
||||
slmMutableOffset = storage.size();
|
||||
iOpenCL::SPatchAllocateLocalSurface slmTok = {};
|
||||
slmTok.Token = iOpenCL::PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE;
|
||||
slmTok.Size = sizeof(slmTok);
|
||||
@@ -210,73 +292,42 @@ struct ValidProgramWithKernelUsingSlm : ValidProgramWithKernel {
|
||||
|
||||
void recalcTokPtr() {
|
||||
ValidProgramWithKernel::recalcTokPtr();
|
||||
this->kernels[0].blobs.patchList = ArrayRef<const uint8_t>(storage.data() + patchlistOffset, storage.data() + storage.size());
|
||||
slmMutable = reinterpret_cast<iOpenCL::SPatchAllocateLocalSurface *>(storage.data() + patchlistOffset);
|
||||
slmMutable = reinterpret_cast<iOpenCL::SPatchAllocateLocalSurface *>(storage.data() + slmMutableOffset);
|
||||
this->kernels[0].tokens.allocateLocalSurface = slmMutable;
|
||||
this->kernelHeaderMutable->PatchListSize = static_cast<uint32_t>(this->kernels[0].blobs.patchList.size());
|
||||
}
|
||||
|
||||
iOpenCL::SPatchAllocateLocalSurface *slmMutable = nullptr;
|
||||
size_t patchlistOffset = 0U;
|
||||
size_t slmMutableOffset = 0U;
|
||||
};
|
||||
|
||||
template <typename TokenT>
|
||||
inline TokenT initToken(iOpenCL::PATCH_TOKEN tok) {
|
||||
TokenT ret = {};
|
||||
ret.Size = sizeof(TokenT);
|
||||
ret.Token = tok;
|
||||
return ret;
|
||||
}
|
||||
struct ValidProgramWithKernelAndArg : ValidProgramWithKernel {
|
||||
ValidProgramWithKernelAndArg() {
|
||||
kernelArgOffset = storage.size();
|
||||
|
||||
inline iOpenCL::SPatchDataParameterBuffer initDataParameterBufferToken(iOpenCL::DATA_PARAMETER_TOKEN type, uint32_t sourceIndex = 0, uint32_t argNum = 0) {
|
||||
iOpenCL::SPatchDataParameterBuffer tok = {};
|
||||
tok.Size = static_cast<uint32_t>(sizeof(iOpenCL::SPatchDataParameterBuffer));
|
||||
tok.Token = iOpenCL::PATCH_TOKEN_DATA_PARAMETER_BUFFER;
|
||||
tok.Type = type;
|
||||
tok.SourceOffset = sourceIndex * sizeof(uint32_t);
|
||||
tok.ArgumentNumber = argNum;
|
||||
return tok;
|
||||
}
|
||||
pushBackArgInfoToken(storage);
|
||||
this->kernels[0].tokens.kernelArgs.resize(1);
|
||||
|
||||
inline uint32_t pushBackString(const std::string &str, std::vector<uint8_t> &storage) {
|
||||
auto offset = storage.size();
|
||||
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(str.c_str()), reinterpret_cast<const uint8_t *>(str.c_str()) + str.size());
|
||||
return static_cast<uint32_t>(offset);
|
||||
}
|
||||
recalcTokPtr();
|
||||
}
|
||||
|
||||
inline uint32_t pushBackStringToken(const std::string &str, uint32_t stringIndex, std::vector<uint8_t> &outStream) {
|
||||
auto off = outStream.size();
|
||||
outStream.reserve(outStream.size() + sizeof(iOpenCL::SPatchString) + str.length());
|
||||
outStream.resize(outStream.size() + sizeof(iOpenCL::SPatchString));
|
||||
iOpenCL::SPatchString *tok = reinterpret_cast<iOpenCL::SPatchString *>(outStream.data() + off);
|
||||
*tok = initToken<iOpenCL::SPatchString>(iOpenCL::PATCH_TOKEN::PATCH_TOKEN_STRING);
|
||||
tok->StringSize = static_cast<uint32_t>(str.length());
|
||||
tok->Size += tok->StringSize;
|
||||
tok->Index = stringIndex;
|
||||
pushBackString(str, outStream);
|
||||
return static_cast<uint32_t>(off);
|
||||
void recalcTokPtr() {
|
||||
ValidProgramWithKernel::recalcTokPtr();
|
||||
arg0InfoMutable = reinterpret_cast<iOpenCL::SPatchKernelArgumentInfo *>(storage.data() + kernelArgOffset);
|
||||
this->kernels[0].tokens.kernelArgs[0].argInfo = arg0InfoMutable;
|
||||
arg0InfoAddressQualifierMutable = reinterpret_cast<char *>(arg0InfoMutable + 1);
|
||||
arg0InfoAccessQualifierMutable = arg0InfoAddressQualifierMutable + arg0InfoMutable->AddressQualifierSize;
|
||||
arg0NameMutable = arg0InfoAccessQualifierMutable + arg0InfoMutable->AccessQualifierSize;
|
||||
arg0TypeMutable = arg0NameMutable + arg0InfoMutable->ArgumentNameSize;
|
||||
arg0TypeQualifierMutable = arg0TypeMutable + arg0InfoMutable->TypeNameSize;
|
||||
}
|
||||
|
||||
iOpenCL::SPatchKernelArgumentInfo *arg0InfoMutable = nullptr;
|
||||
char *arg0InfoAddressQualifierMutable = nullptr;
|
||||
char *arg0InfoAccessQualifierMutable = nullptr;
|
||||
char *arg0NameMutable = nullptr;
|
||||
char *arg0TypeMutable = nullptr;
|
||||
char *arg0TypeQualifierMutable = nullptr;
|
||||
size_t kernelArgOffset = 0U;
|
||||
};
|
||||
|
||||
inline uint32_t pushBackArgInfoToken(std::vector<uint8_t> &outStream,
|
||||
uint32_t argNum = 0,
|
||||
const std::string &addressQualifier = "__global", const std::string &accessQualifier = "read_write",
|
||||
const std::string &argName = "custom_arg", const std::string &typeName = "int*;", std::string typeQualifier = "const") {
|
||||
auto off = outStream.size();
|
||||
iOpenCL::SPatchKernelArgumentInfo tok = {};
|
||||
tok.Token = iOpenCL::PATCH_TOKEN_KERNEL_ARGUMENT_INFO;
|
||||
tok.AddressQualifierSize = static_cast<uint32_t>(addressQualifier.size());
|
||||
tok.AccessQualifierSize = static_cast<uint32_t>(accessQualifier.size());
|
||||
tok.ArgumentNameSize = static_cast<uint32_t>(argName.size());
|
||||
tok.TypeNameSize = static_cast<uint32_t>(typeName.size());
|
||||
tok.TypeQualifierSize = static_cast<uint32_t>(typeQualifier.size());
|
||||
tok.Size = sizeof(iOpenCL::SPatchKernelArgumentInfo) + tok.AddressQualifierSize + tok.AccessQualifierSize + tok.ArgumentNameSize + tok.TypeNameSize + tok.TypeQualifierSize;
|
||||
|
||||
outStream.insert(outStream.end(), reinterpret_cast<const uint8_t *>(&tok), reinterpret_cast<const uint8_t *>(&tok) + sizeof(tok));
|
||||
pushBackString(addressQualifier, outStream);
|
||||
pushBackString(accessQualifier, outStream);
|
||||
pushBackString(argName, outStream);
|
||||
pushBackString(typeName, outStream);
|
||||
pushBackString(typeQualifier, outStream);
|
||||
return static_cast<uint32_t>(off);
|
||||
}
|
||||
} // namespace PatchTokensTestData
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
#include "runtime/compiler_interface/patchtokens_validator.inl"
|
||||
#include "test.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "patchtokens_tests.h"
|
||||
|
||||
struct UknownTokenValidator {
|
||||
@@ -25,8 +26,8 @@ TEST(PatchtokensValidator, GivenValidProgramThenValidationSucceeds) {
|
||||
std::string error, warning;
|
||||
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidOrUnknownStatusThenValidationFails) {
|
||||
@@ -36,7 +37,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidOrUnknownStatusThenValidationF
|
||||
prog.decodeStatus = NEO::PatchTokenBinary::DecoderError::Undefined;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("ProgramFromPatchtokens wasn't successfully decoded", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
warning.clear();
|
||||
@@ -44,7 +45,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidOrUnknownStatusThenValidationF
|
||||
prog.decodeStatus = NEO::PatchTokenBinary::DecoderError::InvalidBinary;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("ProgramFromPatchtokens wasn't successfully decoded", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithASingleConstantSurfaceThenValidationSucceeds) {
|
||||
@@ -52,8 +53,8 @@ TEST(PatchtokensValidator, GivenValidProgramWithASingleConstantSurfaceThenValida
|
||||
std::string error, warning;
|
||||
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithMultipleConstantSurfacesThenValidationFails) {
|
||||
@@ -64,7 +65,7 @@ TEST(PatchtokensValidator, GivenProgramWithMultipleConstantSurfacesThenValidatio
|
||||
prog.programScopeTokens.allocateConstantMemorySurface.push_back(&constSurface2);
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled number of global constants surfaces > 1", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithASingleGlobalSurfaceThenValidationSucceeds) {
|
||||
@@ -72,8 +73,8 @@ TEST(PatchtokensValidator, GivenValidProgramWithASingleGlobalSurfaceThenValidati
|
||||
std::string error, warning;
|
||||
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithMultipleGlobalSurfacesThenValidationFails) {
|
||||
@@ -84,7 +85,7 @@ TEST(PatchtokensValidator, GivenProgramWithMultipleGlobalSurfacesThenValidationF
|
||||
prog.programScopeTokens.allocateGlobalMemorySurface.push_back(&globSurface2);
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled number of global variables surfaces > 1", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithValidConstantPointerThenValidationSucceeds) {
|
||||
@@ -92,8 +93,8 @@ TEST(PatchtokensValidator, GivenValidProgramWithValidConstantPointerThenValidati
|
||||
std::string error, warning;
|
||||
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerBufferIndexThenValidationFails) {
|
||||
@@ -103,7 +104,44 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerBufferIndexThen
|
||||
prog.constantPointerMutable->BufferIndex = 1;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidGpuPointerSizeThenValidationFails) {
|
||||
PatchTokensTestData::ValidEmptyProgram prog;
|
||||
std::string error, warning;
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 0U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Invalid pointer size", error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 1U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 2U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 3U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 4U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 5U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 6U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 7U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 8U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
|
||||
prog.headerMutable->GPUPointerSizeInBytes = 9U;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerConstantBufferIndexThenValidationFails) {
|
||||
@@ -113,7 +151,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerConstantBufferI
|
||||
prog.constantPointerMutable->ConstantBufferIndex = 1;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerBufferTypeThenValidationFails) {
|
||||
@@ -123,7 +161,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerBufferTypeThenV
|
||||
prog.constantPointerMutable->BufferType = iOpenCL::NUM_PROGRAM_SCOPE_BUFFER_TYPE;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerOffsetThenValidationFails) {
|
||||
@@ -133,7 +171,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerOffsetThenValid
|
||||
prog.constantPointerMutable->ConstantPointerOffset = prog.constSurfMutable->InlineDataSize;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithoutConstantSurfaceButWithConstantPointerThenValidationFails) {
|
||||
@@ -143,7 +181,7 @@ TEST(PatchtokensValidator, GivenProgramWithoutConstantSurfaceButWithConstantPoin
|
||||
prog.programScopeTokens.allocateConstantMemorySurface.clear();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithValidGlobalPointerThenValidationSucceeds) {
|
||||
@@ -151,8 +189,8 @@ TEST(PatchtokensValidator, GivenValidProgramWithValidGlobalPointerThenValidation
|
||||
std::string error, warning;
|
||||
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithMixedGlobalVarAndConstSurfacesAndPointersThenValidationSucceeds) {
|
||||
@@ -160,24 +198,24 @@ TEST(PatchtokensValidator, GivenValidProgramWithMixedGlobalVarAndConstSurfacesAn
|
||||
std::string error, warning;
|
||||
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenInvalidProgramWithMixedGlobalVarAndConstSurfacesAndPointersThenValidationSucceeds) {
|
||||
TEST(PatchtokensValidator, GivenInvalidProgramWithMixedGlobalVarAndConstSurfacesAndPointersThenValidationFails) {
|
||||
std::string error, warning;
|
||||
|
||||
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer progGlobalVar;
|
||||
progGlobalVar.globalPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_CONSTANT_BUFFER;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(progGlobalVar, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_NE(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_FALSE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer progConstVar;
|
||||
progConstVar.constantPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(progGlobalVar, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_NE(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(progConstVar, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_FALSE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerBufferIndexThenValidationFails) {
|
||||
@@ -187,7 +225,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerBufferIndexThenVa
|
||||
prog.globalPointerMutable->BufferIndex = 1;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerGlobalBufferIndexThenValidationFails) {
|
||||
@@ -197,7 +235,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerGlobalBufferIndex
|
||||
prog.globalPointerMutable->GlobalBufferIndex = 1;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerBufferTypeThenValidationFails) {
|
||||
@@ -207,7 +245,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerBufferTypeThenVal
|
||||
prog.globalPointerMutable->BufferType = iOpenCL::NUM_PROGRAM_SCOPE_BUFFER_TYPE;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerOffsetThenValidationFails) {
|
||||
@@ -217,7 +255,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerOffsetThenValidat
|
||||
prog.globalPointerMutable->GlobalPointerOffset = prog.globalSurfMutable->InlineDataSize;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithoutGlobalSurfaceButWithGlobalPointerThenValidationFails) {
|
||||
@@ -227,7 +265,7 @@ TEST(PatchtokensValidator, GivenProgramWithoutGlobalSurfaceButWithGlobalPointerT
|
||||
prog.programScopeTokens.allocateGlobalMemorySurface.clear();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithUnknownPatchTokenWhenUknownTokenCantBeSkippedThenValidationFails) {
|
||||
@@ -240,7 +278,7 @@ TEST(PatchtokensValidator, GivenValidProgramWithUnknownPatchTokenWhenUknownToken
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(false), error, warning));
|
||||
auto expectedError = "Unhandled required program-scope Patch Token : " + std::to_string(unknownToken.Token);
|
||||
EXPECT_STREQ(expectedError.c_str(), error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithUnknownPatchTokenWhenUknownTokenCanBeSkippedThenValidationSucceedsAndEmitsWarning) {
|
||||
@@ -252,7 +290,7 @@ TEST(PatchtokensValidator, GivenValidProgramWithUnknownPatchTokenWhenUknownToken
|
||||
prog.unhandledTokens.push_back(&unknownToken);
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
auto expectedWarning = "Unknown program-scope Patch Token : " + std::to_string(unknownToken.Token);
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_STREQ(expectedWarning.c_str(), warning.c_str());
|
||||
}
|
||||
|
||||
@@ -264,7 +302,7 @@ TEST(PatchtokensValidator, GivenProgramWithUnsupportedPatchTokenVersionThenValid
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
auto expectedError = "Unhandled Version of Patchtokens: expected: " + std::to_string(iOpenCL::CURRENT_ICBE_VERSION) + ", got: " + std::to_string(prog.header->Version);
|
||||
EXPECT_STREQ(expectedError.c_str(), error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithUnsupportedPlatformThenValidationFails) {
|
||||
@@ -283,8 +321,8 @@ TEST(PatchtokensValidator, GivenValidProgramWithKernelThenValidationSucceeds) {
|
||||
std::string error, warning;
|
||||
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelHasInvalidOrUnknownStatusThenValidationFails) {
|
||||
@@ -294,7 +332,7 @@ TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelHasInvalidOrUnknownSt
|
||||
prog.kernels[0].decodeStatus = NEO::PatchTokenBinary::DecoderError::Undefined;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("KernelFromPatchtokens wasn't successfully decoded", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
warning.clear();
|
||||
@@ -302,7 +340,7 @@ TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelHasInvalidOrUnknownSt
|
||||
prog.kernels[0].decodeStatus = NEO::PatchTokenBinary::DecoderError::InvalidBinary;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("KernelFromPatchtokens wasn't successfully decoded", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelHasInvalidChecksumThenValidationFails) {
|
||||
@@ -312,7 +350,7 @@ TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelHasInvalidChecksumThe
|
||||
prog.kernelHeaderMutable->CheckSum += 1;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("KernelFromPatchtokens has invalid checksum", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithKernelUsingSlmThenValidationSucceeds) {
|
||||
@@ -321,8 +359,8 @@ TEST(PatchtokensValidator, GivenValidProgramWithKernelUsingSlmThenValidationSucc
|
||||
|
||||
size_t slmSizeAvailable = 1 + prog.kernels[0].tokens.allocateLocalSurface->TotalInlineLocalMemorySize;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, slmSizeAvailable, UknownTokenValidator(), error, warning));
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithKernelUsingSlmWhenKernelRequiresTooMuchSlmThenValidationFails) {
|
||||
@@ -332,7 +370,7 @@ TEST(PatchtokensValidator, GivenProgramWithKernelUsingSlmWhenKernelRequiresTooMu
|
||||
size_t slmSizeAvailable = -1 + prog.kernels[0].tokens.allocateLocalSurface->TotalInlineLocalMemorySize;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::NotEnoughSlm, NEO::PatchTokenBinary::validate(prog, slmSizeAvailable, UknownTokenValidator(), error, warning));
|
||||
EXPECT_STREQ("KernelFromPatchtokens requires too much SLM", error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithKernelContainingUnknownPatchTokenWhenUknownTokenCantBeSkippedThenValidationFails) {
|
||||
@@ -345,7 +383,7 @@ TEST(PatchtokensValidator, GivenValidProgramWithKernelContainingUnknownPatchToke
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(false), error, warning));
|
||||
auto expectedError = "Unhandled required kernel-scope Patch Token : " + std::to_string(unknownToken.Token);
|
||||
EXPECT_STREQ(expectedError.c_str(), error.c_str());
|
||||
EXPECT_EQ(0U, warning.size());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenValidProgramWithKernelContainingUnknownPatchTokenWhenUknownTokenCanBeSkippedThenValidationSucceedsAndEmitsWarning) {
|
||||
@@ -357,6 +395,145 @@ TEST(PatchtokensValidator, GivenValidProgramWithKernelContainingUnknownPatchToke
|
||||
prog.kernels[0].unhandledTokens.push_back(&unknownToken);
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
auto expectedWarning = "Unknown kernel-scope Patch Token : " + std::to_string(unknownToken.Token);
|
||||
EXPECT_EQ(0U, error.size());
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_STREQ(expectedWarning.c_str(), warning.c_str());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelArgsHasProperQualifiersThenValidationSucceeds) {
|
||||
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
|
||||
std::string error, warning;
|
||||
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelsArgDoesntHaveKernelArgInfoThenValidationFails) {
|
||||
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
|
||||
std::string error, warning;
|
||||
prog.kernels[0].tokens.kernelArgs[0].argInfo = nullptr;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
auto expectedError = "Missing kernelArgInfo";
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelsArgHasUnknownAddressSpaceThenValidationFails) {
|
||||
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
|
||||
std::string error, warning;
|
||||
prog.arg0InfoAddressQualifierMutable[2] = '\0';
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
auto expectedError = "Unhandled address qualifier";
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelsArgHasUnknownAccessQualifierThenValidationFails) {
|
||||
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
|
||||
std::string error, warning;
|
||||
prog.arg0InfoAccessQualifierMutable[2] = '\0';
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
auto expectedError = "Unhandled access qualifier";
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenKernelWhenExecutionEnvironmentIsMissingThenValidationFails) {
|
||||
PatchTokensTestData::ValidProgramWithKernel prog;
|
||||
std::string error, warning;
|
||||
prog.kernels[0].tokens.executionEnvironment = nullptr;
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
auto expectedError = "Missing execution environment";
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
TEST(PatchtokensValidator, GivenKernelWhenExecutionEnvironmentHasInvalidSimdSizeThenValidationFails) {
|
||||
PatchTokensTestData::ValidProgramWithKernel prog;
|
||||
std::string error, warning;
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 0U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
auto expectedError = "Invalid LargestCompiledSIMDSize";
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 1U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 2U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 3U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 4U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 5U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 6U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 7U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 8U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 9U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_STREQ(expectedError, error.c_str());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 16U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
|
||||
error.clear();
|
||||
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 32U;
|
||||
prog.recalcTokPtr();
|
||||
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
|
||||
EXPECT_TRUE(error.empty());
|
||||
EXPECT_TRUE(warning.empty());
|
||||
}
|
||||
|
||||
@@ -440,8 +440,10 @@ TEST_F(PerformanceHintTest, givenPrintDriverDiagnosticsDebugModeEnabledWhenCallF
|
||||
|
||||
buffer.getGraphicsAllocation()->setAllocationType(GraphicsAllocation::AllocationType::BUFFER_COMPRESSED);
|
||||
mockKernel.kernelInfo.kernelArgInfo.resize(1);
|
||||
mockKernel.kernelInfo.kernelArgInfo.at(0).kernelArgPatchInfoVector.resize(1);
|
||||
mockKernel.kernelInfo.kernelArgInfo.at(0).pureStatefulBufferAccess = false;
|
||||
mockKernel.kernelInfo.kernelArgInfo[0].metadataExtended = std::make_unique<ArgTypeMetadataExtended>();
|
||||
mockKernel.kernelInfo.kernelArgInfo[0].metadataExtended->argName = "arg0";
|
||||
mockKernel.kernelInfo.kernelArgInfo[0].kernelArgPatchInfoVector.resize(1);
|
||||
mockKernel.kernelInfo.kernelArgInfo[0].pureStatefulBufferAccess = false;
|
||||
mockKernel.mockKernel->initialize();
|
||||
mockKernel.mockKernel->auxTranslationRequired = true;
|
||||
mockKernel.mockKernel->setArgBuffer(0, sizeof(cl_mem *), &clMem);
|
||||
@@ -451,7 +453,7 @@ TEST_F(PerformanceHintTest, givenPrintDriverDiagnosticsDebugModeEnabledWhenCallF
|
||||
mockKernel.mockKernel->fillWithBuffersForAuxTranslation(memObjects);
|
||||
|
||||
snprintf(expectedHint, DriverDiagnostics::maxHintStringSize, DriverDiagnostics::hintFormat[KERNEL_ARGUMENT_AUX_TRANSLATION],
|
||||
mockKernel.mockKernel->getKernelInfo().name.c_str(), 0, mockKernel.mockKernel->getKernelInfo().kernelArgInfo.at(0).name.c_str());
|
||||
mockKernel.mockKernel->getKernelInfo().name.c_str(), 0, mockKernel.mockKernel->getKernelInfo().kernelArgInfo.at(0).metadataExtended->argName.c_str());
|
||||
|
||||
std::string output = testing::internal::GetCapturedStdout();
|
||||
EXPECT_NE(0u, output.size());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "core/helpers/aligned_memory.h"
|
||||
#include "core/helpers/string.h"
|
||||
#include "core/memory_manager/graphics_allocation.h"
|
||||
#include "core/program/program_info_from_patchtokens.h"
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
|
||||
void KernelDataTest::buildAndDecode() {
|
||||
@@ -88,7 +89,9 @@ void KernelDataTest::buildAndDecode() {
|
||||
bool decodeSuccess = NEO::PatchTokenBinary::decodeKernelFromPatchtokensBlob(kernelBlob, kernelFromPatchtokens);
|
||||
EXPECT_TRUE(decodeSuccess);
|
||||
|
||||
program->populateKernelInfo(programFromPatchtokens, 0, error);
|
||||
ProgramInfo programInfo;
|
||||
NEO::populateProgramInfo(programInfo, programFromPatchtokens, DeviceInfoKernelPayloadConstants());
|
||||
error = program->processProgramInfo(programInfo);
|
||||
EXPECT_EQ(CL_SUCCESS, error);
|
||||
|
||||
// extract the kernel info
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
#include "runtime/kernel/kernel.h"
|
||||
#include "runtime/mem_obj/buffer.h"
|
||||
#include "runtime/memory_manager/surface.h"
|
||||
#include "runtime/program/create.inl"
|
||||
#include "test.h"
|
||||
#include "unit_tests/compiler_interface/patchtokens_tests.h"
|
||||
#include "unit_tests/fixtures/context_fixture.h"
|
||||
#include "unit_tests/fixtures/memory_management_fixture.h"
|
||||
#include "unit_tests/fixtures/platform_fixture.h"
|
||||
@@ -978,69 +980,25 @@ TEST_F(GTPinTests, givenInitializedGTPinInterfaceWhenKernelWithoutSSHIsUsedThenK
|
||||
EXPECT_NE(nullptr, context);
|
||||
auto pContext = castToObject<Context>(context);
|
||||
|
||||
// Prepare a kernel without SSH
|
||||
char binary[1024] = {1, 2, 3, 4, 5, 6, 7, 8, 9, '\0'};
|
||||
size_t binSize = 10;
|
||||
MockProgram *pProgram = Program::createFromGenBinary<MockProgram>(*pDevice->getExecutionEnvironment(), pContext, &binary[0], binSize, false, &retVal);
|
||||
ASSERT_NE(nullptr, pProgram);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
char *pBin = &binary[0];
|
||||
SProgramBinaryHeader *pBHdr = (SProgramBinaryHeader *)pBin;
|
||||
pBHdr->Magic = iOpenCL::MAGIC_CL;
|
||||
pBHdr->Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
pBHdr->Device = pDevice->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
pBHdr->GPUPointerSizeInBytes = 8;
|
||||
pBHdr->NumberOfKernels = 1;
|
||||
pBHdr->SteppingId = 0;
|
||||
pBHdr->PatchListSize = 0;
|
||||
pBin += sizeof(SProgramBinaryHeader);
|
||||
binSize += sizeof(SProgramBinaryHeader);
|
||||
PatchTokensTestData::ValidProgramWithKernel programTokens;
|
||||
|
||||
SKernelBinaryHeaderCommon *pKHdr = (SKernelBinaryHeaderCommon *)pBin;
|
||||
pKHdr->CheckSum = 0;
|
||||
pKHdr->ShaderHashCode = 0;
|
||||
pKHdr->KernelNameSize = 4;
|
||||
pKHdr->PatchListSize = 0;
|
||||
pKHdr->KernelHeapSize = 16;
|
||||
pKHdr->GeneralStateHeapSize = 0;
|
||||
pKHdr->DynamicStateHeapSize = 0;
|
||||
pKHdr->SurfaceStateHeapSize = 0;
|
||||
pKHdr->KernelUnpaddedSize = 0;
|
||||
pBin += sizeof(SKernelBinaryHeaderCommon);
|
||||
binSize += sizeof(SKernelBinaryHeaderCommon);
|
||||
char *pKernelBin = pBin;
|
||||
|
||||
strcpy(pBin, "Tst");
|
||||
pBin += pKHdr->KernelNameSize;
|
||||
binSize += pKHdr->KernelNameSize;
|
||||
|
||||
strcpy(pBin, "fake_ISA_code__");
|
||||
binSize += pKHdr->KernelHeapSize;
|
||||
|
||||
uint32_t kernelBinSize =
|
||||
pKHdr->DynamicStateHeapSize +
|
||||
pKHdr->GeneralStateHeapSize +
|
||||
pKHdr->KernelHeapSize +
|
||||
pKHdr->KernelNameSize +
|
||||
pKHdr->PatchListSize +
|
||||
pKHdr->SurfaceStateHeapSize;
|
||||
uint64_t hashValue = Hash::hash(reinterpret_cast<const char *>(pKernelBin), kernelBinSize);
|
||||
pKHdr->CheckSum = static_cast<uint32_t>(hashValue & 0xFFFFFFFF);
|
||||
|
||||
pProgram->genBinary = makeCopy(&binary[0], binSize);
|
||||
pProgram->genBinarySize = binSize;
|
||||
pProgram->genBinary = makeCopy(reinterpret_cast<char *>(programTokens.storage.data()), programTokens.storage.size());
|
||||
pProgram->genBinarySize = programTokens.storage.size();
|
||||
retVal = pProgram->processGenBinary();
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
// Verify that GT-Pin Kernel Create callback is not called
|
||||
int prevCount = KernelCreateCallbackCount;
|
||||
cl_kernel kernel = clCreateKernel(pProgram, "Tst", &retVal);
|
||||
cl_kernel kernel = clCreateKernel(pProgram, std::string(programTokens.kernels[0].name.begin(), programTokens.kernels[0].name.size()).c_str(), &retVal);
|
||||
EXPECT_NE(nullptr, kernel);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ(prevCount, KernelCreateCallbackCount);
|
||||
|
||||
// Cleanup
|
||||
retVal = clReleaseKernel(kernel);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
@@ -2074,68 +2032,16 @@ TEST_F(GTPinTests, givenInitializedGTPinInterfaceWhenLowMemoryConditionOccursThe
|
||||
EXPECT_NE(nullptr, context);
|
||||
auto pContext = castToObject<Context>(context);
|
||||
|
||||
// Prepare a program with one kernel having Stateless Private Surface
|
||||
char binary[1024] = {1, 2, 3, 4, 5, 6, 7, 8, 9, '\0'};
|
||||
size_t binSize = 10;
|
||||
MockProgram *pProgram = Program::createFromGenBinary<MockProgram>(*pDevice->getExecutionEnvironment(), pContext, &binary[0], binSize, false, &retVal);
|
||||
ASSERT_NE(nullptr, pProgram);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
char *pBin = &binary[0];
|
||||
SProgramBinaryHeader *pBHdr = (SProgramBinaryHeader *)pBin;
|
||||
pBHdr->Magic = iOpenCL::MAGIC_CL;
|
||||
pBHdr->Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
pBHdr->Device = pDevice->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
pBHdr->GPUPointerSizeInBytes = 8;
|
||||
pBHdr->NumberOfKernels = 1;
|
||||
pBHdr->SteppingId = 0;
|
||||
pBHdr->PatchListSize = 0;
|
||||
pBin += sizeof(SProgramBinaryHeader);
|
||||
binSize += sizeof(SProgramBinaryHeader);
|
||||
PatchTokensTestData::ValidProgramWithKernel programTokens;
|
||||
|
||||
SKernelBinaryHeaderCommon *pKHdr = (SKernelBinaryHeaderCommon *)pBin;
|
||||
pKHdr->CheckSum = 0;
|
||||
pKHdr->ShaderHashCode = 0;
|
||||
pKHdr->KernelNameSize = 4;
|
||||
pKHdr->PatchListSize = sizeof(SPatchAllocateStatelessPrivateSurface);
|
||||
pKHdr->KernelHeapSize = 16;
|
||||
pKHdr->GeneralStateHeapSize = 0;
|
||||
pKHdr->DynamicStateHeapSize = 0;
|
||||
pKHdr->SurfaceStateHeapSize = 0;
|
||||
pKHdr->KernelUnpaddedSize = 0;
|
||||
pBin += sizeof(SKernelBinaryHeaderCommon);
|
||||
binSize += sizeof(SKernelBinaryHeaderCommon);
|
||||
char *pKernelBin = pBin;
|
||||
|
||||
strcpy(pBin, "Tst");
|
||||
pBin += pKHdr->KernelNameSize;
|
||||
binSize += pKHdr->KernelNameSize;
|
||||
|
||||
strcpy(pBin, "fake_ISA_code__");
|
||||
pBin += pKHdr->KernelHeapSize;
|
||||
binSize += pKHdr->KernelHeapSize;
|
||||
|
||||
SPatchAllocateStatelessPrivateSurface *pPatch = (SPatchAllocateStatelessPrivateSurface *)pBin;
|
||||
pPatch->Token = iOpenCL::PATCH_TOKEN_ALLOCATE_STATELESS_PRIVATE_MEMORY;
|
||||
pPatch->Size = sizeof(iOpenCL::SPatchAllocateStatelessPrivateSurface);
|
||||
pPatch->SurfaceStateHeapOffset = 0;
|
||||
pPatch->DataParamOffset = 0;
|
||||
pPatch->DataParamSize = 0;
|
||||
pPatch->PerThreadPrivateMemorySize = 4;
|
||||
binSize += sizeof(SPatchAllocateStatelessPrivateSurface);
|
||||
|
||||
uint32_t kernelBinSize =
|
||||
pKHdr->DynamicStateHeapSize +
|
||||
pKHdr->GeneralStateHeapSize +
|
||||
pKHdr->KernelHeapSize +
|
||||
pKHdr->KernelNameSize +
|
||||
pKHdr->PatchListSize +
|
||||
pKHdr->SurfaceStateHeapSize;
|
||||
uint64_t hashValue = Hash::hash(reinterpret_cast<const char *>(pKernelBin), kernelBinSize);
|
||||
pKHdr->CheckSum = static_cast<uint32_t>(hashValue & 0xFFFFFFFF);
|
||||
|
||||
pProgram->genBinary = makeCopy(&binary[0], binSize);
|
||||
pProgram->genBinarySize = binSize;
|
||||
pProgram->genBinary = makeCopy(programTokens.storage.data(), programTokens.storage.size());
|
||||
pProgram->genBinarySize = programTokens.storage.size();
|
||||
retVal = pProgram->processGenBinary();
|
||||
if (retVal == CL_OUT_OF_HOST_MEMORY) {
|
||||
auto nonFailingAlloc = MemoryManagement::nonfailingAllocation;
|
||||
@@ -2430,64 +2336,17 @@ TEST_F(GTPinTests, givenInitializedGTPinInterfaceWhenOnContextCreateIsCalledThen
|
||||
EXPECT_NE(gtpinGetIgcInit(), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(ProgramTests, givenGenBinaryWithGtpinInfoWhenProcessGenBinaryCalledThenGtpinInfoIsSet) {
|
||||
cl_int retVal = CL_INVALID_BINARY;
|
||||
char genBin[1024] = {1, 2, 3, 4, 5, 6, 7, 8, 9, '\0'};
|
||||
size_t binSize = 10;
|
||||
|
||||
std::unique_ptr<MockProgram> pProgram(Program::createFromGenBinary<MockProgram>(*pDevice->getExecutionEnvironment(), nullptr, &genBin[0], binSize, false, &retVal));
|
||||
EXPECT_NE(nullptr, pProgram.get());
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ((uint32_t)CL_PROGRAM_BINARY_TYPE_EXECUTABLE, (uint32_t)pProgram->getProgramBinaryType());
|
||||
|
||||
cl_device_id deviceId = pContext->getDevice(0);
|
||||
ClDevice *pDevice = castToObject<ClDevice>(deviceId);
|
||||
char *pBin = &genBin[0];
|
||||
retVal = CL_INVALID_BINARY;
|
||||
binSize = 0;
|
||||
|
||||
// Prepare simple program binary containing patch token PATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT
|
||||
SProgramBinaryHeader *pBHdr = (SProgramBinaryHeader *)pBin;
|
||||
pBHdr->Magic = iOpenCL::MAGIC_CL;
|
||||
pBHdr->Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
pBHdr->Device = pDevice->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
pBHdr->GPUPointerSizeInBytes = 8;
|
||||
pBHdr->NumberOfKernels = 1;
|
||||
pBHdr->SteppingId = 0;
|
||||
pBHdr->PatchListSize = 0;
|
||||
pBin += sizeof(SProgramBinaryHeader);
|
||||
binSize += sizeof(SProgramBinaryHeader);
|
||||
|
||||
SKernelBinaryHeaderCommon *pKHdr = (SKernelBinaryHeaderCommon *)pBin;
|
||||
pKHdr->CheckSum = 0;
|
||||
pKHdr->ShaderHashCode = 0;
|
||||
pKHdr->KernelNameSize = 8;
|
||||
pKHdr->PatchListSize = 8;
|
||||
pKHdr->KernelHeapSize = 0;
|
||||
pKHdr->GeneralStateHeapSize = 0;
|
||||
pKHdr->DynamicStateHeapSize = 0;
|
||||
pKHdr->SurfaceStateHeapSize = 0;
|
||||
pKHdr->KernelUnpaddedSize = 0;
|
||||
pBin += sizeof(SKernelBinaryHeaderCommon);
|
||||
binSize += sizeof(SKernelBinaryHeaderCommon);
|
||||
|
||||
strcpy(pBin, "TstCopy");
|
||||
pBin += pKHdr->KernelNameSize;
|
||||
binSize += pKHdr->KernelNameSize;
|
||||
|
||||
iOpenCL::SPatchItemHeader *pPatch = (iOpenCL::SPatchItemHeader *)pBin;
|
||||
pPatch->Token = iOpenCL::PATCH_TOKEN_GTPIN_INFO;
|
||||
pPatch->Size = sizeof(iOpenCL::SPatchItemHeader);
|
||||
binSize += sizeof(iOpenCL::SPatchItemHeader);
|
||||
pBin += sizeof(iOpenCL::SPatchItemHeader);
|
||||
|
||||
pKHdr->CheckSum = PatchTokenBinary::calcKernelChecksum(ArrayRef<const uint8_t>(reinterpret_cast<uint8_t *>(pKHdr), reinterpret_cast<uint8_t *>(pBin)));
|
||||
// Decode prepared program binary
|
||||
pProgram->genBinary = makeCopy(&genBin[0], binSize);
|
||||
pProgram->genBinarySize = binSize;
|
||||
retVal = pProgram->processGenBinary();
|
||||
auto kernelInfo = pProgram->getKernelInfo("TstCopy");
|
||||
EXPECT_NE(kernelInfo->igcInfoForGtpin, nullptr);
|
||||
ASSERT_EQ(CL_SUCCESS, retVal);
|
||||
TEST_F(GTPinTests, givenInitializedGTPinInterfaceWhenOnKernelCreateIsCalledWithNullptrThenCallIsIgnored) {
|
||||
gtpinCallbacks.onContextCreate = OnContextCreate;
|
||||
gtpinCallbacks.onContextDestroy = OnContextDestroy;
|
||||
gtpinCallbacks.onKernelCreate = OnKernelCreate;
|
||||
gtpinCallbacks.onKernelSubmit = OnKernelSubmit;
|
||||
gtpinCallbacks.onCommandBufferCreate = OnCommandBufferCreate;
|
||||
gtpinCallbacks.onCommandBufferComplete = OnCommandBufferComplete;
|
||||
retFromGtPin = GTPin_Init(>pinCallbacks, &driverServices, nullptr);
|
||||
auto prevCreateCount = KernelCreateCallbackCount;
|
||||
gtpinNotifyKernelCreate(nullptr);
|
||||
EXPECT_EQ(prevCreateCount, KernelCreateCallbackCount);
|
||||
}
|
||||
|
||||
} // namespace ULT
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2017-2019 Intel Corporation
|
||||
# Copyright (C) 2017-2020 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
@@ -16,6 +16,7 @@ set(IGDRCL_SRCS_tests_kernel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_arg_pipe_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_arg_svm_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/kernel_cache_flush_requirements_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_info_cl_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_image_arg_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_immediate_arg_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_is_patched_tests.cpp
|
||||
|
||||
@@ -264,7 +264,7 @@ TEST_F(CloneKernelTest, cloneKernelWithArgImage) {
|
||||
auto crossThreadData = reinterpret_cast<uint32_t *>(pClonedKernel->getCrossThreadData());
|
||||
EXPECT_EQ(objectId, *crossThreadData);
|
||||
|
||||
auto argInfo = pClonedKernel->getKernelInfo().kernelArgInfo[0];
|
||||
const auto &argInfo = pClonedKernel->getKernelInfo().kernelArgInfo[0];
|
||||
|
||||
auto pImgWidth = ptrOffset(crossThreadData, argInfo.offsetImgWidth);
|
||||
EXPECT_EQ(imageWidth, *pImgWidth);
|
||||
@@ -315,7 +315,7 @@ TEST_F(CloneKernelTest, cloneKernelWithArgAccelerator) {
|
||||
|
||||
auto crossThreadData = reinterpret_cast<uint32_t *>(pClonedKernel->getCrossThreadData());
|
||||
|
||||
auto argInfo = pClonedKernel->getKernelInfo().kernelArgInfo[0];
|
||||
const auto &argInfo = pClonedKernel->getKernelInfo().kernelArgInfo[0];
|
||||
|
||||
uint32_t *pMbBlockType = ptrOffset(crossThreadData, argInfo.offsetVmeMbBlockType);
|
||||
EXPECT_EQ(desc.mb_block_type, *pMbBlockType);
|
||||
@@ -369,7 +369,7 @@ TEST_F(CloneKernelTest, cloneKernelWithArgSampler) {
|
||||
auto crossThreadData = reinterpret_cast<uint32_t *>(pClonedKernel->getCrossThreadData());
|
||||
EXPECT_EQ(objectId, *crossThreadData);
|
||||
|
||||
auto argInfo = pClonedKernel->getKernelInfo().kernelArgInfo[0];
|
||||
const auto &argInfo = pClonedKernel->getKernelInfo().kernelArgInfo[0];
|
||||
|
||||
auto pSnapWa = ptrOffset(crossThreadData, argInfo.offsetSamplerSnapWa);
|
||||
EXPECT_EQ(sampler->getSnapWaValue(), *pSnapWa);
|
||||
|
||||
@@ -105,7 +105,7 @@ TEST_F(KernelArgAcceleratorTest, SetKernelArgValidAccelerator) {
|
||||
|
||||
char *crossThreadData = pKernel->getCrossThreadData();
|
||||
|
||||
auto arginfo = pKernelInfo->kernelArgInfo[0];
|
||||
const auto &arginfo = pKernelInfo->kernelArgInfo[0];
|
||||
|
||||
uint32_t *pMbBlockType = ptrOffset(reinterpret_cast<uint32_t *>(crossThreadData),
|
||||
arginfo.offsetVmeMbBlockType);
|
||||
|
||||
@@ -191,3 +191,100 @@ INSTANTIATE_TEST_CASE_P(KernelArgInfoTests,
|
||||
::testing::ValuesIn(SourceFileNames),
|
||||
::testing::ValuesIn(BinaryForSourceFileNames),
|
||||
::testing::ValuesIn(KernelNames)));
|
||||
|
||||
TEST(KernelArgMetadata, WhenParseAccessQualifierIsCalledThenQualifierIsProperlyParsed) {
|
||||
using namespace NEO::KernelArgMetadata;
|
||||
EXPECT_EQ(AccessQualifier::None, KernelArgMetadata::parseAccessQualifier(""));
|
||||
EXPECT_EQ(AccessQualifier::None, KernelArgMetadata::parseAccessQualifier("NONE"));
|
||||
EXPECT_EQ(AccessQualifier::ReadOnly, KernelArgMetadata::parseAccessQualifier("read_only"));
|
||||
EXPECT_EQ(AccessQualifier::WriteOnly, KernelArgMetadata::parseAccessQualifier("write_only"));
|
||||
EXPECT_EQ(AccessQualifier::ReadWrite, KernelArgMetadata::parseAccessQualifier("read_write"));
|
||||
EXPECT_EQ(AccessQualifier::ReadOnly, KernelArgMetadata::parseAccessQualifier("__read_only"));
|
||||
EXPECT_EQ(AccessQualifier::WriteOnly, KernelArgMetadata::parseAccessQualifier("__write_only"));
|
||||
EXPECT_EQ(AccessQualifier::ReadWrite, KernelArgMetadata::parseAccessQualifier("__read_write"));
|
||||
|
||||
EXPECT_EQ(AccessQualifier::Unknown, KernelArgMetadata::parseAccessQualifier("re"));
|
||||
EXPECT_EQ(AccessQualifier::Unknown, KernelArgMetadata::parseAccessQualifier("read"));
|
||||
EXPECT_EQ(AccessQualifier::Unknown, KernelArgMetadata::parseAccessQualifier("write"));
|
||||
}
|
||||
|
||||
TEST(KernelArgMetadata, WhenParseAddressQualifierIsCalledThenQualifierIsProperlyParsed) {
|
||||
using namespace NEO::KernelArgMetadata;
|
||||
EXPECT_EQ(AddressSpaceQualifier::Global, KernelArgMetadata::parseAddressSpace(""));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Global, KernelArgMetadata::parseAddressSpace("__global"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Local, KernelArgMetadata::parseAddressSpace("__local"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Private, KernelArgMetadata::parseAddressSpace("__private"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Constant, KernelArgMetadata::parseAddressSpace("__constant"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Private, KernelArgMetadata::parseAddressSpace("not_specified"));
|
||||
|
||||
EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("wrong"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("__glob"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("__loc"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("__priv"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("__const"));
|
||||
EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("not"));
|
||||
}
|
||||
|
||||
TEST(KernelArgMetadata, WhenParseTypeQualifiersIsCalledThenQualifierIsProperlyParsed) {
|
||||
using namespace NEO::KernelArgMetadata;
|
||||
|
||||
TypeQualifiers qual = {};
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("").packed);
|
||||
|
||||
qual = {};
|
||||
qual.constQual = true;
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("const").packed);
|
||||
|
||||
qual = {};
|
||||
qual.volatileQual = true;
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("volatile").packed);
|
||||
|
||||
qual = {};
|
||||
qual.restrictQual = true;
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("restrict").packed);
|
||||
|
||||
qual = {};
|
||||
qual.pipeQual = true;
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe").packed);
|
||||
|
||||
qual = {};
|
||||
qual.unknownQual = true;
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("inval").packed);
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("cons").packed);
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("volat").packed);
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("restr").packed);
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pip").packed);
|
||||
|
||||
qual = {};
|
||||
qual.constQual = true;
|
||||
qual.volatileQual = true;
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("const volatile").packed);
|
||||
|
||||
qual = {};
|
||||
qual.constQual = true;
|
||||
qual.volatileQual = true;
|
||||
qual.restrictQual = true;
|
||||
qual.pipeQual = true;
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe const restrict volatile").packed);
|
||||
|
||||
qual = {};
|
||||
qual.constQual = true;
|
||||
qual.volatileQual = true;
|
||||
qual.restrictQual = true;
|
||||
qual.pipeQual = true;
|
||||
qual.unknownQual = true;
|
||||
EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe const restrict volatile some").packed);
|
||||
}
|
||||
|
||||
TEST(KernelArgMetadata, WhenParseLimitedStringIsCalledThenReturnedStringDoesntContainExcessiveTrailingZeroes) {
|
||||
char str1[] = "abcd\0\0\0after\0";
|
||||
EXPECT_STREQ("abcd", NEO::parseLimitedString(str1, sizeof(str1)).c_str());
|
||||
EXPECT_EQ(4U, NEO::parseLimitedString(str1, sizeof(str1)).size());
|
||||
|
||||
EXPECT_STREQ("ab", NEO::parseLimitedString(str1, 2).c_str());
|
||||
EXPECT_EQ(2U, NEO::parseLimitedString(str1, 2).size());
|
||||
|
||||
char str2[] = {'a', 'b', 'd', 'e', 'f'};
|
||||
EXPECT_STREQ("abdef", NEO::parseLimitedString(str2, sizeof(str2)).c_str());
|
||||
EXPECT_EQ(5U, NEO::parseLimitedString(str2, sizeof(str2)).size());
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ TEST_F(KernelImageArgTest, givenImageWithWriteOnlyAccessAndReadOnlyArgWhenCheckC
|
||||
imgDesc.image_height = 5;
|
||||
auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imgFormat);
|
||||
std::unique_ptr<Image> img(Image::create(context.get(), MemoryPropertiesFlagsParser::createMemoryPropertiesFlags(flags, 0, 0), flags, 0, surfaceFormat, &imgDesc, nullptr, retVal));
|
||||
pKernelInfo->kernelArgInfo[0].accessQualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY;
|
||||
pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadOnly;
|
||||
cl_mem memObj = img.get();
|
||||
retVal = pKernel->checkCorrectImageAccessQualifier(0, sizeof(memObj), &memObj);
|
||||
|
||||
@@ -157,7 +157,7 @@ TEST_F(KernelImageArgTest, givenImageWithReadOnlyAccessAndWriteOnlyArgWhenCheckC
|
||||
imgDesc.image_height = 5;
|
||||
auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imgFormat);
|
||||
std::unique_ptr<Image> img(Image::create(context.get(), MemoryPropertiesFlagsParser::createMemoryPropertiesFlags(flags, 0, 0), flags, 0, surfaceFormat, &imgDesc, nullptr, retVal));
|
||||
pKernelInfo->kernelArgInfo[0].accessQualifier = CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
|
||||
pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::WriteOnly;
|
||||
cl_mem memObj = img.get();
|
||||
retVal = pKernel->checkCorrectImageAccessQualifier(0, sizeof(memObj), &memObj);
|
||||
|
||||
@@ -177,7 +177,7 @@ TEST_F(KernelImageArgTest, givenImageWithReadOnlyAccessAndReadOnlyArgWhenCheckCo
|
||||
imgDesc.image_height = 5;
|
||||
auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imgFormat);
|
||||
std::unique_ptr<Image> img(Image::create(context.get(), MemoryPropertiesFlagsParser::createMemoryPropertiesFlags(flags, 0, 0), flags, 0, surfaceFormat, &imgDesc, nullptr, retVal));
|
||||
pKernelInfo->kernelArgInfo[0].accessQualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY;
|
||||
pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadOnly;
|
||||
cl_mem memObj = img.get();
|
||||
retVal = pKernel->checkCorrectImageAccessQualifier(0, sizeof(memObj), &memObj);
|
||||
|
||||
@@ -193,7 +193,7 @@ TEST_F(KernelImageArgTest, givenImageWithWriteOnlyAccessAndWriteOnlyArgWhenCheck
|
||||
imgDesc.image_height = 5;
|
||||
auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imgFormat);
|
||||
std::unique_ptr<Image> img(Image::create(context.get(), MemoryPropertiesFlagsParser::createMemoryPropertiesFlags(flags, 0, 0), flags, 0, surfaceFormat, &imgDesc, nullptr, retVal));
|
||||
pKernelInfo->kernelArgInfo[0].accessQualifier = CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
|
||||
pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::WriteOnly;
|
||||
cl_mem memObj = img.get();
|
||||
retVal = pKernel->checkCorrectImageAccessQualifier(0, sizeof(memObj), &memObj);
|
||||
|
||||
|
||||
61
unit_tests/kernel/kernel_info_cl_tests.cpp
Normal file
61
unit_tests/kernel/kernel_info_cl_tests.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "runtime/kernel/kernel_info_cl.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(AsClConvertersTest, whenConvertingAccessQualifiersThenProperEnumValuesAreReturned) {
|
||||
using namespace NEO::KernelArgMetadata;
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_access_qualifier>(CL_KERNEL_ARG_ACCESS_NONE), NEO::asClKernelArgAccessQualifier(AccessQualifier::None));
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_access_qualifier>(CL_KERNEL_ARG_ACCESS_READ_ONLY), NEO::asClKernelArgAccessQualifier(AccessQualifier::ReadOnly));
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_access_qualifier>(CL_KERNEL_ARG_ACCESS_WRITE_ONLY), NEO::asClKernelArgAccessQualifier(AccessQualifier::WriteOnly));
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_access_qualifier>(CL_KERNEL_ARG_ACCESS_READ_WRITE), NEO::asClKernelArgAccessQualifier(AccessQualifier::ReadWrite));
|
||||
EXPECT_EQ(0U, NEO::asClKernelArgAccessQualifier(AccessQualifier::Unknown));
|
||||
}
|
||||
|
||||
TEST(AsClConvertersTest, whenConvertingAddressQualifiersThenProperEnumValuesAreReturned) {
|
||||
using namespace NEO::KernelArgMetadata;
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_address_qualifier>(CL_KERNEL_ARG_ADDRESS_GLOBAL), NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Global));
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_address_qualifier>(CL_KERNEL_ARG_ADDRESS_LOCAL), NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Local));
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_address_qualifier>(CL_KERNEL_ARG_ADDRESS_PRIVATE), NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Private));
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_address_qualifier>(CL_KERNEL_ARG_ADDRESS_CONSTANT), NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Constant));
|
||||
EXPECT_EQ(0U, NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Unknown));
|
||||
}
|
||||
|
||||
TEST(AsClConvertersTest, whenConvertingTypeQualifiersThenProperBitfieldsAreSet) {
|
||||
using namespace NEO::KernelArgMetadata;
|
||||
TypeQualifiers typeQualifiers = {};
|
||||
typeQualifiers.constQual = true;
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_type_qualifier>(CL_KERNEL_ARG_TYPE_CONST), NEO::asClKernelArgTypeQualifier(typeQualifiers));
|
||||
|
||||
typeQualifiers = {};
|
||||
typeQualifiers.volatileQual = true;
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_type_qualifier>(CL_KERNEL_ARG_TYPE_VOLATILE), NEO::asClKernelArgTypeQualifier(typeQualifiers));
|
||||
|
||||
typeQualifiers = {};
|
||||
typeQualifiers.restrictQual = true;
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_type_qualifier>(CL_KERNEL_ARG_TYPE_RESTRICT), NEO::asClKernelArgTypeQualifier(typeQualifiers));
|
||||
|
||||
typeQualifiers = {};
|
||||
typeQualifiers.pipeQual = true;
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_type_qualifier>(CL_KERNEL_ARG_TYPE_PIPE), NEO::asClKernelArgTypeQualifier(typeQualifiers));
|
||||
|
||||
typeQualifiers = {};
|
||||
typeQualifiers.constQual = true;
|
||||
typeQualifiers.volatileQual = true;
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_type_qualifier>(CL_KERNEL_ARG_TYPE_CONST | CL_KERNEL_ARG_TYPE_VOLATILE), NEO::asClKernelArgTypeQualifier(typeQualifiers));
|
||||
|
||||
typeQualifiers = {};
|
||||
typeQualifiers.constQual = true;
|
||||
typeQualifiers.volatileQual = true;
|
||||
typeQualifiers.pipeQual = true;
|
||||
typeQualifiers.restrictQual = true;
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_type_qualifier>(CL_KERNEL_ARG_TYPE_CONST | CL_KERNEL_ARG_TYPE_VOLATILE | CL_KERNEL_ARG_TYPE_RESTRICT | CL_KERNEL_ARG_TYPE_PIPE),
|
||||
NEO::asClKernelArgTypeQualifier(typeQualifiers));
|
||||
}
|
||||
@@ -93,10 +93,11 @@ TEST_P(KernelReflectionSurfaceTest, GivenKernelInfoWithCorrectlyFilledImageArgum
|
||||
const uint32_t offsetArraySize = 32;
|
||||
|
||||
info.storeKernelArgument(&imageMemObjKernelArg);
|
||||
info.kernelArgInfo[0].accessQualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY;
|
||||
info.kernelArgInfo[0].accessQualifierStr = "read_only";
|
||||
info.kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
info.kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadOnly;
|
||||
info.kernelArgInfo[0].metadataExtended->accessQualifier = "read_only";
|
||||
info.kernelArgInfo[0].isImage = true;
|
||||
info.kernelArgInfo[0].name = "img";
|
||||
info.kernelArgInfo[0].metadataExtended->argName = "img";
|
||||
info.kernelArgInfo[0].offsetChannelDataType = offsetDataType;
|
||||
info.kernelArgInfo[0].offsetChannelOrder = offsetChannelOrder;
|
||||
info.kernelArgInfo[0].offsetHeap = offsetHeap;
|
||||
@@ -282,8 +283,9 @@ TEST_P(KernelReflectionSurfaceTest, GivenKernelInfoWithCorrectlyFilledSamplerArg
|
||||
const uint32_t offsetObjectID = 28;
|
||||
|
||||
info.storeKernelArgument(&samplerMemObjKernelArg);
|
||||
info.kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
info.kernelArgInfo[0].isSampler = true;
|
||||
info.kernelArgInfo[0].name = "smp";
|
||||
info.kernelArgInfo[0].metadataExtended->argName = "smp";
|
||||
info.kernelArgInfo[0].offsetSamplerAddressingMode = offsetSamplerAddressingMode;
|
||||
info.kernelArgInfo[0].offsetSamplerNormalizedCoords = offsetSamplerNormalizedCoords;
|
||||
info.kernelArgInfo[0].offsetSamplerSnapWa = offsetSamplerSnapWa;
|
||||
@@ -725,7 +727,7 @@ TEST(KernelReflectionSurfaceTestSingle, ObtainKernelReflectionSurfaceWithDeviceQ
|
||||
argInfo.isDeviceQueue = true;
|
||||
|
||||
info.kernelArgInfo.resize(1);
|
||||
info.kernelArgInfo[0] = argInfo;
|
||||
info.kernelArgInfo[0] = std::move(argInfo);
|
||||
|
||||
info.kernelArgInfo[0].kernelArgPatchInfoVector.resize(1);
|
||||
info.kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset = devQueueCurbeOffset;
|
||||
@@ -1654,32 +1656,35 @@ TEST_F(ReflectionSurfaceHelperFixture, setParentImageParams) {
|
||||
|
||||
argInfo.offsetHeap = 0;
|
||||
argInfo.isBuffer = true;
|
||||
info.kernelArgInfo.push_back(argInfo);
|
||||
info.kernelArgInfo.push_back(std::move(argInfo));
|
||||
|
||||
imgInfo.type = Kernel::kernelArgType::IMAGE_OBJ;
|
||||
imgInfo.object = (cl_mem)image2d.get();
|
||||
kernelArguments.push_back(imgInfo);
|
||||
|
||||
argInfo = {};
|
||||
argInfo.offsetHeap = imageID[0];
|
||||
argInfo.isImage = true;
|
||||
info.kernelArgInfo.push_back(argInfo);
|
||||
info.kernelArgInfo.push_back(std::move(argInfo));
|
||||
|
||||
// Buffer Object should never be dereferenced by setParentImageParams
|
||||
imgInfo.type = Kernel::kernelArgType::BUFFER_OBJ;
|
||||
imgInfo.object = reinterpret_cast<void *>(0x0);
|
||||
kernelArguments.push_back(imgInfo);
|
||||
|
||||
argInfo = {};
|
||||
argInfo.offsetHeap = 0;
|
||||
argInfo.isBuffer = true;
|
||||
info.kernelArgInfo.push_back(argInfo);
|
||||
info.kernelArgInfo.push_back(std::move(argInfo));
|
||||
|
||||
imgInfo.type = Kernel::kernelArgType::IMAGE_OBJ;
|
||||
imgInfo.object = (cl_mem)image1d.get();
|
||||
kernelArguments.push_back(imgInfo);
|
||||
|
||||
argInfo = {};
|
||||
argInfo.offsetHeap = imageID[1];
|
||||
argInfo.isImage = true;
|
||||
info.kernelArgInfo.push_back(argInfo);
|
||||
info.kernelArgInfo.push_back(std::move(argInfo));
|
||||
|
||||
std::unique_ptr<char> reflectionSurfaceMemory(new char[4096]);
|
||||
|
||||
@@ -1737,36 +1742,42 @@ TEST_F(ReflectionSurfaceHelperFixture, setParentSamplerParams) {
|
||||
// Buffer Object should never be dereferenced by setParentImageParams
|
||||
imgInfo.type = Kernel::kernelArgType::BUFFER_OBJ;
|
||||
imgInfo.object = reinterpret_cast<void *>(0x0);
|
||||
kernelArguments.push_back(imgInfo);
|
||||
kernelArguments.push_back(std::move(imgInfo));
|
||||
|
||||
argInfo.offsetHeap = 0;
|
||||
argInfo.isBuffer = true;
|
||||
info.kernelArgInfo.push_back(argInfo);
|
||||
info.kernelArgInfo.push_back(std::move(argInfo));
|
||||
|
||||
imgInfo = {};
|
||||
imgInfo.type = Kernel::kernelArgType::SAMPLER_OBJ;
|
||||
imgInfo.object = (cl_sampler)sampler1.get();
|
||||
kernelArguments.push_back(imgInfo);
|
||||
kernelArguments.push_back(std::move(imgInfo));
|
||||
|
||||
argInfo = {};
|
||||
argInfo.offsetHeap = samplerID[0];
|
||||
argInfo.isSampler = true;
|
||||
info.kernelArgInfo.push_back(argInfo);
|
||||
info.kernelArgInfo.push_back(std::move(argInfo));
|
||||
|
||||
// Buffer Object should never be dereferenced by setParentImageParams
|
||||
imgInfo = {};
|
||||
imgInfo.type = Kernel::kernelArgType::BUFFER_OBJ;
|
||||
imgInfo.object = reinterpret_cast<void *>(0x0);
|
||||
kernelArguments.push_back(imgInfo);
|
||||
kernelArguments.push_back(std::move(imgInfo));
|
||||
|
||||
argInfo = {};
|
||||
argInfo.offsetHeap = 0;
|
||||
argInfo.isBuffer = true;
|
||||
info.kernelArgInfo.push_back(argInfo);
|
||||
info.kernelArgInfo.push_back(std::move(argInfo));
|
||||
|
||||
imgInfo = {};
|
||||
imgInfo.type = Kernel::kernelArgType::SAMPLER_OBJ;
|
||||
imgInfo.object = (cl_sampler)sampler2.get();
|
||||
kernelArguments.push_back(imgInfo);
|
||||
kernelArguments.push_back(std::move(imgInfo));
|
||||
|
||||
argInfo = {};
|
||||
argInfo.offsetHeap = samplerID[1];
|
||||
argInfo.isSampler = true;
|
||||
info.kernelArgInfo.push_back(argInfo);
|
||||
info.kernelArgInfo.push_back(std::move(argInfo));
|
||||
|
||||
std::unique_ptr<char> reflectionSurfaceMemory(new char[4096]);
|
||||
|
||||
@@ -2196,7 +2207,7 @@ TEST_F(KernelReflectionMultiDeviceTest, ObtainKernelReflectionSurfaceWithDeviceQ
|
||||
argInfo.isDeviceQueue = true;
|
||||
|
||||
info.kernelArgInfo.resize(1);
|
||||
info.kernelArgInfo[0] = argInfo;
|
||||
info.kernelArgInfo[0] = std::move(argInfo);
|
||||
|
||||
info.kernelArgInfo[0].kernelArgPatchInfoVector.resize(1);
|
||||
info.kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset = devQueueCurbeOffset;
|
||||
|
||||
@@ -2075,7 +2075,7 @@ HWTEST_F(KernelResidencyTest, test_MakeArgsResidentCheckImageFromImage) {
|
||||
KernelArgInfo kernelArgInfo;
|
||||
kernelArgInfo.isImage = true;
|
||||
|
||||
pKernelInfo->kernelArgInfo.push_back(kernelArgInfo);
|
||||
pKernelInfo->kernelArgInfo.push_back(std::move(kernelArgInfo));
|
||||
|
||||
auto program = std::make_unique<MockProgram>(*pDevice->getExecutionEnvironment());
|
||||
program->setContext(&context);
|
||||
@@ -2494,19 +2494,25 @@ TEST(KernelInfoTest, getArgNumByName) {
|
||||
EXPECT_EQ(-1, info.getArgNumByName(""));
|
||||
|
||||
KernelArgInfo kai;
|
||||
kai.name = "arg1";
|
||||
info.kernelArgInfo.push_back(kai);
|
||||
kai.metadataExtended = std::make_unique<ArgTypeMetadataExtended>();
|
||||
kai.metadataExtended->argName = "arg1";
|
||||
info.kernelArgInfo.push_back(std::move(kai));
|
||||
|
||||
EXPECT_EQ(-1, info.getArgNumByName(""));
|
||||
EXPECT_EQ(-1, info.getArgNumByName("arg2"));
|
||||
|
||||
EXPECT_EQ(0, info.getArgNumByName("arg1"));
|
||||
|
||||
kai.name = "arg2";
|
||||
info.kernelArgInfo.push_back(kai);
|
||||
kai = {};
|
||||
kai.metadataExtended = std::make_unique<ArgTypeMetadataExtended>();
|
||||
kai.metadataExtended->argName = "arg2";
|
||||
info.kernelArgInfo.push_back(std::move(kai));
|
||||
|
||||
EXPECT_EQ(0, info.getArgNumByName("arg1"));
|
||||
EXPECT_EQ(1, info.getArgNumByName("arg2"));
|
||||
|
||||
info.kernelArgInfo[0].metadataExtended.reset();
|
||||
EXPECT_EQ(-1, info.getArgNumByName("arg1"));
|
||||
}
|
||||
|
||||
TEST(KernelTest, getInstructionHeapSizeForExecutionModelReturnsZeroForNormalKernel) {
|
||||
@@ -2644,15 +2650,16 @@ TEST(KernelTest, givenFtrRenderCompressedBuffersWhenInitializingArgsWithNonState
|
||||
context->contextType = ContextType::CONTEXT_TYPE_UNRESTRICTIVE;
|
||||
MockKernelWithInternals kernel(*device, context.get());
|
||||
kernel.kernelInfo.kernelArgInfo.resize(1);
|
||||
kernel.kernelInfo.kernelArgInfo.at(0).typeStr = "char *";
|
||||
kernel.kernelInfo.kernelArgInfo.at(0).isBuffer = true;
|
||||
kernel.kernelInfo.kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
kernel.kernelInfo.kernelArgInfo[0].metadataExtended->type = "char *";
|
||||
kernel.kernelInfo.kernelArgInfo[0].isBuffer = true;
|
||||
|
||||
capabilityTable.ftrRenderCompressedBuffers = false;
|
||||
kernel.kernelInfo.kernelArgInfo.at(0).pureStatefulBufferAccess = true;
|
||||
kernel.kernelInfo.kernelArgInfo[0].pureStatefulBufferAccess = true;
|
||||
kernel.mockKernel->initialize();
|
||||
EXPECT_FALSE(kernel.mockKernel->isAuxTranslationRequired());
|
||||
|
||||
kernel.kernelInfo.kernelArgInfo.at(0).pureStatefulBufferAccess = false;
|
||||
kernel.kernelInfo.kernelArgInfo[0].pureStatefulBufferAccess = false;
|
||||
kernel.mockKernel->initialize();
|
||||
EXPECT_FALSE(kernel.mockKernel->isAuxTranslationRequired());
|
||||
|
||||
@@ -2680,10 +2687,11 @@ TEST(KernelTest, givenDebugVariableSetWhenKernelHasStatefulBufferAccessThenMarkK
|
||||
auto context = clUniquePtr(new MockContext(device.get()));
|
||||
MockKernelWithInternals kernel(*device, context.get());
|
||||
kernel.kernelInfo.kernelArgInfo.resize(1);
|
||||
kernel.kernelInfo.kernelArgInfo.at(0).typeStr = "char *";
|
||||
kernel.kernelInfo.kernelArgInfo.at(0).isBuffer = true;
|
||||
kernel.kernelInfo.kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
kernel.kernelInfo.kernelArgInfo[0].metadataExtended->type = "char *";
|
||||
kernel.kernelInfo.kernelArgInfo[0].isBuffer = true;
|
||||
|
||||
kernel.kernelInfo.kernelArgInfo.at(0).pureStatefulBufferAccess = false;
|
||||
kernel.kernelInfo.kernelArgInfo[0].pureStatefulBufferAccess = false;
|
||||
localHwInfo.capabilityTable.ftrRenderCompressedBuffers = false;
|
||||
|
||||
kernel.mockKernel->initialize();
|
||||
@@ -2702,7 +2710,8 @@ TEST(KernelTest, givenKernelWithPairArgumentWhenItIsInitializedThenPatchImmediat
|
||||
auto context = clUniquePtr(new MockContext(device.get()));
|
||||
MockKernelWithInternals kernel(*device, context.get());
|
||||
kernel.kernelInfo.kernelArgInfo.resize(1);
|
||||
kernel.kernelInfo.kernelArgInfo.at(0).typeStr = "pair<char*, int>";
|
||||
kernel.kernelInfo.kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
kernel.kernelInfo.kernelArgInfo[0].metadataExtended->type = "pair<char*, int>";
|
||||
|
||||
kernel.mockKernel->initialize();
|
||||
EXPECT_EQ(&Kernel::setArgImmediate, kernel.mockKernel->kernelArgHandlers[0]);
|
||||
@@ -2800,7 +2809,7 @@ TEST(KernelTest, givenAllArgumentsAreStatefulBuffersWhenInitializingThenAllBuffe
|
||||
kernelArgInfo[1].pureStatefulBufferAccess = true;
|
||||
|
||||
MockKernelWithInternals kernel{*device};
|
||||
kernel.kernelInfo.kernelArgInfo = kernelArgInfo;
|
||||
kernel.kernelInfo.kernelArgInfo.swap(kernelArgInfo);
|
||||
|
||||
kernel.mockKernel->initialize();
|
||||
EXPECT_TRUE(kernel.mockKernel->allBufferArgsStateful);
|
||||
@@ -2816,7 +2825,7 @@ TEST(KernelTest, givenAllArgumentsAreBuffersButNotAllAreStatefulWhenInitializing
|
||||
kernelArgInfo[1].pureStatefulBufferAccess = false;
|
||||
|
||||
MockKernelWithInternals kernel{*device};
|
||||
kernel.kernelInfo.kernelArgInfo = kernelArgInfo;
|
||||
kernel.kernelInfo.kernelArgInfo.swap(kernelArgInfo);
|
||||
|
||||
kernel.mockKernel->initialize();
|
||||
EXPECT_FALSE(kernel.mockKernel->allBufferArgsStateful);
|
||||
@@ -2832,7 +2841,7 @@ TEST(KernelTest, givenNotAllArgumentsAreBuffersButAllBuffersAreStatefulWhenIniti
|
||||
kernelArgInfo[1].pureStatefulBufferAccess = false;
|
||||
|
||||
MockKernelWithInternals kernel{*device};
|
||||
kernel.kernelInfo.kernelArgInfo = kernelArgInfo;
|
||||
kernel.kernelInfo.kernelArgInfo.swap(kernelArgInfo);
|
||||
|
||||
kernel.mockKernel->initialize();
|
||||
EXPECT_TRUE(kernel.mockKernel->allBufferArgsStateful);
|
||||
@@ -3006,3 +3015,20 @@ TEST_F(KernelMultiRootDeviceTest, privateSurfaceHasCorrectRootDeviceIndex) {
|
||||
ASSERT_NE(nullptr, privateSurface);
|
||||
EXPECT_EQ(expectedRootDeviceIndex, privateSurface->getRootDeviceIndex());
|
||||
}
|
||||
|
||||
TEST(KernelCreateTest, whenInitFailedThenReturnNull) {
|
||||
struct MockProgram {
|
||||
int getDevice(int) { return 0; }
|
||||
void getSource(std::string &) {}
|
||||
} mockProgram;
|
||||
struct MockKernel {
|
||||
MockKernel(MockProgram *, const KernelInfo &, int) {}
|
||||
int initialize() { return -1; };
|
||||
};
|
||||
|
||||
KernelInfo info;
|
||||
info.gpuPointerSize = 8;
|
||||
|
||||
auto ret = Kernel::create<MockKernel>(&mockProgram, info, nullptr);
|
||||
EXPECT_EQ(nullptr, ret);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "core/memory_manager/residency.h"
|
||||
#include "core/os_interface/os_context.h"
|
||||
#include "core/os_interface/os_interface.h"
|
||||
#include "core/program/program_initialization.h"
|
||||
#include "core/unit_tests/compiler_interface/linker_mock.h"
|
||||
#include "core/unit_tests/helpers/debug_manager_state_restore.h"
|
||||
#include "runtime/event/event.h"
|
||||
#include "runtime/helpers/dispatch_info.h"
|
||||
@@ -2118,17 +2120,15 @@ TEST(MemoryManagerTest, whenMemoryManagerReturnsNullptrThenAllocateGlobalsSurfac
|
||||
MockClDevice device{new MockDevice};
|
||||
std::unique_ptr<MemoryManager> memoryManager(new MemoryManagerWithFailure());
|
||||
device.injectMemoryManager(memoryManager.release());
|
||||
MockContext context(&device, true);
|
||||
|
||||
delete context.svmAllocsManager;
|
||||
context.svmAllocsManager = nullptr;
|
||||
|
||||
GraphicsAllocation *allocation = allocateGlobalsSurface(&context, &device, 1024, false, true, nullptr);
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
linkerInput.traits.exportsGlobalConstants = true;
|
||||
linkerInput.traits.exportsGlobalVariables = true;
|
||||
GraphicsAllocation *allocation = allocateGlobalsSurface(nullptr, device.getDevice(), 1024, false, &linkerInput, nullptr);
|
||||
EXPECT_EQ(nullptr, allocation);
|
||||
|
||||
context.svmAllocsManager = new SVMAllocsManager(device.getMemoryManager());
|
||||
|
||||
allocation = allocateGlobalsSurface(&context, &device, 1024, false, true, nullptr);
|
||||
auto svmAllocsManager = std::make_unique<SVMAllocsManager>(device.getMemoryManager());
|
||||
allocation = allocateGlobalsSurface(svmAllocsManager.get(), device.getDevice(), 1024, false, &linkerInput, nullptr);
|
||||
EXPECT_EQ(nullptr, allocation);
|
||||
}
|
||||
|
||||
@@ -2161,7 +2161,10 @@ TEST_F(MemoryManagerMultiRootDeviceTests, globalsSurfaceHasCorrectRootDeviceInde
|
||||
}
|
||||
|
||||
std::vector<unsigned char> initData(1024, 0x5B);
|
||||
GraphicsAllocation *allocation = allocateGlobalsSurface(context.get(), device.get(), initData.size(), false, true, initData.data());
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
linkerInput.traits.exportsGlobalConstants = true;
|
||||
linkerInput.traits.exportsGlobalVariables = true;
|
||||
GraphicsAllocation *allocation = allocateGlobalsSurface(context->svmAllocsManager, device->getDevice(), initData.size(), false, &linkerInput, initData.data());
|
||||
|
||||
ASSERT_NE(nullptr, allocation);
|
||||
EXPECT_EQ(expectedRootDeviceIndex, allocation->getRootDeviceIndex());
|
||||
|
||||
@@ -307,10 +307,14 @@ class MockKernelWithInternals {
|
||||
kernelInfo.kernelArgInfo[0].kernelArgPatchInfoVector.resize(1);
|
||||
kernelInfo.kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset = 0;
|
||||
kernelInfo.kernelArgInfo[0].kernelArgPatchInfoVector[0].size = sizeof(uintptr_t);
|
||||
kernelInfo.kernelArgInfo[0].metadata.addressQualifier = NEO::KernelArgMetadata::AddressSpaceQualifier::Global;
|
||||
kernelInfo.kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadWrite;
|
||||
|
||||
kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector.resize(1);
|
||||
kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector[0].crossthreadOffset = 0;
|
||||
kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector[0].size = sizeof(uintptr_t);
|
||||
kernelInfo.kernelArgInfo[1].metadata.addressQualifier = NEO::KernelArgMetadata::AddressSpaceQualifier::Global;
|
||||
kernelInfo.kernelArgInfo[1].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadWrite;
|
||||
|
||||
mockKernel->setKernelArguments(defaultKernelArguments);
|
||||
mockKernel->kernelArgRequiresCacheFlush.resize(2);
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "core/compiler_interface/compiler_cache.h"
|
||||
#include "core/helpers/hash.h"
|
||||
#include "core/program/program_info_from_patchtokens.h"
|
||||
#include "runtime/compiler_interface/patchtokens_decoder.h"
|
||||
#include "runtime/context/context.h"
|
||||
#include "runtime/program/create.inl"
|
||||
#include "runtime/program/kernel_info.h"
|
||||
@@ -81,56 +83,30 @@ void GlobalMockSipProgram::shutDownSipProgram() {
|
||||
}
|
||||
|
||||
Program *GlobalMockSipProgram::getSipProgramWithCustomBinary() {
|
||||
char binary[1024];
|
||||
char *pBinary = binary;
|
||||
auto totalSize = 0u;
|
||||
NEO::PatchTokenBinary::ProgramFromPatchtokens programTokens;
|
||||
programTokens.kernels.resize(1);
|
||||
|
||||
SProgramBinaryHeader *pBHdr = (SProgramBinaryHeader *)binary;
|
||||
pBHdr->Magic = iOpenCL::MAGIC_CL;
|
||||
pBHdr->Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
pBHdr->Device = platformDevices[0]->platform.eRenderCoreFamily;
|
||||
pBHdr->GPUPointerSizeInBytes = 8;
|
||||
pBHdr->NumberOfKernels = 1;
|
||||
pBHdr->SteppingId = 0;
|
||||
pBHdr->PatchListSize = 0;
|
||||
pBinary += sizeof(SProgramBinaryHeader);
|
||||
totalSize += sizeof(SProgramBinaryHeader);
|
||||
const uint8_t isa[] = "kernel morphEUs()";
|
||||
const char name[] = "sip";
|
||||
|
||||
SKernelBinaryHeaderCommon *pKHdr = (SKernelBinaryHeaderCommon *)pBinary;
|
||||
pKHdr->CheckSum = 0;
|
||||
pKHdr->ShaderHashCode = 0;
|
||||
pKHdr->KernelNameSize = 4;
|
||||
pKHdr->PatchListSize = 0;
|
||||
pKHdr->KernelHeapSize = 16;
|
||||
pKHdr->GeneralStateHeapSize = 0;
|
||||
pKHdr->DynamicStateHeapSize = 0;
|
||||
pKHdr->SurfaceStateHeapSize = 0;
|
||||
pKHdr->KernelUnpaddedSize = 0;
|
||||
pBinary += sizeof(SKernelBinaryHeaderCommon);
|
||||
totalSize += sizeof(SKernelBinaryHeaderCommon);
|
||||
char *pKernelBin = pBinary;
|
||||
strcpy_s(pBinary, 4, "sip");
|
||||
pBinary += pKHdr->KernelNameSize;
|
||||
totalSize += pKHdr->KernelNameSize;
|
||||
SProgramBinaryHeader progHeader = {};
|
||||
progHeader.NumberOfKernels = 1;
|
||||
|
||||
strcpy_s(pBinary, 18, "kernel morphEUs()");
|
||||
totalSize += pKHdr->KernelHeapSize;
|
||||
SKernelBinaryHeaderCommon kernHeader = {};
|
||||
kernHeader.KernelNameSize = sizeof(name);
|
||||
kernHeader.KernelHeapSize = sizeof(isa);
|
||||
kernHeader.KernelUnpaddedSize = sizeof(isa);
|
||||
|
||||
uint32_t kernelBinSize =
|
||||
pKHdr->DynamicStateHeapSize +
|
||||
pKHdr->GeneralStateHeapSize +
|
||||
pKHdr->KernelHeapSize +
|
||||
pKHdr->KernelNameSize +
|
||||
pKHdr->PatchListSize +
|
||||
pKHdr->SurfaceStateHeapSize;
|
||||
uint64_t hashValue = Hash::hash(reinterpret_cast<const char *>(pKernelBin), kernelBinSize);
|
||||
pKHdr->CheckSum = static_cast<uint32_t>(hashValue & 0xFFFFFFFF);
|
||||
programTokens.header = &progHeader;
|
||||
programTokens.kernels[0].header = &kernHeader;
|
||||
programTokens.kernels[0].isa = isa;
|
||||
programTokens.kernels[0].name = name;
|
||||
|
||||
auto errCode = CL_SUCCESS;
|
||||
auto program = Program::createFromGenBinary(executionEnvironment, nullptr, binary, totalSize, false, &errCode);
|
||||
UNRECOVERABLE_IF(errCode != CL_SUCCESS);
|
||||
errCode = program->processGenBinary();
|
||||
UNRECOVERABLE_IF(errCode != CL_SUCCESS);
|
||||
return program;
|
||||
NEO::ProgramInfo programInfo;
|
||||
NEO::populateProgramInfo(programInfo, programTokens, {});
|
||||
|
||||
Program *ret = new Program(executionEnvironment, nullptr, false);
|
||||
ret->processProgramInfo(programInfo);
|
||||
return ret;
|
||||
}
|
||||
} // namespace NEO
|
||||
|
||||
@@ -26,12 +26,9 @@ class GraphicsAllocation;
|
||||
class MockProgram : public Program {
|
||||
public:
|
||||
using Program::createProgramFromBinary;
|
||||
using Program::getKernelNamesString;
|
||||
using Program::internalOptionsToExtract;
|
||||
using Program::isKernelDebugEnabled;
|
||||
using Program::linkBinary;
|
||||
using Program::populateKernelInfo;
|
||||
using Program::prepareLinkerInputStorage;
|
||||
using Program::rebuildProgramFromIr;
|
||||
using Program::resolveProgramBinary;
|
||||
using Program::separateBlockKernels;
|
||||
@@ -58,7 +55,6 @@ class MockProgram : public Program {
|
||||
using Program::isSpirV;
|
||||
using Program::linkerInput;
|
||||
using Program::pDevice;
|
||||
using Program::processProgramScopeMetadata;
|
||||
using Program::programBinaryType;
|
||||
using Program::sourceCode;
|
||||
using Program::specConstantsIds;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2017-2019 Intel Corporation
|
||||
# Copyright (C) 2017-2020 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
@@ -27,5 +27,11 @@ set(IGDRCL_SRCS_tests_program
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_with_kernel_debug_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/program_with_source.h
|
||||
)
|
||||
|
||||
get_property(NEO_CORE_SRCS_tests_program GLOBAL PROPERTY NEO_CORE_SRCS_tests_program)
|
||||
list(APPEND IGDRCL_SRCS_tests_program
|
||||
${NEO_CORE_SRCS_tests_program}
|
||||
)
|
||||
|
||||
target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_program})
|
||||
add_subdirectories()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "runtime/execution_environment/execution_environment.h"
|
||||
#include "runtime/program/create.inl"
|
||||
#include "runtime/program/program.h"
|
||||
#include "unit_tests/compiler_interface/patchtokens_tests.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@@ -61,60 +62,28 @@ inline std::vector<char> CreateBinary(bool addUnhandledProgramScopePatchToken, b
|
||||
int32_t unhandledTokenId = static_cast<int32_t>(iOpenCL::NUM_PATCH_TOKENS)) {
|
||||
std::vector<char> ret;
|
||||
|
||||
{
|
||||
iOpenCL::SProgramBinaryHeader progBinHeader = {};
|
||||
progBinHeader.Magic = iOpenCL::MAGIC_CL;
|
||||
progBinHeader.Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
progBinHeader.Device = renderCoreFamily;
|
||||
progBinHeader.GPUPointerSizeInBytes = 8;
|
||||
progBinHeader.NumberOfKernels = 1;
|
||||
progBinHeader.SteppingId = 0;
|
||||
progBinHeader.PatchListSize = 0;
|
||||
if (false == addUnhandledProgramScopePatchToken) {
|
||||
PushBackToken(ret, progBinHeader);
|
||||
} else {
|
||||
progBinHeader.PatchListSize = static_cast<uint32_t>(sizeof(iOpenCL::SPatchItemHeader));
|
||||
PushBackToken(ret, progBinHeader);
|
||||
|
||||
iOpenCL::SPatchItemHeader unhandledToken = {};
|
||||
unhandledToken.Size = static_cast<uint32_t>(sizeof(iOpenCL::SPatchItemHeader));
|
||||
unhandledToken.Token = static_cast<uint32_t>(unhandledTokenId);
|
||||
PushBackToken(ret, unhandledToken);
|
||||
}
|
||||
if (addUnhandledProgramScopePatchToken && addUnhandledKernelScopePatchToken) {
|
||||
return {};
|
||||
}
|
||||
|
||||
{
|
||||
std::string kernelName = "testKernel";
|
||||
while (kernelName.size() % 4 != 0) {
|
||||
// pad with \0 to get 4-byte size alignment of kernelName
|
||||
kernelName.push_back('\0');
|
||||
}
|
||||
iOpenCL::SKernelBinaryHeaderCommon kernBinHeader = {};
|
||||
kernBinHeader.CheckSum = 0U;
|
||||
kernBinHeader.ShaderHashCode = 0;
|
||||
kernBinHeader.KernelNameSize = static_cast<uint32_t>(kernelName.size());
|
||||
kernBinHeader.PatchListSize = 0;
|
||||
kernBinHeader.KernelHeapSize = 0;
|
||||
kernBinHeader.GeneralStateHeapSize = 0;
|
||||
kernBinHeader.DynamicStateHeapSize = 0;
|
||||
kernBinHeader.SurfaceStateHeapSize = 0;
|
||||
kernBinHeader.KernelUnpaddedSize = 0;
|
||||
if (addUnhandledProgramScopePatchToken) {
|
||||
PatchTokensTestData::ValidProgramWithConstantSurface programWithUnhandledToken;
|
||||
|
||||
auto headerOffset = ret.size();
|
||||
PushBackToken(ret, kernBinHeader);
|
||||
ret.insert(ret.end(), kernelName.begin(), kernelName.end());
|
||||
uint32_t patchListSize = 0;
|
||||
if (addUnhandledKernelScopePatchToken) {
|
||||
iOpenCL::SPatchItemHeader unhandledToken = {};
|
||||
unhandledToken.Size = static_cast<uint32_t>(sizeof(iOpenCL::SPatchItemHeader));
|
||||
unhandledToken.Token = static_cast<uint32_t>(unhandledTokenId);
|
||||
PushBackToken(ret, unhandledToken);
|
||||
patchListSize = static_cast<uint32_t>(sizeof(iOpenCL::SPatchItemHeader));
|
||||
}
|
||||
iOpenCL::SKernelBinaryHeaderCommon *kernHeader = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(ret.data() + headerOffset);
|
||||
kernHeader->PatchListSize = patchListSize;
|
||||
auto kernelData = reinterpret_cast<const uint8_t *>(kernHeader);
|
||||
kernHeader->CheckSum = NEO::PatchTokenBinary::calcKernelChecksum(ArrayRef<const uint8_t>(kernelData, reinterpret_cast<const uint8_t *>(&*ret.rbegin()) + 1));
|
||||
iOpenCL::SPatchItemHeader &unhandledToken = *programWithUnhandledToken.constSurfMutable;
|
||||
unhandledToken.Size += programWithUnhandledToken.constSurfMutable->InlineDataSize;
|
||||
unhandledToken.Token = static_cast<uint32_t>(unhandledTokenId);
|
||||
ret.assign(reinterpret_cast<char *>(programWithUnhandledToken.storage.data()),
|
||||
reinterpret_cast<char *>(programWithUnhandledToken.storage.data() + programWithUnhandledToken.storage.size()));
|
||||
} else if (addUnhandledKernelScopePatchToken) {
|
||||
PatchTokensTestData::ValidProgramWithKernelAndArg programWithKernelWithUnhandledToken;
|
||||
iOpenCL::SPatchItemHeader &unhandledToken = *programWithKernelWithUnhandledToken.arg0InfoMutable;
|
||||
unhandledToken.Token = static_cast<uint32_t>(unhandledTokenId);
|
||||
programWithKernelWithUnhandledToken.recalcTokPtr();
|
||||
ret.assign(reinterpret_cast<char *>(programWithKernelWithUnhandledToken.storage.data()),
|
||||
reinterpret_cast<char *>(programWithKernelWithUnhandledToken.storage.data() + programWithKernelWithUnhandledToken.storage.size()));
|
||||
} else {
|
||||
PatchTokensTestData::ValidProgramWithKernel regularProgramTokens;
|
||||
ret.assign(reinterpret_cast<char *>(regularProgramTokens.storage.data()), reinterpret_cast<char *>(regularProgramTokens.storage.data() + regularProgramTokens.storage.size()));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -10,18 +10,177 @@
|
||||
#include "runtime/program/kernel_info_from_patchtokens.h"
|
||||
#include "unit_tests/compiler_interface/patchtokens_tests.h"
|
||||
|
||||
TEST(GetInlineData, GivenValidEmptyKernelFromPatchtokensThenReturnEmptyKernelInfo) {
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenValidEmptyKernelFromPatchtokensThenReturnEmptyKernelInfo) {
|
||||
std::vector<uint8_t> storage;
|
||||
auto src = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
NEO::KernelInfo dst = {};
|
||||
NEO::populateKernelInfo(dst, src);
|
||||
NEO::populateKernelInfo(dst, src, 4, {});
|
||||
|
||||
NEO::KernelInfo expectedKernelInfo = {};
|
||||
expectedKernelInfo.name = std::string(src.name.begin()).c_str();
|
||||
expectedKernelInfo.heapInfo.pKernelHeader = src.header;
|
||||
expectedKernelInfo.isValid = true;
|
||||
|
||||
EXPECT_STREQ(expectedKernelInfo.name.c_str(), dst.name.c_str());
|
||||
EXPECT_EQ(expectedKernelInfo.heapInfo.pKernelHeader, dst.heapInfo.pKernelHeader);
|
||||
EXPECT_EQ(expectedKernelInfo.isValid, dst.isValid);
|
||||
}
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenValidKernelWithArgThenMetadataIsProperlyPopulated) {
|
||||
PatchTokensTestData::ValidProgramWithKernelAndArg src;
|
||||
NEO::KernelInfo dst = {};
|
||||
NEO::populateKernelInfo(dst, src.kernels[0], 4, {});
|
||||
ASSERT_EQ(1U, dst.kernelArgInfo.size());
|
||||
EXPECT_EQ(NEO::KernelArgMetadata::AccessQualifier::ReadWrite, dst.kernelArgInfo[0].metadata.accessQualifier);
|
||||
EXPECT_EQ(NEO::KernelArgMetadata::AddressSpaceQualifier::Global, dst.kernelArgInfo[0].metadata.addressQualifier);
|
||||
NEO::KernelArgMetadata::TypeQualifiers typeQualifiers = {};
|
||||
typeQualifiers.constQual = true;
|
||||
EXPECT_EQ(typeQualifiers.packed, dst.kernelArgInfo[0].metadata.typeQualifiers.packed);
|
||||
EXPECT_EQ(0U, dst.kernelArgInfo[0].metadata.argByValSize);
|
||||
ASSERT_NE(nullptr, dst.kernelArgInfo[0].metadataExtended);
|
||||
EXPECT_STREQ("__global", dst.kernelArgInfo[0].metadataExtended->addressQualifier.c_str());
|
||||
EXPECT_STREQ("read_write", dst.kernelArgInfo[0].metadataExtended->accessQualifier.c_str());
|
||||
EXPECT_STREQ("custom_arg", dst.kernelArgInfo[0].metadataExtended->argName.c_str());
|
||||
EXPECT_STREQ("int*", dst.kernelArgInfo[0].metadataExtended->type.c_str());
|
||||
EXPECT_STREQ("const", dst.kernelArgInfo[0].metadataExtended->typeQualifiers.c_str());
|
||||
}
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenValidKernelWithNonDelimitedArgTypeThenUsesArgTypeAsIs) {
|
||||
PatchTokensTestData::ValidProgramWithKernelAndArg src;
|
||||
src.arg0TypeMutable[4] = '*';
|
||||
NEO::KernelInfo dst = {};
|
||||
NEO::populateKernelInfo(dst, src.kernels[0], 4, {});
|
||||
ASSERT_EQ(1U, dst.kernelArgInfo.size());
|
||||
EXPECT_STREQ("int**", dst.kernelArgInfo[0].metadataExtended->type.c_str());
|
||||
}
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenDataParameterStreamWithEmptySizeThenTokenIsIgnored) {
|
||||
std::vector<uint8_t> storage;
|
||||
auto src = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
iOpenCL::SPatchDataParameterStream dataParameterStream = {};
|
||||
src.tokens.dataParameterStream = &dataParameterStream;
|
||||
dataParameterStream.DataParameterStreamSize = 0U;
|
||||
NEO::KernelInfo dst;
|
||||
NEO::populateKernelInfo(dst, src, 4, {});
|
||||
EXPECT_EQ(nullptr, dst.crossThreadData);
|
||||
}
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenDataParameterStreamWithNonEmptySizeThenCrossthreadDataIsAllocated) {
|
||||
std::vector<uint8_t> storage;
|
||||
auto src = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
iOpenCL::SPatchDataParameterStream dataParameterStream = {};
|
||||
src.tokens.dataParameterStream = &dataParameterStream;
|
||||
dataParameterStream.DataParameterStreamSize = 256U;
|
||||
NEO::KernelInfo dst;
|
||||
NEO::populateKernelInfo(dst, src, 4, {});
|
||||
EXPECT_NE(nullptr, dst.crossThreadData);
|
||||
}
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenDataParameterStreamWhenTokensRequiringDeviceInfoPayloadConstantsArePresentThenCrossthreadDataIsProperlyPatched) {
|
||||
std::vector<uint8_t> storage;
|
||||
auto src = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
iOpenCL::SPatchDataParameterStream dataParameterStream = {};
|
||||
src.tokens.dataParameterStream = &dataParameterStream;
|
||||
dataParameterStream.DataParameterStreamSize = 256U;
|
||||
|
||||
NEO::DeviceInfoKernelPayloadConstants deviceInfoConstants;
|
||||
deviceInfoConstants.computeUnitsUsedForScratch = 128U;
|
||||
deviceInfoConstants.maxWorkGroupSize = 64U;
|
||||
std::unique_ptr<uint8_t> slm = std::make_unique<uint8_t>();
|
||||
deviceInfoConstants.slmWindow = slm.get();
|
||||
deviceInfoConstants.slmWindowSize = 512U;
|
||||
|
||||
iOpenCL::SPatchAllocateStatelessPrivateSurface privateSurface = {};
|
||||
privateSurface.PerThreadPrivateMemorySize = 8U;
|
||||
src.tokens.allocateStatelessPrivateSurface = &privateSurface;
|
||||
|
||||
iOpenCL::SPatchDataParameterBuffer privateMemorySize = {};
|
||||
privateMemorySize.Offset = 8U;
|
||||
src.tokens.crossThreadPayloadArgs.privateMemoryStatelessSize = &privateMemorySize;
|
||||
|
||||
iOpenCL::SPatchDataParameterBuffer localMemoryWindowStartVA = {};
|
||||
localMemoryWindowStartVA.Offset = 16U;
|
||||
src.tokens.crossThreadPayloadArgs.localMemoryStatelessWindowStartAddress = &localMemoryWindowStartVA;
|
||||
|
||||
iOpenCL::SPatchDataParameterBuffer localMemoryWindowsSize = {};
|
||||
localMemoryWindowsSize.Offset = 24U;
|
||||
src.tokens.crossThreadPayloadArgs.localMemoryStatelessWindowSize = &localMemoryWindowsSize;
|
||||
|
||||
iOpenCL::SPatchDataParameterBuffer maxWorkgroupSize = {};
|
||||
maxWorkgroupSize.Offset = 32U;
|
||||
src.tokens.crossThreadPayloadArgs.maxWorkGroupSize = &maxWorkgroupSize;
|
||||
|
||||
NEO::KernelInfo dst;
|
||||
NEO::populateKernelInfo(dst, src, 4, deviceInfoConstants);
|
||||
ASSERT_NE(nullptr, dst.crossThreadData);
|
||||
uint32_t expectedPrivateMemorySize = privateSurface.PerThreadPrivateMemorySize * deviceInfoConstants.computeUnitsUsedForScratch * src.tokens.executionEnvironment->LargestCompiledSIMDSize;
|
||||
EXPECT_EQ(expectedPrivateMemorySize, *reinterpret_cast<uint32_t *>(dst.crossThreadData + privateMemorySize.Offset));
|
||||
EXPECT_EQ(deviceInfoConstants.slmWindowSize, *reinterpret_cast<uint32_t *>(dst.crossThreadData + localMemoryWindowsSize.Offset));
|
||||
EXPECT_EQ(deviceInfoConstants.maxWorkGroupSize, *reinterpret_cast<uint32_t *>(dst.crossThreadData + maxWorkgroupSize.Offset));
|
||||
EXPECT_EQ(reinterpret_cast<uintptr_t>(deviceInfoConstants.slmWindow), *reinterpret_cast<uintptr_t *>(dst.crossThreadData + localMemoryWindowStartVA.Offset));
|
||||
}
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenDataParameterStreamWhenPrivateSurfaceIsNotAllocatedButPrivateSurfaceMemorySizePatchIsNeededThenPatchWithZero) {
|
||||
std::vector<uint8_t> storage;
|
||||
auto src = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
iOpenCL::SPatchDataParameterStream dataParameterStream = {};
|
||||
src.tokens.dataParameterStream = &dataParameterStream;
|
||||
dataParameterStream.DataParameterStreamSize = 256U;
|
||||
|
||||
NEO::DeviceInfoKernelPayloadConstants deviceInfoConstants;
|
||||
deviceInfoConstants.computeUnitsUsedForScratch = 128U;
|
||||
deviceInfoConstants.maxWorkGroupSize = 64U;
|
||||
std::unique_ptr<uint8_t> slm = std::make_unique<uint8_t>();
|
||||
deviceInfoConstants.slmWindow = slm.get();
|
||||
deviceInfoConstants.slmWindowSize = 512U;
|
||||
|
||||
iOpenCL::SPatchDataParameterBuffer privateMemorySize = {};
|
||||
privateMemorySize.Offset = 8U;
|
||||
src.tokens.crossThreadPayloadArgs.privateMemoryStatelessSize = &privateMemorySize;
|
||||
|
||||
NEO::KernelInfo dst;
|
||||
NEO::populateKernelInfo(dst, src, 4, deviceInfoConstants);
|
||||
ASSERT_NE(nullptr, dst.crossThreadData);
|
||||
uint32_t expectedPrivateMemorySize = 0U;
|
||||
EXPECT_EQ(expectedPrivateMemorySize, *reinterpret_cast<uint32_t *>(dst.crossThreadData + privateMemorySize.Offset));
|
||||
}
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenKernelWithGtpinInfoTokenThenKernelInfoIsProperlyPopulated) {
|
||||
std::vector<uint8_t> storage;
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens kernelTokens = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
iOpenCL::SPatchItemHeader gtpinInfo = {};
|
||||
gtpinInfo.Token = iOpenCL::PATCH_TOKEN_GTPIN_INFO;
|
||||
gtpinInfo.Size = sizeof(iOpenCL::SPatchItemHeader);
|
||||
kernelTokens.tokens.gtpinInfo = >pinInfo;
|
||||
|
||||
NEO::KernelInfo kernelInfo = {};
|
||||
NEO::populateKernelInfo(kernelInfo, kernelTokens, sizeof(uintptr_t), {});
|
||||
EXPECT_NE(nullptr, kernelInfo.igcInfoForGtpin);
|
||||
}
|
||||
|
||||
TEST(KernelInfoFromPatchTokens, GivenKernelWithGlobalObjectArgThenKernelInfoIsProperlyPopulated) {
|
||||
std::vector<uint8_t> storage;
|
||||
NEO::PatchTokenBinary::KernelFromPatchtokens kernelTokens = PatchTokensTestData::ValidEmptyKernel::create(storage);
|
||||
|
||||
iOpenCL::SPatchGlobalMemoryObjectKernelArgument globalMemArg = {};
|
||||
globalMemArg.Token = iOpenCL::PATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT;
|
||||
globalMemArg.Size = sizeof(iOpenCL::SPatchGlobalMemoryObjectKernelArgument);
|
||||
globalMemArg.ArgumentNumber = 1;
|
||||
globalMemArg.Offset = 0x40;
|
||||
|
||||
kernelTokens.tokens.kernelArgs.resize(2);
|
||||
kernelTokens.tokens.kernelArgs[1].objectArg = &globalMemArg;
|
||||
NEO::KernelInfo kernelInfo = {};
|
||||
NEO::populateKernelInfo(kernelInfo, kernelTokens, sizeof(uintptr_t), {});
|
||||
EXPECT_TRUE(kernelInfo.usesSsh);
|
||||
EXPECT_EQ(1U, kernelInfo.argumentsToPatchNum);
|
||||
ASSERT_EQ(2U, kernelInfo.kernelArgInfo.size());
|
||||
EXPECT_TRUE(kernelInfo.kernelArgInfo[1].isBuffer);
|
||||
ASSERT_EQ(1U, kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector.size());
|
||||
EXPECT_EQ(0U, kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector[0].crossthreadOffset);
|
||||
EXPECT_EQ(0U, kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector[0].sourceOffset);
|
||||
EXPECT_EQ(0U, kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector[0].size);
|
||||
EXPECT_EQ(globalMemArg.Offset, kernelInfo.kernelArgInfo[1].offsetHeap);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "runtime/execution_environment/execution_environment.h"
|
||||
#include "runtime/memory_manager/os_agnostic_memory_manager.h"
|
||||
#include "runtime/program/kernel_arg_info.h"
|
||||
#include "runtime/program/kernel_info.h"
|
||||
#include "unit_tests/fixtures/multi_root_device_fixture.h"
|
||||
#include "unit_tests/mocks/mock_execution_environment.h"
|
||||
@@ -18,20 +19,16 @@
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
TEST(KernelInfo, NonCopyable) {
|
||||
EXPECT_FALSE(std::is_move_constructible<KernelInfo>::value);
|
||||
EXPECT_FALSE(std::is_copy_constructible<KernelInfo>::value);
|
||||
TEST(KernelInfo, KernelInfoHasCopyMoveAssingmentDisabled) {
|
||||
static_assert(false == std::is_move_constructible<KernelInfo>::value, "");
|
||||
static_assert(false == std::is_copy_constructible<KernelInfo>::value, "");
|
||||
static_assert(false == std::is_move_assignable<KernelInfo>::value, "");
|
||||
static_assert(false == std::is_copy_assignable<KernelInfo>::value, "");
|
||||
}
|
||||
|
||||
TEST(KernelInfo, NonAssignable) {
|
||||
EXPECT_FALSE(std::is_move_assignable<KernelInfo>::value);
|
||||
EXPECT_FALSE(std::is_copy_assignable<KernelInfo>::value);
|
||||
}
|
||||
|
||||
TEST(KernelInfo, defaultBehavior) {
|
||||
auto pKernelInfo = std::make_unique<KernelInfo>();
|
||||
EXPECT_FALSE(pKernelInfo->usesSsh);
|
||||
EXPECT_FALSE(pKernelInfo->isValid);
|
||||
TEST(KernelInfo, whenDefaultConstructedThenUsesSshFlagIsNotSet) {
|
||||
KernelInfo kernelInfo;
|
||||
EXPECT_FALSE(kernelInfo.usesSsh);
|
||||
}
|
||||
|
||||
TEST(KernelInfo, decodeConstantMemoryKernelArgument) {
|
||||
@@ -99,13 +96,11 @@ TEST(KernelInfo, decodeImageKernelArgument) {
|
||||
EXPECT_TRUE(pKernelInfo->usesSsh);
|
||||
|
||||
const auto &argInfo = pKernelInfo->kernelArgInfo[argumentNumber];
|
||||
//EXPECT_EQ(???, argInfo.argSize);
|
||||
EXPECT_EQ(sizeof(cl_mem), static_cast<size_t>(argInfo.metadata.argByValSize));
|
||||
EXPECT_EQ(arg.Offset, argInfo.offsetHeap);
|
||||
EXPECT_TRUE(argInfo.isImage);
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_access_qualifier>(CL_KERNEL_ARG_ACCESS_READ_WRITE), argInfo.accessQualifier);
|
||||
//EXPECT_EQ(CL_KERNEL_ARG_ACCESS_READ_WRITE, argInfo.accessQualifier);
|
||||
//EXPECT_EQ(CL_KERNEL_ARG_ADDRESS_, argInfo.addressQualifier);
|
||||
//EXPECT_EQ(CL_KERNEL_ARG_TYPE_NONE, argInfo.typeQualifier);
|
||||
EXPECT_EQ(KernelArgMetadata::AccessQualifier::ReadWrite, argInfo.metadata.accessQualifier);
|
||||
EXPECT_TRUE(argInfo.metadata.typeQualifiers.empty());
|
||||
}
|
||||
|
||||
TEST(KernelInfoTest, givenKernelInfoWhenCreateKernelAllocationThenCopyWholeKernelHeapToKernelAllocation) {
|
||||
@@ -190,39 +185,23 @@ TEST(KernelInfo, decodeSamplerKernelArgument) {
|
||||
EXPECT_TRUE(pKernelInfo->usesSsh);
|
||||
}
|
||||
|
||||
typedef KernelInfo KernelInfo_resolveKernelInfo;
|
||||
TEST(KernelInfo_resolveKernelInfo, basicArgument) {
|
||||
auto pKernelInfo = std::make_unique<KernelInfo>();
|
||||
TEST(KernelInfo, whenStoringArgInfoThenMetadataIsProperlyPopulated) {
|
||||
KernelInfo kernelInfo;
|
||||
NEO::ArgTypeMetadata metadata;
|
||||
metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::WriteOnly;
|
||||
metadata.addressQualifier = NEO::KernelArgMetadata::AddressSpaceQualifier::Global;
|
||||
metadata.argByValSize = sizeof(void *);
|
||||
metadata.typeQualifiers.pipeQual = true;
|
||||
auto metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
auto metadataExtendedPtr = metadataExtended.get();
|
||||
kernelInfo.storeArgInfo(2, metadata, std::move(metadataExtended));
|
||||
|
||||
pKernelInfo->kernelArgInfo.resize(1);
|
||||
auto &kernelArgInfo = pKernelInfo->kernelArgInfo[0];
|
||||
kernelArgInfo.accessQualifierStr = "read_only";
|
||||
kernelArgInfo.addressQualifierStr = "__global";
|
||||
kernelArgInfo.typeQualifierStr = "restrict";
|
||||
|
||||
auto retVal = pKernelInfo->resolveKernelInfo();
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_access_qualifier>(CL_KERNEL_ARG_ACCESS_READ_ONLY), kernelArgInfo.accessQualifier);
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_address_qualifier>(CL_KERNEL_ARG_ADDRESS_GLOBAL), kernelArgInfo.addressQualifier);
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_type_qualifier>(CL_KERNEL_ARG_TYPE_RESTRICT), kernelArgInfo.typeQualifier);
|
||||
}
|
||||
|
||||
TEST(KernelInfo_resolveKernelInfo, complexArgumentType) {
|
||||
auto pKernelInfo = std::make_unique<KernelInfo>();
|
||||
|
||||
pKernelInfo->kernelArgInfo.resize(1);
|
||||
auto &kernelArgInfo = pKernelInfo->kernelArgInfo[0];
|
||||
kernelArgInfo.accessQualifierStr = "read_only";
|
||||
kernelArgInfo.addressQualifierStr = "__global";
|
||||
kernelArgInfo.typeQualifierStr = "restrict const";
|
||||
|
||||
auto retVal = pKernelInfo->resolveKernelInfo();
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_access_qualifier>(CL_KERNEL_ARG_ACCESS_READ_ONLY), kernelArgInfo.accessQualifier);
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_address_qualifier>(CL_KERNEL_ARG_ADDRESS_GLOBAL), kernelArgInfo.addressQualifier);
|
||||
EXPECT_EQ(static_cast<cl_kernel_arg_type_qualifier>(CL_KERNEL_ARG_TYPE_RESTRICT | CL_KERNEL_ARG_TYPE_CONST), kernelArgInfo.typeQualifier);
|
||||
ASSERT_EQ(3U, kernelInfo.kernelArgInfo.size());
|
||||
EXPECT_EQ(metadata.accessQualifier, kernelInfo.kernelArgInfo[2].metadata.accessQualifier);
|
||||
EXPECT_EQ(metadata.addressQualifier, kernelInfo.kernelArgInfo[2].metadata.addressQualifier);
|
||||
EXPECT_EQ(metadata.argByValSize, kernelInfo.kernelArgInfo[2].metadata.argByValSize);
|
||||
EXPECT_EQ(metadata.typeQualifiers.packed, kernelInfo.kernelArgInfo[2].metadata.typeQualifiers.packed);
|
||||
EXPECT_EQ(metadataExtendedPtr, kernelInfo.kernelArgInfo[2].metadataExtended.get());
|
||||
}
|
||||
|
||||
TEST(KernelInfo, givenKernelInfoWhenStoreTransformableArgThenArgInfoIsTransformable) {
|
||||
@@ -267,3 +246,15 @@ TEST_F(KernelInfoMultiRootDeviceTests, kernelAllocationHasCorrectRootDeviceIndex
|
||||
EXPECT_EQ(expectedRootDeviceIndex, allocation->getRootDeviceIndex());
|
||||
mockMemoryManager->checkGpuUsageAndDestroyGraphicsAllocations(allocation);
|
||||
}
|
||||
|
||||
TEST(KernelInfo, whenGetKernelNamesStringIsCalledThenNamesAreProperlyConcatenated) {
|
||||
ExecutionEnvironment execEnv;
|
||||
KernelInfo kernel1 = {};
|
||||
kernel1.name = "kern1";
|
||||
KernelInfo kernel2 = {};
|
||||
kernel2.name = "kern2";
|
||||
std::vector<KernelInfo *> kernelInfoArray;
|
||||
kernelInfoArray.push_back(&kernel1);
|
||||
kernelInfoArray.push_back(&kernel2);
|
||||
EXPECT_STREQ("kern1;kern2", concatenateKernelNames(kernelInfoArray).c_str());
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "core/memory_manager/allocations_list.h"
|
||||
#include "core/memory_manager/graphics_allocation.h"
|
||||
#include "core/memory_manager/unified_memory_manager.h"
|
||||
#include "core/program/program_info_from_patchtokens.h"
|
||||
#include "core/unit_tests/compiler_interface/linker_mock.h"
|
||||
#include "runtime/platform/platform.h"
|
||||
#include "runtime/program/program.h"
|
||||
@@ -184,12 +185,14 @@ TEST_F(ProgramDataTest, whenGlobalConstantsAreExportedThenAllocateSurfacesAsSvm)
|
||||
return;
|
||||
}
|
||||
|
||||
setupConstantAllocation();
|
||||
char constantData[128] = {};
|
||||
ProgramInfo programInfo;
|
||||
programInfo.globalConstants.initData = constantData;
|
||||
programInfo.globalConstants.size = sizeof(constantData);
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalConstants = true;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
programInfo.linkerInput = std::move(mockLinkerInput);
|
||||
this->pProgram->processProgramInfo(programInfo);
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getConstantSurface());
|
||||
EXPECT_NE(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getConstantSurface()->getGpuAddress())));
|
||||
@@ -200,15 +203,14 @@ TEST_F(ProgramDataTest, whenGlobalConstantsAreNotExportedThenAllocateSurfacesAsN
|
||||
return;
|
||||
}
|
||||
|
||||
setupConstantAllocation();
|
||||
char constantData[128] = {};
|
||||
ProgramInfo programInfo;
|
||||
programInfo.globalConstants.initData = constantData;
|
||||
programInfo.globalConstants.size = sizeof(constantData);
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalConstants = false;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
static_cast<MockProgram *>(pProgram)->context = nullptr;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
static_cast<MockProgram *>(pProgram)->context = pContext;
|
||||
programInfo.linkerInput = std::move(mockLinkerInput);
|
||||
this->pProgram->processProgramInfo(programInfo);
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getConstantSurface());
|
||||
EXPECT_EQ(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getConstantSurface()->getGpuAddress())));
|
||||
@@ -219,15 +221,19 @@ TEST_F(ProgramDataTest, whenGlobalConstantsAreExportedButContextUnavailableThenA
|
||||
return;
|
||||
}
|
||||
|
||||
setupConstantAllocation();
|
||||
char constantData[128] = {};
|
||||
ProgramInfo programInfo;
|
||||
programInfo.globalConstants.initData = constantData;
|
||||
programInfo.globalConstants.size = sizeof(constantData);
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalConstants = true;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
static_cast<MockProgram *>(pProgram)->context = nullptr;
|
||||
programInfo.linkerInput = std::move(mockLinkerInput);
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
pProgram->context = nullptr;
|
||||
|
||||
static_cast<MockProgram *>(pProgram)->context = pContext;
|
||||
this->pProgram->processProgramInfo(programInfo);
|
||||
|
||||
pProgram->context = pContext;
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getConstantSurface());
|
||||
EXPECT_EQ(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getConstantSurface()->getGpuAddress())));
|
||||
@@ -237,12 +243,14 @@ TEST_F(ProgramDataTest, whenGlobalVariablesAreExportedThenAllocateSurfacesAsSvm)
|
||||
if (this->pContext->getSVMAllocsManager() == nullptr) {
|
||||
return;
|
||||
}
|
||||
setupGlobalAllocation();
|
||||
char globalData[128] = {};
|
||||
ProgramInfo programInfo;
|
||||
programInfo.globalVariables.initData = globalData;
|
||||
programInfo.globalVariables.size = sizeof(globalData);
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalVariables = true;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
programInfo.linkerInput = std::move(mockLinkerInput);
|
||||
this->pProgram->processProgramInfo(programInfo);
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getGlobalSurface());
|
||||
EXPECT_NE(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getGlobalSurface()->getGpuAddress())));
|
||||
@@ -253,15 +261,19 @@ TEST_F(ProgramDataTest, whenGlobalVariablesAreExportedButContextUnavailableThenA
|
||||
return;
|
||||
}
|
||||
|
||||
setupGlobalAllocation();
|
||||
char globalData[128] = {};
|
||||
ProgramInfo programInfo;
|
||||
programInfo.globalVariables.initData = globalData;
|
||||
programInfo.globalVariables.size = sizeof(globalData);
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalVariables = true;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
static_cast<MockProgram *>(pProgram)->context = nullptr;
|
||||
programInfo.linkerInput = std::move(mockLinkerInput);
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
pProgram->context = nullptr;
|
||||
|
||||
static_cast<MockProgram *>(pProgram)->context = pContext;
|
||||
this->pProgram->processProgramInfo(programInfo);
|
||||
|
||||
pProgram->context = pContext;
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getGlobalSurface());
|
||||
EXPECT_EQ(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getGlobalSurface()->getGpuAddress())));
|
||||
@@ -272,15 +284,14 @@ TEST_F(ProgramDataTest, whenGlobalVariablesAreNotExportedThenAllocateSurfacesAsN
|
||||
return;
|
||||
}
|
||||
|
||||
setupGlobalAllocation();
|
||||
char globalData[128] = {};
|
||||
ProgramInfo programInfo;
|
||||
programInfo.globalVariables.initData = globalData;
|
||||
programInfo.globalVariables.size = sizeof(globalData);
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalVariables = false;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
static_cast<MockProgram *>(pProgram)->context = nullptr;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
static_cast<MockProgram *>(pProgram)->context = pContext;
|
||||
programInfo.linkerInput = std::move(mockLinkerInput);
|
||||
this->pProgram->processProgramInfo(programInfo);
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getGlobalSurface());
|
||||
EXPECT_EQ(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getGlobalSurface()->getGpuAddress())));
|
||||
@@ -342,167 +353,6 @@ TEST_F(ProgramDataTest, AllocateGlobalMemorySurfaceProgramBinaryInfo) {
|
||||
EXPECT_EQ(0, memcmp(globalValue, pProgram->getGlobalSurface()->getUnderlyingBuffer(), globalSize));
|
||||
}
|
||||
|
||||
TEST_F(ProgramDataTest, GlobalPointerProgramBinaryInfo) {
|
||||
char globalValue;
|
||||
char *pGlobalPointerValue = &globalValue;
|
||||
size_t globalPointerSize = sizeof(pGlobalPointerValue);
|
||||
char *ptr;
|
||||
|
||||
// simulate case when global surface was not allocated
|
||||
EXPECT_EQ(nullptr, pProgram->getGlobalSurface());
|
||||
|
||||
SPatchGlobalPointerProgramBinaryInfo globalPointer;
|
||||
globalPointer.Token = PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO;
|
||||
globalPointer.Size = sizeof(SPatchGlobalPointerProgramBinaryInfo);
|
||||
|
||||
globalPointer.GlobalBufferIndex = 0;
|
||||
globalPointer.GlobalPointerOffset = 0;
|
||||
globalPointer.BufferIndex = 0;
|
||||
globalPointer.BufferType = PROGRAM_SCOPE_GLOBAL_BUFFER;
|
||||
|
||||
cl_char *pGlobalPointer = new cl_char[globalPointer.Size];
|
||||
memcpy_s(pGlobalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo),
|
||||
&globalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pGlobalPointer;
|
||||
programPatchListSize = globalPointer.Size;
|
||||
|
||||
this->allowDecodeFailure = true;
|
||||
buildAndDecodeProgramPatchList();
|
||||
EXPECT_EQ(nullptr, pProgram->getGlobalSurface());
|
||||
EXPECT_EQ(CL_INVALID_BINARY, this->patchlistDecodeErrorCode);
|
||||
this->allowDecodeFailure = false;
|
||||
|
||||
delete[] pGlobalPointer;
|
||||
|
||||
// regular case - global surface exists
|
||||
SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo allocateGlobalMemorySurface;
|
||||
allocateGlobalMemorySurface.Token = PATCH_TOKEN_ALLOCATE_GLOBAL_MEMORY_SURFACE_PROGRAM_BINARY_INFO;
|
||||
allocateGlobalMemorySurface.Size = static_cast<uint32_t>(sizeof(SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo));
|
||||
allocateGlobalMemorySurface.GlobalBufferIndex = 0;
|
||||
allocateGlobalMemorySurface.InlineDataSize = static_cast<uint32_t>(globalPointerSize);
|
||||
|
||||
cl_char *pAllocateGlobalMemorySurface = new cl_char[allocateGlobalMemorySurface.Size + globalPointerSize];
|
||||
|
||||
memcpy_s(pAllocateGlobalMemorySurface,
|
||||
sizeof(SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo),
|
||||
&allocateGlobalMemorySurface,
|
||||
sizeof(SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo));
|
||||
memcpy_s((cl_char *)pAllocateGlobalMemorySurface + sizeof(allocateGlobalMemorySurface), globalPointerSize, &pGlobalPointerValue, globalPointerSize);
|
||||
|
||||
pProgramPatchList = pAllocateGlobalMemorySurface;
|
||||
programPatchListSize = static_cast<uint32_t>(allocateGlobalMemorySurface.Size + globalPointerSize);
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
EXPECT_NE(nullptr, pProgram->getGlobalSurface());
|
||||
|
||||
auto globalSurface = pProgram->getGlobalSurface();
|
||||
|
||||
globalSurface->setCpuPtrAndGpuAddress(globalSurface->getUnderlyingBuffer(), globalSurface->getGpuAddress() + 1);
|
||||
EXPECT_NE(reinterpret_cast<uint64_t>(globalSurface->getUnderlyingBuffer()), globalSurface->getGpuAddress());
|
||||
EXPECT_EQ(0, memcmp(&pGlobalPointerValue, globalSurface->getUnderlyingBuffer(), globalPointerSize));
|
||||
|
||||
delete[] pAllocateGlobalMemorySurface;
|
||||
|
||||
// global pointer to global surface - simulate invalid GlobalBufferIndex
|
||||
globalPointer.Token = PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO;
|
||||
globalPointer.Size = sizeof(SPatchGlobalPointerProgramBinaryInfo);
|
||||
|
||||
globalPointer.GlobalBufferIndex = 10;
|
||||
globalPointer.GlobalPointerOffset = 0;
|
||||
globalPointer.BufferIndex = 0;
|
||||
globalPointer.BufferType = PROGRAM_SCOPE_GLOBAL_BUFFER;
|
||||
|
||||
pGlobalPointer = new cl_char[globalPointer.Size];
|
||||
memcpy_s(pGlobalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo),
|
||||
&globalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pGlobalPointer;
|
||||
programPatchListSize = globalPointer.Size;
|
||||
this->allowDecodeFailure = true;
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
EXPECT_EQ(0, memcmp(&pGlobalPointerValue, globalSurface->getUnderlyingBuffer(), globalPointerSize));
|
||||
|
||||
delete[] pGlobalPointer;
|
||||
|
||||
// global pointer to global surface - simulate invalid BufferIndex
|
||||
globalPointer.Token = PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO;
|
||||
globalPointer.Size = sizeof(SPatchGlobalPointerProgramBinaryInfo);
|
||||
|
||||
globalPointer.GlobalBufferIndex = 0;
|
||||
globalPointer.GlobalPointerOffset = 0;
|
||||
globalPointer.BufferIndex = 10;
|
||||
globalPointer.BufferType = PROGRAM_SCOPE_GLOBAL_BUFFER;
|
||||
|
||||
pGlobalPointer = new cl_char[globalPointer.Size];
|
||||
memcpy_s(pGlobalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo),
|
||||
&globalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pGlobalPointer;
|
||||
programPatchListSize = globalPointer.Size;
|
||||
this->allowDecodeFailure = true;
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
EXPECT_EQ(0, memcmp(&pGlobalPointerValue, globalSurface->getUnderlyingBuffer(), globalPointerSize));
|
||||
|
||||
delete[] pGlobalPointer;
|
||||
|
||||
// global pointer to global surface - simulate invalid BufferType
|
||||
globalPointer.Token = PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO;
|
||||
globalPointer.Size = sizeof(SPatchGlobalPointerProgramBinaryInfo);
|
||||
|
||||
globalPointer.GlobalBufferIndex = 0;
|
||||
globalPointer.GlobalPointerOffset = 0;
|
||||
globalPointer.BufferIndex = 0;
|
||||
globalPointer.BufferType = PROGRAM_SCOPE_CONSTANT_BUFFER;
|
||||
|
||||
pGlobalPointer = new cl_char[globalPointer.Size];
|
||||
memcpy_s(pGlobalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo),
|
||||
&globalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pGlobalPointer;
|
||||
programPatchListSize = globalPointer.Size;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
EXPECT_EQ(0, memcmp(&pGlobalPointerValue, globalSurface->getUnderlyingBuffer(), globalPointerSize));
|
||||
|
||||
delete[] pGlobalPointer;
|
||||
|
||||
// regular case - global pointer to global surface - all parameters valid
|
||||
this->pProgram->skipValidationOfBinary = true;
|
||||
this->allowDecodeFailure = false;
|
||||
globalPointer.Token = PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO;
|
||||
globalPointer.Size = sizeof(SPatchGlobalPointerProgramBinaryInfo);
|
||||
|
||||
globalPointer.GlobalBufferIndex = 0;
|
||||
globalPointer.GlobalPointerOffset = 0;
|
||||
globalPointer.BufferIndex = 0;
|
||||
globalPointer.BufferType = PROGRAM_SCOPE_GLOBAL_BUFFER;
|
||||
|
||||
pGlobalPointer = new cl_char[globalPointer.Size];
|
||||
memcpy_s(pGlobalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo),
|
||||
&globalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo));
|
||||
|
||||
pProgramPatchList = (void *)pGlobalPointer;
|
||||
programPatchListSize = globalPointer.Size;
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
if (!globalSurface->is32BitAllocation()) {
|
||||
EXPECT_NE(0, memcmp(&pGlobalPointerValue, globalSurface->getUnderlyingBuffer(), globalPointerSize));
|
||||
ptr = pGlobalPointerValue + (globalSurface->getGpuAddressToPatch());
|
||||
EXPECT_EQ(0, memcmp(&ptr, globalSurface->getUnderlyingBuffer(), globalPointerSize));
|
||||
}
|
||||
delete[] pGlobalPointer;
|
||||
}
|
||||
|
||||
TEST_F(ProgramDataTest, Given32BitDeviceWhenGlobalMemorySurfaceIsPresentThenItHas32BitStorage) {
|
||||
char globalValue[] = "55667788";
|
||||
size_t globalSize = strlen(globalValue) + 1;
|
||||
@@ -539,188 +389,6 @@ TEST_F(ProgramDataTest, Given32BitDeviceWhenGlobalMemorySurfaceIsPresentThenItHa
|
||||
delete[] pAllocateGlobalMemorySurface;
|
||||
}
|
||||
|
||||
TEST_F(ProgramDataTest, ConstantPointerProgramBinaryInfo) {
|
||||
const char *pConstantData = "01234567";
|
||||
size_t constantDataLen = strlen(pConstantData);
|
||||
|
||||
// simulate case when constant surface was not allocated
|
||||
EXPECT_EQ(nullptr, pProgram->getConstantSurface());
|
||||
|
||||
SPatchConstantPointerProgramBinaryInfo constantPointer;
|
||||
constantPointer.Token = PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO;
|
||||
constantPointer.Size = sizeof(SPatchConstantPointerProgramBinaryInfo);
|
||||
constantPointer.ConstantBufferIndex = 0;
|
||||
constantPointer.ConstantPointerOffset = 0;
|
||||
constantPointer.BufferIndex = 0;
|
||||
constantPointer.BufferType = PROGRAM_SCOPE_CONSTANT_BUFFER;
|
||||
|
||||
cl_char *pConstantPointer = new cl_char[constantPointer.Size];
|
||||
memcpy_s(pConstantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo),
|
||||
&constantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pConstantPointer;
|
||||
programPatchListSize = constantPointer.Size;
|
||||
|
||||
this->allowDecodeFailure = true;
|
||||
buildAndDecodeProgramPatchList();
|
||||
EXPECT_EQ(nullptr, pProgram->getConstantSurface());
|
||||
EXPECT_EQ(CL_INVALID_BINARY, this->patchlistDecodeErrorCode);
|
||||
this->allowDecodeFailure = false;
|
||||
|
||||
delete[] pConstantPointer;
|
||||
|
||||
// regular case - constant surface exists
|
||||
SPatchAllocateConstantMemorySurfaceProgramBinaryInfo allocateConstMemorySurface;
|
||||
allocateConstMemorySurface.Token = PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO;
|
||||
// note : + sizeof(uint64_t) is to accomodate for constant buffer offset
|
||||
allocateConstMemorySurface.Size = static_cast<uint32_t>(sizeof(SPatchAllocateConstantMemorySurfaceProgramBinaryInfo));
|
||||
|
||||
allocateConstMemorySurface.ConstantBufferIndex = 0;
|
||||
allocateConstMemorySurface.InlineDataSize = static_cast<uint32_t>(constantDataLen + sizeof(uint64_t));
|
||||
|
||||
auto pAllocateConstMemorySurface = std::unique_ptr<char>(new char[allocateConstMemorySurface.Size + allocateConstMemorySurface.InlineDataSize]);
|
||||
|
||||
// copy the token header
|
||||
memcpy_s(pAllocateConstMemorySurface.get(),
|
||||
sizeof(SPatchAllocateConstantMemorySurfaceProgramBinaryInfo),
|
||||
&allocateConstMemorySurface,
|
||||
sizeof(SPatchAllocateConstantMemorySurfaceProgramBinaryInfo));
|
||||
|
||||
// copy the constant data
|
||||
memcpy_s((char *)pAllocateConstMemorySurface.get() + sizeof(allocateConstMemorySurface), constantDataLen, pConstantData, constantDataLen);
|
||||
|
||||
// zero-out the constant buffer offset (will be patched during gen binary decoding)
|
||||
size_t constantBufferOffsetPatchOffset = constantDataLen;
|
||||
*(uint64_t *)((char *)pAllocateConstMemorySurface.get() + sizeof(allocateConstMemorySurface) + constantBufferOffsetPatchOffset) = 0U;
|
||||
|
||||
pProgramPatchList = (void *)pAllocateConstMemorySurface.get();
|
||||
programPatchListSize = allocateConstMemorySurface.Size + allocateConstMemorySurface.InlineDataSize;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
EXPECT_NE(nullptr, pProgram->getConstantSurface());
|
||||
|
||||
auto constantSurface = pProgram->getConstantSurface();
|
||||
constantSurface->setCpuPtrAndGpuAddress(constantSurface->getUnderlyingBuffer(), constantSurface->getGpuAddress() + 1);
|
||||
EXPECT_NE(reinterpret_cast<uint64_t>(constantSurface->getUnderlyingBuffer()), constantSurface->getGpuAddress());
|
||||
|
||||
EXPECT_EQ(0, memcmp(pConstantData, constantSurface->getUnderlyingBuffer(), constantDataLen));
|
||||
// there was no PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO, so constant buffer offset should be still 0
|
||||
EXPECT_EQ(0U, *reinterpret_cast<uint64_t *>(static_cast<char *>(constantSurface->getUnderlyingBuffer()) + constantBufferOffsetPatchOffset));
|
||||
// once finally constant buffer offset gets patched - the patch value depends on the bitness of the compute kernel
|
||||
auto patchOffsetValueStorage = std::unique_ptr<uint64_t>(new uint64_t); // 4bytes for 32-bit compute kernel, full 8byte for 64-bit compute kernel
|
||||
uint64_t *patchOffsetValue = patchOffsetValueStorage.get();
|
||||
if (constantSurface->is32BitAllocation() || (sizeof(void *) == 4)) {
|
||||
reinterpret_cast<uint32_t *>(patchOffsetValue)[0] = static_cast<uint32_t>(constantSurface->getGpuAddressToPatch());
|
||||
reinterpret_cast<uint32_t *>(patchOffsetValue)[1] = 0; // just pad with 0
|
||||
} else {
|
||||
// full 8 bytes
|
||||
*reinterpret_cast<uint64_t *>(patchOffsetValue) = constantSurface->getGpuAddressToPatch();
|
||||
}
|
||||
|
||||
// constant pointer to constant surface - simulate invalid GlobalBufferIndex
|
||||
constantPointer.Token = PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO;
|
||||
constantPointer.Size = sizeof(SPatchConstantPointerProgramBinaryInfo);
|
||||
constantPointer.ConstantBufferIndex = 10;
|
||||
constantPointer.ConstantPointerOffset = 0;
|
||||
constantPointer.BufferIndex = 0;
|
||||
constantPointer.BufferType = PROGRAM_SCOPE_CONSTANT_BUFFER;
|
||||
|
||||
pConstantPointer = new cl_char[constantPointer.Size];
|
||||
memcpy_s(pConstantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo),
|
||||
&constantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pConstantPointer;
|
||||
programPatchListSize = constantPointer.Size;
|
||||
|
||||
this->allowDecodeFailure = true;
|
||||
buildAndDecodeProgramPatchList();
|
||||
EXPECT_EQ(0, memcmp(pConstantData, constantSurface->getUnderlyingBuffer(), constantDataLen));
|
||||
// check that constant pointer offset was not patched
|
||||
EXPECT_EQ(0U, *reinterpret_cast<uint64_t *>(static_cast<char *>(constantSurface->getUnderlyingBuffer()) + constantBufferOffsetPatchOffset));
|
||||
// reset the constant pointer offset
|
||||
*reinterpret_cast<uint64_t *>(static_cast<char *>(constantSurface->getUnderlyingBuffer()) + constantBufferOffsetPatchOffset) = 0U;
|
||||
|
||||
delete[] pConstantPointer;
|
||||
|
||||
// constant pointer to constant surface - simulate invalid BufferIndex
|
||||
constantPointer.Token = PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO;
|
||||
constantPointer.Size = sizeof(SPatchConstantPointerProgramBinaryInfo);
|
||||
constantPointer.ConstantBufferIndex = 0;
|
||||
constantPointer.ConstantPointerOffset = 0;
|
||||
constantPointer.BufferIndex = 10;
|
||||
constantPointer.BufferType = PROGRAM_SCOPE_CONSTANT_BUFFER;
|
||||
|
||||
pConstantPointer = new cl_char[constantPointer.Size];
|
||||
memcpy_s(pConstantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo),
|
||||
&constantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pConstantPointer;
|
||||
programPatchListSize = constantPointer.Size;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
EXPECT_EQ(0, memcmp(pConstantData, constantSurface->getUnderlyingBuffer(), constantDataLen));
|
||||
// check that constant pointer offset was not patched
|
||||
EXPECT_EQ(0U, *reinterpret_cast<uint64_t *>(static_cast<char *>(constantSurface->getUnderlyingBuffer()) + constantBufferOffsetPatchOffset));
|
||||
// reset the constant pointer offset
|
||||
*(uint64_t *)((char *)constantSurface->getUnderlyingBuffer() + constantBufferOffsetPatchOffset) = 0U;
|
||||
|
||||
delete[] pConstantPointer;
|
||||
|
||||
// constant pointer to constant surface - simulate invalid BufferType
|
||||
constantPointer.Token = PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO;
|
||||
constantPointer.Size = sizeof(SPatchConstantPointerProgramBinaryInfo);
|
||||
constantPointer.ConstantBufferIndex = 0;
|
||||
constantPointer.ConstantPointerOffset = 0;
|
||||
constantPointer.BufferIndex = 0;
|
||||
constantPointer.BufferType = PROGRAM_SCOPE_GLOBAL_BUFFER;
|
||||
|
||||
pConstantPointer = new cl_char[constantPointer.Size];
|
||||
memcpy_s(pConstantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo),
|
||||
&constantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pConstantPointer;
|
||||
programPatchListSize = constantPointer.Size;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
EXPECT_EQ(0, memcmp(pConstantData, constantSurface->getUnderlyingBuffer(), constantDataLen));
|
||||
// check that constant pointer offset was not patched
|
||||
EXPECT_EQ(0U, *reinterpret_cast<uint64_t *>(static_cast<char *>(constantSurface->getUnderlyingBuffer()) + constantBufferOffsetPatchOffset));
|
||||
// reset the constant pointer offset
|
||||
*reinterpret_cast<uint64_t *>(static_cast<char *>(constantSurface->getUnderlyingBuffer()) + constantBufferOffsetPatchOffset) = 0U;
|
||||
|
||||
delete[] pConstantPointer;
|
||||
|
||||
// regular case - constant pointer to constant surface - all parameters valid
|
||||
constantPointer.Token = PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO;
|
||||
constantPointer.Size = sizeof(SPatchConstantPointerProgramBinaryInfo);
|
||||
constantPointer.ConstantBufferIndex = 0;
|
||||
constantPointer.ConstantPointerOffset = constantDataLen;
|
||||
constantPointer.BufferIndex = 0;
|
||||
constantPointer.BufferType = PROGRAM_SCOPE_CONSTANT_BUFFER;
|
||||
|
||||
pConstantPointer = new cl_char[constantPointer.Size];
|
||||
memcpy_s(pConstantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo),
|
||||
&constantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pConstantPointer;
|
||||
programPatchListSize = constantPointer.Size;
|
||||
this->pProgram->skipValidationOfBinary = true;
|
||||
this->allowDecodeFailure = false;
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
EXPECT_EQ(0, memcmp(pConstantData, constantSurface->getUnderlyingBuffer(), constantDataLen));
|
||||
// check that constant pointer offset was patched
|
||||
EXPECT_EQ(*reinterpret_cast<uint64_t *>(patchOffsetValue), *reinterpret_cast<uint64_t *>(static_cast<char *>(constantSurface->getUnderlyingBuffer()) + constantBufferOffsetPatchOffset));
|
||||
|
||||
delete[] pConstantPointer;
|
||||
}
|
||||
|
||||
TEST(ProgramScopeMetadataTest, WhenPatchingGlobalSurfaceThenPickProperSourceBuffer) {
|
||||
MockExecutionEnvironment execEnv;
|
||||
MockClDevice device{new MockDevice};
|
||||
@@ -730,9 +398,11 @@ TEST(ProgramScopeMetadataTest, WhenPatchingGlobalSurfaceThenPickProperSourceBuff
|
||||
decodedProgram.constantPointerMutable->ConstantPointerOffset = 0U;
|
||||
memset(decodedProgram.globalSurfMutable + 1, 0U, sizeof(uintptr_t));
|
||||
memset(decodedProgram.constSurfMutable + 1, 0U, sizeof(uintptr_t));
|
||||
ProgramInfo programInfo;
|
||||
MockProgram program(execEnv);
|
||||
program.pDevice = &device;
|
||||
program.processProgramScopeMetadata(decodedProgram);
|
||||
NEO::populateProgramInfo(programInfo, decodedProgram, DeviceInfoKernelPayloadConstants{});
|
||||
program.processProgramInfo(programInfo);
|
||||
ASSERT_NE(nullptr, program.globalSurface);
|
||||
ASSERT_NE(nullptr, program.constantSurface);
|
||||
ASSERT_NE(nullptr, program.globalSurface->getUnderlyingBuffer());
|
||||
@@ -750,22 +420,15 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeConstantB
|
||||
|
||||
// simulate case when constant surface was not allocated
|
||||
EXPECT_EQ(nullptr, prog->getConstantSurface());
|
||||
|
||||
SPatchConstantPointerProgramBinaryInfo constantPointer;
|
||||
constantPointer.Token = PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO;
|
||||
constantPointer.Size = sizeof(SPatchConstantPointerProgramBinaryInfo);
|
||||
constantPointer.ConstantBufferIndex = 0;
|
||||
constantPointer.ConstantPointerOffset = 0;
|
||||
constantPointer.BufferIndex = 0;
|
||||
constantPointer.BufferType = PROGRAM_SCOPE_CONSTANT_BUFFER;
|
||||
|
||||
auto pConstantPointer = std::unique_ptr<char[]>(new char[constantPointer.Size]);
|
||||
memcpy_s(pConstantPointer.get(),
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo),
|
||||
&constantPointer,
|
||||
sizeof(SPatchConstantPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pConstantPointer.get();
|
||||
programPatchListSize = constantPointer.Size;
|
||||
ProgramInfo programInfo;
|
||||
programInfo.prepareLinkerInputStorage();
|
||||
NEO::LinkerInput::RelocationInfo relocInfo;
|
||||
relocInfo.relocationSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocInfo.symbolSegment = NEO::SegmentType::GlobalConstants;
|
||||
relocInfo.offset = 0U;
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
programInfo.linkerInput->addDataRelocationInfo(relocInfo);
|
||||
programInfo.linkerInput->setPointerSize(LinkerInput::Traits::PointerSize::Ptr32bit);
|
||||
|
||||
MockBuffer constantSurface;
|
||||
ASSERT_LT(8U, constantSurface.getSize());
|
||||
@@ -775,8 +438,9 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeConstantB
|
||||
uint32_t sentinel = 0x17192329U;
|
||||
constantSurfaceStorage[0] = 0U;
|
||||
constantSurfaceStorage[1] = sentinel;
|
||||
this->pProgram->skipValidationOfBinary = true;
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
pProgram->linkerInput = std::move(programInfo.linkerInput);
|
||||
pProgram->linkBinary();
|
||||
uint32_t expectedAddr = static_cast<uint32_t>(constantSurface.getGraphicsAllocation()->getGpuAddressToPatch());
|
||||
EXPECT_EQ(expectedAddr, constantSurfaceStorage[0]);
|
||||
EXPECT_EQ(sentinel, constantSurfaceStorage[1]);
|
||||
@@ -794,21 +458,15 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeGlobalPoi
|
||||
// simulate case when constant surface was not allocated
|
||||
EXPECT_EQ(nullptr, prog->getConstantSurface());
|
||||
|
||||
SPatchGlobalPointerProgramBinaryInfo globalPointer;
|
||||
globalPointer.Token = PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO;
|
||||
globalPointer.Size = sizeof(SPatchConstantPointerProgramBinaryInfo);
|
||||
globalPointer.GlobalBufferIndex = 0;
|
||||
globalPointer.GlobalPointerOffset = 0;
|
||||
globalPointer.BufferIndex = 0;
|
||||
globalPointer.BufferType = PROGRAM_SCOPE_GLOBAL_BUFFER;
|
||||
|
||||
auto pGlobalPointer = std::unique_ptr<char[]>(new char[globalPointer.Size]);
|
||||
memcpy_s(pGlobalPointer.get(),
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo),
|
||||
&globalPointer,
|
||||
sizeof(SPatchGlobalPointerProgramBinaryInfo));
|
||||
pProgramPatchList = (void *)pGlobalPointer.get();
|
||||
programPatchListSize = globalPointer.Size;
|
||||
ProgramInfo programInfo;
|
||||
programInfo.prepareLinkerInputStorage();
|
||||
NEO::LinkerInput::RelocationInfo relocInfo;
|
||||
relocInfo.relocationSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocInfo.symbolSegment = NEO::SegmentType::GlobalVariables;
|
||||
relocInfo.offset = 0U;
|
||||
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
programInfo.linkerInput->addDataRelocationInfo(relocInfo);
|
||||
programInfo.linkerInput->setPointerSize(LinkerInput::Traits::PointerSize::Ptr32bit);
|
||||
|
||||
MockBuffer globalSurface;
|
||||
ASSERT_LT(8U, globalSurface.getSize());
|
||||
@@ -819,7 +477,9 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeGlobalPoi
|
||||
globalSurfaceStorage[0] = 0U;
|
||||
globalSurfaceStorage[1] = sentinel;
|
||||
this->pProgram->skipValidationOfBinary = true;
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
pProgram->linkerInput = std::move(programInfo.linkerInput);
|
||||
pProgram->linkBinary();
|
||||
uint32_t expectedAddr = static_cast<uint32_t>(globalSurface.getGraphicsAllocation()->getGpuAddressToPatch());
|
||||
EXPECT_EQ(expectedAddr, globalSurfaceStorage[0]);
|
||||
EXPECT_EQ(sentinel, globalSurfaceStorage[1]);
|
||||
@@ -882,22 +542,11 @@ TEST(ProgramLinkBinaryTest, whenLinkerUnresolvedExternalThenLinkFailedAndBuildLo
|
||||
EXPECT_THAT(buildLog, ::testing::HasSubstr(expectedError));
|
||||
}
|
||||
|
||||
TEST(ProgramLinkBinaryTest, whenPrepareLinkerInputStorageGetsCalledTwiceThenLinkerInputStorageIsReused) {
|
||||
ExecutionEnvironment execEnv;
|
||||
MockProgram program{execEnv};
|
||||
EXPECT_EQ(nullptr, program.linkerInput);
|
||||
program.prepareLinkerInputStorage();
|
||||
EXPECT_NE(nullptr, program.linkerInput);
|
||||
auto prevLinkerInput = program.getLinkerInput();
|
||||
program.prepareLinkerInputStorage();
|
||||
EXPECT_EQ(prevLinkerInput, program.linkerInput.get());
|
||||
}
|
||||
|
||||
TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) {
|
||||
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
|
||||
linkerInput->symbols["A"] = NEO::SymbolInfo{4U, 4U, NEO::SymbolInfo::GlobalVariable};
|
||||
linkerInput->symbols["B"] = NEO::SymbolInfo{8U, 4U, NEO::SymbolInfo::GlobalConstant};
|
||||
linkerInput->symbols["C"] = NEO::SymbolInfo{16U, 4U, NEO::SymbolInfo::Function};
|
||||
linkerInput->symbols["A"] = NEO::SymbolInfo{4U, 4U, NEO::SegmentType::GlobalVariables};
|
||||
linkerInput->symbols["B"] = NEO::SymbolInfo{8U, 4U, NEO::SegmentType::GlobalConstants};
|
||||
linkerInput->symbols["C"] = NEO::SymbolInfo{16U, 4U, NEO::SegmentType::Instructions};
|
||||
|
||||
auto relocationType = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
linkerInput->relocations.push_back({NEO::LinkerInput::RelocationInfo{"A", 8U, relocationType},
|
||||
@@ -951,8 +600,8 @@ TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) {
|
||||
|
||||
TEST_F(ProgramDataTest, whenRelocationsAreNotNeededThenIsaIsPreserved) {
|
||||
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
|
||||
linkerInput->symbols["A"] = NEO::SymbolInfo{4U, 4U, NEO::SymbolInfo::GlobalVariable};
|
||||
linkerInput->symbols["B"] = NEO::SymbolInfo{8U, 4U, NEO::SymbolInfo::GlobalConstant};
|
||||
linkerInput->symbols["A"] = NEO::SymbolInfo{4U, 4U, NEO::SegmentType::GlobalVariables};
|
||||
linkerInput->symbols["B"] = NEO::SymbolInfo{8U, 4U, NEO::SegmentType::GlobalConstants};
|
||||
|
||||
NEO::ExecutionEnvironment env;
|
||||
MockProgram program{env};
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
#include "runtime/memory_manager/surface.h"
|
||||
#include "runtime/program/create.inl"
|
||||
#include "test.h"
|
||||
#include "unit_tests/compiler_interface/patchtokens_tests.h"
|
||||
#include "unit_tests/fixtures/device_fixture.h"
|
||||
#include "unit_tests/fixtures/multi_root_device_fixture.h"
|
||||
#include "unit_tests/global_environment.h"
|
||||
#include "unit_tests/helpers/kernel_binary_helper.h"
|
||||
#include "unit_tests/libult/ult_command_stream_receiver.h"
|
||||
#include "unit_tests/mocks/mock_graphics_allocation.h"
|
||||
#include "unit_tests/mocks/mock_kernel.h"
|
||||
#include "unit_tests/mocks/mock_program.h"
|
||||
#include "unit_tests/program/program_from_binary.h"
|
||||
@@ -606,6 +608,23 @@ TEST_P(ProgramFromBinaryTest, givenProgramWhenItIsBeingBuildThenItContainsGraphi
|
||||
EXPECT_EQ(GmmHelper::decanonize(graphicsAllocation->getGpuBaseAddress()), pProgram->getDevice(0).getMemoryManager()->getInternalHeapBaseAddress(rootDeviceIndex));
|
||||
}
|
||||
|
||||
TEST_P(ProgramFromBinaryTest, whenProgramIsBeingRebuildThenOutdatedGlobalBuffersAreFreed) {
|
||||
cl_device_id device = pClDevice;
|
||||
pProgram->build(1, &device, nullptr, nullptr, nullptr, true);
|
||||
EXPECT_EQ(nullptr, pProgram->constantSurface);
|
||||
EXPECT_EQ(nullptr, pProgram->globalSurface);
|
||||
|
||||
pProgram->constantSurface = new MockGraphicsAllocation();
|
||||
pProgram->processGenBinary();
|
||||
EXPECT_EQ(nullptr, pProgram->constantSurface);
|
||||
EXPECT_EQ(nullptr, pProgram->globalSurface);
|
||||
|
||||
pProgram->globalSurface = new MockGraphicsAllocation();
|
||||
pProgram->processGenBinary();
|
||||
EXPECT_EQ(nullptr, pProgram->constantSurface);
|
||||
EXPECT_EQ(nullptr, pProgram->globalSurface);
|
||||
}
|
||||
|
||||
TEST_P(ProgramFromBinaryTest, givenProgramWhenCleanKernelInfoIsCalledThenKernelAllocationIsFreed) {
|
||||
cl_device_id device = pClDevice;
|
||||
pProgram->build(1, &device, nullptr, nullptr, nullptr, true);
|
||||
@@ -1916,203 +1935,18 @@ TEST_F(ProgramTests, ProgramFromGenBinaryWithNullcontext) {
|
||||
delete pProgram;
|
||||
}
|
||||
|
||||
TEST_F(ProgramTests, ProgramFromGenBinaryWithPATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT) {
|
||||
cl_int retVal = CL_INVALID_BINARY;
|
||||
char genBin[1024] = {1, 2, 3, 4, 5, 6, 7, 8, 9, '\0'};
|
||||
size_t binSize = 10;
|
||||
|
||||
MockProgram *pProgram = Program::createFromGenBinary<MockProgram>(*pDevice->getExecutionEnvironment(), nullptr, &genBin[0], binSize, false, &retVal);
|
||||
EXPECT_NE(nullptr, pProgram);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ((uint32_t)CL_PROGRAM_BINARY_TYPE_EXECUTABLE, (uint32_t)pProgram->getProgramBinaryType());
|
||||
|
||||
cl_device_id deviceId = pContext->getDevice(0);
|
||||
ClDevice *pDevice = castToObject<ClDevice>(deviceId);
|
||||
char *pBin = &genBin[0];
|
||||
retVal = CL_INVALID_BINARY;
|
||||
binSize = 0;
|
||||
|
||||
// Prepare simple program binary containing patch token PATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT
|
||||
SProgramBinaryHeader *pBHdr = (SProgramBinaryHeader *)pBin;
|
||||
pBHdr->Magic = iOpenCL::MAGIC_CL;
|
||||
pBHdr->Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
pBHdr->Device = pDevice->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
pBHdr->GPUPointerSizeInBytes = 8;
|
||||
pBHdr->NumberOfKernels = 1;
|
||||
pBHdr->SteppingId = 0;
|
||||
pBHdr->PatchListSize = 0;
|
||||
pBin += sizeof(SProgramBinaryHeader);
|
||||
binSize += sizeof(SProgramBinaryHeader);
|
||||
|
||||
SKernelBinaryHeaderCommon *pKHdr = (SKernelBinaryHeaderCommon *)pBin;
|
||||
pKHdr->CheckSum = 0;
|
||||
pKHdr->ShaderHashCode = 0;
|
||||
pKHdr->KernelNameSize = 8;
|
||||
pKHdr->PatchListSize = sizeof(iOpenCL::SPatchGlobalMemoryObjectKernelArgument);
|
||||
pKHdr->KernelHeapSize = 0;
|
||||
pKHdr->GeneralStateHeapSize = 0;
|
||||
pKHdr->DynamicStateHeapSize = 0;
|
||||
pKHdr->SurfaceStateHeapSize = 0;
|
||||
pKHdr->KernelUnpaddedSize = 0;
|
||||
pBin += sizeof(SKernelBinaryHeaderCommon);
|
||||
binSize += sizeof(SKernelBinaryHeaderCommon);
|
||||
|
||||
strcpy(pBin, "TstCopy");
|
||||
pBin += pKHdr->KernelNameSize;
|
||||
binSize += pKHdr->KernelNameSize;
|
||||
|
||||
SPatchGlobalMemoryObjectKernelArgument *pPatch = (SPatchGlobalMemoryObjectKernelArgument *)pBin;
|
||||
pPatch->Token = iOpenCL::PATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT;
|
||||
pPatch->Size = sizeof(iOpenCL::SPatchGlobalMemoryObjectKernelArgument);
|
||||
pPatch->ArgumentNumber = 0;
|
||||
pPatch->Offset = 0x40;
|
||||
pPatch->LocationIndex = iOpenCL::INVALID_INDEX;
|
||||
pPatch->LocationIndex2 = iOpenCL::INVALID_INDEX;
|
||||
binSize += pPatch->Size;
|
||||
pBin += pPatch->Size;
|
||||
|
||||
ArrayRef<const uint8_t> kernelBlob(reinterpret_cast<uint8_t *>(pKHdr), reinterpret_cast<uint8_t *>(pBin));
|
||||
pKHdr->CheckSum = PatchTokenBinary::calcKernelChecksum(kernelBlob);
|
||||
|
||||
// Decode prepared program binary
|
||||
pProgram->genBinary = makeCopy(&genBin[0], binSize);
|
||||
pProgram->genBinarySize = binSize;
|
||||
retVal = pProgram->processGenBinary();
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
delete pProgram;
|
||||
}
|
||||
|
||||
TEST_F(ProgramTests, givenProgramFromGenBinaryWhenSLMSizeIsBiggerThenDeviceLimitThenReturnError) {
|
||||
cl_int retVal = CL_INVALID_BINARY;
|
||||
char genBin[1024] = {1, 2, 3, 4, 5, 6, 7, 8, 9, '\0'};
|
||||
size_t binSize = 10;
|
||||
|
||||
auto program = std::unique_ptr<MockProgram>(Program::createFromGenBinary<MockProgram>(*pDevice->getExecutionEnvironment(), nullptr, &genBin[0], binSize, false, &retVal));
|
||||
|
||||
EXPECT_NE(nullptr, program.get());
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ((uint32_t)CL_PROGRAM_BINARY_TYPE_EXECUTABLE, (uint32_t)program->getProgramBinaryType());
|
||||
|
||||
cl_device_id deviceId = pContext->getDevice(0);
|
||||
ClDevice *pDevice = castToObject<ClDevice>(deviceId);
|
||||
program->setDevice(pDevice);
|
||||
char *pBin = &genBin[0];
|
||||
retVal = CL_INVALID_BINARY;
|
||||
binSize = 0;
|
||||
|
||||
// Prepare simple program binary containing patch token PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE
|
||||
SProgramBinaryHeader *pBHdr = (SProgramBinaryHeader *)pBin;
|
||||
pBHdr->Magic = iOpenCL::MAGIC_CL;
|
||||
pBHdr->Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
pBHdr->Device = pDevice->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
pBHdr->GPUPointerSizeInBytes = 8;
|
||||
pBHdr->NumberOfKernels = 1;
|
||||
pBHdr->SteppingId = 0;
|
||||
pBHdr->PatchListSize = 0;
|
||||
pBin += sizeof(SProgramBinaryHeader);
|
||||
binSize += sizeof(SProgramBinaryHeader);
|
||||
|
||||
SKernelBinaryHeaderCommon *pKHdr = (SKernelBinaryHeaderCommon *)pBin;
|
||||
pKHdr->CheckSum = 0;
|
||||
pKHdr->ShaderHashCode = 0;
|
||||
pKHdr->KernelNameSize = 8;
|
||||
pKHdr->PatchListSize = sizeof(iOpenCL::SPatchAllocateLocalSurface);
|
||||
pKHdr->KernelHeapSize = 0;
|
||||
pKHdr->GeneralStateHeapSize = 0;
|
||||
pKHdr->DynamicStateHeapSize = 0;
|
||||
pKHdr->SurfaceStateHeapSize = 0;
|
||||
pKHdr->KernelUnpaddedSize = 0;
|
||||
pBin += sizeof(SKernelBinaryHeaderCommon);
|
||||
binSize += sizeof(SKernelBinaryHeaderCommon);
|
||||
|
||||
strcpy(pBin, "TstCopy");
|
||||
pBin += pKHdr->KernelNameSize;
|
||||
binSize += pKHdr->KernelNameSize;
|
||||
|
||||
SPatchAllocateLocalSurface *pPatch = (SPatchAllocateLocalSurface *)pBin;
|
||||
pPatch->Token = iOpenCL::PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE;
|
||||
pPatch->Size = sizeof(iOpenCL::SPatchAllocateLocalSurface);
|
||||
pPatch->TotalInlineLocalMemorySize = static_cast<uint32_t>(pDevice->getDeviceInfo().localMemSize * 2);
|
||||
|
||||
binSize += sizeof(SPatchAllocateLocalSurface);
|
||||
pBin += sizeof(SPatchAllocateLocalSurface);
|
||||
pKHdr->CheckSum = PatchTokenBinary::calcKernelChecksum(ArrayRef<const uint8_t>(reinterpret_cast<uint8_t *>(pKHdr), reinterpret_cast<uint8_t *>(pBin)));
|
||||
|
||||
// Decode prepared program binary
|
||||
program->genBinary = makeCopy(&genBin[0], binSize);
|
||||
program->genBinarySize = binSize;
|
||||
retVal = program->processGenBinary();
|
||||
PatchTokensTestData::ValidProgramWithKernelUsingSlm patchtokensProgram;
|
||||
patchtokensProgram.slmMutable->TotalInlineLocalMemorySize = static_cast<uint32_t>(pDevice->getDeviceInfo().localMemSize * 2);
|
||||
patchtokensProgram.recalcTokPtr();
|
||||
auto program = std::make_unique<MockProgram>(*pDevice->getExecutionEnvironment(), nullptr, false);
|
||||
program->genBinary = makeCopy(patchtokensProgram.storage.data(), patchtokensProgram.storage.size());
|
||||
program->genBinarySize = patchtokensProgram.storage.size();
|
||||
auto retVal = program->processGenBinary();
|
||||
|
||||
EXPECT_EQ(CL_OUT_OF_RESOURCES, retVal);
|
||||
}
|
||||
|
||||
TEST_F(ProgramTests, ProgramFromGenBinaryWithPATCH_TOKEN_GTPIN_FREE_GRF_INFO) {
|
||||
#define GRF_INFO_SIZE 44u
|
||||
cl_int retVal = CL_INVALID_BINARY;
|
||||
char genBin[1024] = {1, 2, 3, 4, 5, 6, 7, 8, 9, '\0'};
|
||||
size_t binSize = 10;
|
||||
|
||||
MockProgram *pProgram = Program::createFromGenBinary<MockProgram>(*pDevice->getExecutionEnvironment(), nullptr, &genBin[0], binSize, false, &retVal);
|
||||
EXPECT_NE(nullptr, pProgram);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ((uint32_t)CL_PROGRAM_BINARY_TYPE_EXECUTABLE, (uint32_t)pProgram->getProgramBinaryType());
|
||||
|
||||
cl_device_id deviceId = pContext->getDevice(0);
|
||||
ClDevice *pDevice = castToObject<ClDevice>(deviceId);
|
||||
char *pBin = &genBin[0];
|
||||
retVal = CL_INVALID_BINARY;
|
||||
binSize = 0;
|
||||
|
||||
// Prepare simple program binary containing patch token PATCH_TOKEN_GTPIN_FREE_GRF_INFO
|
||||
SProgramBinaryHeader *pBHdr = (SProgramBinaryHeader *)pBin;
|
||||
pBHdr->Magic = iOpenCL::MAGIC_CL;
|
||||
pBHdr->Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
pBHdr->Device = pDevice->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
pBHdr->GPUPointerSizeInBytes = 8;
|
||||
pBHdr->NumberOfKernels = 1;
|
||||
pBHdr->SteppingId = 0;
|
||||
pBHdr->PatchListSize = 0;
|
||||
pBin += sizeof(SProgramBinaryHeader);
|
||||
binSize += sizeof(SProgramBinaryHeader);
|
||||
|
||||
uint32_t patchTokenSize = sizeof(iOpenCL::SPatchGtpinFreeGRFInfo) + GRF_INFO_SIZE;
|
||||
SKernelBinaryHeaderCommon *pKHdr = (SKernelBinaryHeaderCommon *)pBin;
|
||||
pKHdr->CheckSum = 0;
|
||||
pKHdr->ShaderHashCode = 0;
|
||||
pKHdr->KernelNameSize = 8;
|
||||
pKHdr->PatchListSize = patchTokenSize;
|
||||
pKHdr->KernelHeapSize = 0;
|
||||
pKHdr->GeneralStateHeapSize = 0;
|
||||
pKHdr->DynamicStateHeapSize = 0;
|
||||
pKHdr->SurfaceStateHeapSize = 0;
|
||||
pKHdr->KernelUnpaddedSize = 0;
|
||||
pBin += sizeof(SKernelBinaryHeaderCommon);
|
||||
binSize += sizeof(SKernelBinaryHeaderCommon);
|
||||
|
||||
strcpy(pBin, "TstCopy");
|
||||
pBin += pKHdr->KernelNameSize;
|
||||
binSize += pKHdr->KernelNameSize;
|
||||
|
||||
SPatchGtpinFreeGRFInfo *pPatch = (SPatchGtpinFreeGRFInfo *)pBin;
|
||||
pPatch->Token = iOpenCL::PATCH_TOKEN_GTPIN_FREE_GRF_INFO;
|
||||
pPatch->Size = patchTokenSize;
|
||||
pPatch->BufferSize = GRF_INFO_SIZE;
|
||||
|
||||
binSize += pPatch->Size;
|
||||
pBin += pPatch->Size;
|
||||
pKHdr->CheckSum = PatchTokenBinary::calcKernelChecksum(ArrayRef<const uint8_t>(reinterpret_cast<uint8_t *>(pKHdr), reinterpret_cast<uint8_t *>(pBin)));
|
||||
|
||||
// Decode prepared program binary
|
||||
pProgram->genBinary = makeCopy(&genBin[0], binSize);
|
||||
pProgram->genBinarySize = binSize;
|
||||
retVal = pProgram->processGenBinary();
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
delete pProgram;
|
||||
#undef GRF_INFO_SIZE
|
||||
}
|
||||
|
||||
TEST_F(ProgramTests, ValidBinaryWithIGCVersionEqual0) {
|
||||
cl_int retVal;
|
||||
|
||||
@@ -2989,19 +2823,6 @@ TEST(RebuildProgramFromIrTests, givenBinaryProgramWhenKernelRebulildIsNotForcedT
|
||||
EXPECT_FALSE(pProgram->rebuildProgramFromIrCalled);
|
||||
}
|
||||
|
||||
TEST(Program, whenGetKernelNamesStringIsCalledThenNamesAreProperlyConcatenated) {
|
||||
ExecutionEnvironment execEnv;
|
||||
MockProgram program{execEnv};
|
||||
KernelInfo kernel1 = {};
|
||||
kernel1.name = "kern1";
|
||||
KernelInfo kernel2 = {};
|
||||
kernel2.name = "kern2";
|
||||
program.getKernelInfoArray().push_back(&kernel1);
|
||||
program.getKernelInfoArray().push_back(&kernel2);
|
||||
EXPECT_EQ("kern1;kern2", program.getKernelNamesString());
|
||||
program.getKernelInfoArray().clear();
|
||||
}
|
||||
|
||||
struct SpecializationConstantProgramMock : public MockProgram {
|
||||
using MockProgram::MockProgram;
|
||||
cl_int updateSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue) override {
|
||||
|
||||
@@ -367,9 +367,11 @@ HWTEST_F(SamplerSetArgTest, setKernelArgWithInvalidSampler) {
|
||||
|
||||
TEST_F(SamplerSetArgTest, givenSamplerTypeStrAndIsSamplerTrueWhenInitializeKernelThenKernelArgumentsTypeIsSamplerObj) {
|
||||
pKernelInfo->kernelArgInfo.resize(2);
|
||||
pKernelInfo->kernelArgInfo[0].typeStr = "sampler*";
|
||||
pKernelInfo->kernelArgInfo[0].metadataExtended = std::make_unique<ArgTypeMetadataExtended>();
|
||||
pKernelInfo->kernelArgInfo[0].metadataExtended->type = "sampler*";
|
||||
pKernelInfo->kernelArgInfo[0].isSampler = true;
|
||||
pKernelInfo->kernelArgInfo[1].typeStr = "sampler";
|
||||
pKernelInfo->kernelArgInfo[1].metadataExtended = std::make_unique<ArgTypeMetadataExtended>();
|
||||
pKernelInfo->kernelArgInfo[1].metadataExtended->type = "sampler";
|
||||
pKernelInfo->kernelArgInfo[1].isSampler = true;
|
||||
|
||||
auto pMockKernell = std::make_unique<MockKernel>(program.get(), *pKernelInfo, *pClDevice);
|
||||
@@ -380,9 +382,11 @@ TEST_F(SamplerSetArgTest, givenSamplerTypeStrAndIsSamplerTrueWhenInitializeKerne
|
||||
|
||||
TEST_F(SamplerSetArgTest, givenSamplerTypeStrAndAndIsSamplerFalseWhenInitializeKernelThenKernelArgumentsTypeIsNotSamplerObj) {
|
||||
pKernelInfo->kernelArgInfo.resize(2);
|
||||
pKernelInfo->kernelArgInfo[0].typeStr = "sampler*";
|
||||
pKernelInfo->kernelArgInfo[0].metadataExtended = std::make_unique<ArgTypeMetadataExtended>();
|
||||
pKernelInfo->kernelArgInfo[0].metadataExtended->type = "sampler*";
|
||||
pKernelInfo->kernelArgInfo[0].isSampler = false;
|
||||
pKernelInfo->kernelArgInfo[1].typeStr = "sampler";
|
||||
pKernelInfo->kernelArgInfo[1].metadataExtended = std::make_unique<ArgTypeMetadataExtended>();
|
||||
pKernelInfo->kernelArgInfo[1].metadataExtended->type = "sampler";
|
||||
pKernelInfo->kernelArgInfo[1].isSampler = false;
|
||||
|
||||
auto pMockKernell = std::make_unique<MockKernel>(program.get(), *pKernelInfo, *pClDevice);
|
||||
|
||||
@@ -50,7 +50,7 @@ class MockSchedulerKernel : public SchedulerKernel {
|
||||
bufferArg.kernelArgPatchInfoVector[0].crossthreadOffset = 0;
|
||||
bufferArg.kernelArgPatchInfoVector[0].size = 0;
|
||||
bufferArg.kernelArgPatchInfoVector[0].sourceOffset = 0;
|
||||
info->kernelArgInfo.push_back(bufferArg);
|
||||
info->kernelArgInfo.push_back(std::move(bufferArg));
|
||||
}
|
||||
|
||||
MockSchedulerKernel *mock = Kernel::create<MockSchedulerKernel>(&program, *info, nullptr);
|
||||
|
||||
@@ -525,7 +525,7 @@ TEST(FileLogger, WithDebugFunctionalityDumpKernelArgsLocalBuffer) {
|
||||
|
||||
kernelInfo->kernelArgInfo.resize(1);
|
||||
kernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo);
|
||||
kernelInfo->kernelArgInfo[0].addressQualifier = static_cast<cl_kernel_arg_address_qualifier>(CL_KERNEL_ARG_ADDRESS_LOCAL);
|
||||
kernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Local;
|
||||
|
||||
std::string testFile = "testfile";
|
||||
DebugVariables flags;
|
||||
@@ -547,8 +547,9 @@ TEST(FileLogger, WithDebugFunctionalityDumpKernelArgsBufferNotSet) {
|
||||
KernelArgPatchInfo kernelArgPatchInfo;
|
||||
|
||||
kernelInfo->kernelArgInfo.resize(1);
|
||||
kernelInfo->kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
kernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo);
|
||||
kernelInfo->kernelArgInfo[0].typeStr = "uint8 *buffer";
|
||||
kernelInfo->kernelArgInfo[0].metadataExtended->type = "uint8 *buffer";
|
||||
|
||||
kernel->initialize();
|
||||
|
||||
@@ -580,8 +581,9 @@ TEST(FileLogger, WithDebugFunctionalityDumpKernelArgsBuffer) {
|
||||
KernelArgPatchInfo kernelArgPatchInfo;
|
||||
|
||||
kernelInfo->kernelArgInfo.resize(1);
|
||||
kernelInfo->kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
kernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo);
|
||||
kernelInfo->kernelArgInfo[0].typeStr = "uint8 *buffer";
|
||||
kernelInfo->kernelArgInfo[0].metadataExtended->type = "uint8 *buffer";
|
||||
kernelInfo->kernelArgInfo.at(0).isBuffer = true;
|
||||
|
||||
kernel->initialize();
|
||||
@@ -618,8 +620,9 @@ TEST(FileLogger, WithDebugFunctionalityDumpKernelArgsSampler) {
|
||||
KernelArgPatchInfo kernelArgPatchInfo;
|
||||
|
||||
kernelInfo->kernelArgInfo.resize(1);
|
||||
kernelInfo->kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
kernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo);
|
||||
kernelInfo->kernelArgInfo[0].typeStr = "sampler test";
|
||||
kernelInfo->kernelArgInfo[0].metadataExtended->type = "sampler test";
|
||||
|
||||
kernel->initialize();
|
||||
|
||||
@@ -653,8 +656,9 @@ TEST(FileLogger, WithDebugFunctionalityDumpKernelArgsImageNotSet) {
|
||||
KernelArgPatchInfo kernelArgPatchInfo;
|
||||
|
||||
kernelInfo->kernelArgInfo.resize(1);
|
||||
kernelInfo->kernelArgInfo[0].metadataExtended = std::make_unique<NEO::ArgTypeMetadataExtended>();
|
||||
kernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo);
|
||||
kernelInfo->kernelArgInfo[0].typeStr = "image2d buffer";
|
||||
kernelInfo->kernelArgInfo[0].metadataExtended->type = "image2d buffer";
|
||||
kernelInfo->kernelArgInfo[0].isImage = true;
|
||||
kernelInfo->kernelArgInfo[0].offsetImgWidth = 0x4;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user