diff --git a/runtime/compiler_interface/patchtokens_validator.inl b/runtime/compiler_interface/patchtokens_validator.inl index 72ddd41a55..6149b76f4c 100644 --- a/runtime/compiler_interface/patchtokens_validator.inl +++ b/runtime/compiler_interface/patchtokens_validator.inl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2019-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -52,8 +52,9 @@ inline ValidatorError validate(const ProgramFromPatchtokens &decodedProgram, for (const auto &globalConstantPointerToken : decodedProgram.programScopeTokens.constantPointer) { bool isUnhandled = (globalConstantPointerToken->ConstantBufferIndex != 0); isUnhandled |= (globalConstantPointerToken->BufferIndex != 0); - isUnhandled |= (globalConstantPointerToken->BufferType != PROGRAM_SCOPE_CONSTANT_BUFFER); - isUnhandled |= (0 == decodedProgram.programScopeTokens.allocateConstantMemorySurface.size()) || decodedProgram.programScopeTokens.allocateConstantMemorySurface[0]->InlineDataSize < globalConstantPointerToken->ConstantPointerOffset + sizeof(uint32_t); + isUnhandled |= (globalConstantPointerToken->BufferType != PROGRAM_SCOPE_CONSTANT_BUFFER) && (globalConstantPointerToken->BufferType != PROGRAM_SCOPE_GLOBAL_BUFFER); + isUnhandled |= (globalConstantPointerToken->BufferType == PROGRAM_SCOPE_GLOBAL_BUFFER) && (decodedProgram.programScopeTokens.allocateGlobalMemorySurface.empty()); + isUnhandled |= (decodedProgram.programScopeTokens.allocateConstantMemorySurface.empty()) || decodedProgram.programScopeTokens.allocateConstantMemorySurface[0]->InlineDataSize < globalConstantPointerToken->ConstantPointerOffset + sizeof(uint32_t); if (isUnhandled) { outErrReason = "Unhandled SPatchConstantPointerProgramBinaryInfo"; @@ -64,8 +65,9 @@ inline ValidatorError validate(const ProgramFromPatchtokens &decodedProgram, for (const auto &globalVariablePointerToken : decodedProgram.programScopeTokens.globalPointer) { bool isUnhandled = (globalVariablePointerToken->GlobalBufferIndex != 0); isUnhandled |= (globalVariablePointerToken->BufferIndex != 0); - isUnhandled |= (globalVariablePointerToken->BufferType != PROGRAM_SCOPE_GLOBAL_BUFFER); - isUnhandled |= (0 == decodedProgram.programScopeTokens.allocateGlobalMemorySurface.size()) || decodedProgram.programScopeTokens.allocateGlobalMemorySurface[0]->InlineDataSize < globalVariablePointerToken->GlobalPointerOffset + sizeof(uint32_t); + isUnhandled |= (globalVariablePointerToken->BufferType != PROGRAM_SCOPE_GLOBAL_BUFFER) && (globalVariablePointerToken->BufferType != PROGRAM_SCOPE_CONSTANT_BUFFER); + isUnhandled |= (globalVariablePointerToken->BufferType == PROGRAM_SCOPE_CONSTANT_BUFFER) && (decodedProgram.programScopeTokens.allocateConstantMemorySurface.empty()); + isUnhandled |= (decodedProgram.programScopeTokens.allocateGlobalMemorySurface.empty()) || decodedProgram.programScopeTokens.allocateGlobalMemorySurface[0]->InlineDataSize < globalVariablePointerToken->GlobalPointerOffset + sizeof(uint32_t); if (isUnhandled) { outErrReason = "Unhandled SPatchGlobalPointerProgramBinaryInfo"; diff --git a/runtime/program/kernel_info_from_patchtokens.cpp b/runtime/program/kernel_info_from_patchtokens.cpp index 03975ce716..468ee71c06 100644 --- a/runtime/program/kernel_info_from_patchtokens.cpp +++ b/runtime/program/kernel_info_from_patchtokens.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2019-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -29,7 +29,7 @@ inline uint32_t getOffset(T *token) { return WorkloadInfo::undefinedOffset; } -void populateKernelInfoArg(KernelInfo &dstKernelInfo, KernelArgInfo &dstKernelInfoArg, const PatchTokenBinary::KernelArgFromPatchtokens src) { +void populateKernelInfoArg(KernelInfo &dstKernelInfo, KernelArgInfo &dstKernelInfoArg, const PatchTokenBinary::KernelArgFromPatchtokens &src) { dstKernelInfoArg.needPatch = true; dstKernelInfo.storeArgInfo(src.argInfo); if (src.objectArg != nullptr) { diff --git a/runtime/program/process_gen_binary.cpp b/runtime/program/process_gen_binary.cpp index 66d098fb24..50ae056d58 100644 --- a/runtime/program/process_gen_binary.cpp +++ b/runtime/program/process_gen_binary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2019 Intel Corporation + * Copyright (C) 2017-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -218,19 +218,31 @@ void Program::processProgramScopeMetadata(const PatchTokenBinary::ProgramFromPat } 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(offset)); - patchIncrement(patchOffset, constantSurface->is32BitAllocation() ? 4 : sizeof(uintptr_t), constantSurface->getGpuAddressToPatch()); + 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(offset)); - patchIncrement(patchOffset, globalSurface->is32BitAllocation() ? 4 : sizeof(uintptr_t), globalSurface->getGpuAddressToPatch()); + patchIncrement(patchOffset, globalSurface->is32BitAllocation() ? 4 : sizeof(uintptr_t), srcSurface->getGpuAddressToPatch()); } } diff --git a/unit_tests/compiler_interface/patchtokens_tests.h b/unit_tests/compiler_interface/patchtokens_tests.h index bdb459528e..6284eb38ef 100644 --- a/unit_tests/compiler_interface/patchtokens_tests.h +++ b/unit_tests/compiler_interface/patchtokens_tests.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2019-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -126,6 +126,36 @@ struct ValidProgramWithGlobalSurfaceAndPointer : ValidProgramWithGlobalSurface { iOpenCL::SPatchGlobalPointerProgramBinaryInfo *globalPointerMutable = nullptr; }; +struct ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers : ValidProgramWithConstantSurfaceAndPointer { + ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers() { + globalVariableTokensOffset = this->storage.size(); + this->constantPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER; + + ValidProgramWithGlobalSurfaceAndPointer globalVarSurfProg; + this->programScopeTokens.globalPointer.push_back(nullptr); + this->programScopeTokens.allocateGlobalMemorySurface.push_back(nullptr); + this->storage.insert(this->storage.end(), globalVarSurfProg.storage.data() + sizeof(*globalVarSurfProg.headerMutable), + globalVarSurfProg.storage.data() + globalVarSurfProg.storage.size()); + recalcTokPtr(); + this->globalPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_CONSTANT_BUFFER; + } + + void recalcTokPtr() { + this->ValidProgramWithConstantSurfaceAndPointer::recalcTokPtr(); + this->globalSurfMutable = reinterpret_cast(storage.data() + globalVariableTokensOffset); + this->programScopeTokens.allocateGlobalMemorySurface[0] = this->globalSurfMutable; + this->blobs.patchList = ArrayRef(storage.data() + sizeof(*this->headerMutable), storage.size() - sizeof(*this->headerMutable)); + this->headerMutable->PatchListSize = static_cast(this->blobs.patchList.size()); + + this->globalPointerMutable = reinterpret_cast(storage.data() + globalVariableTokensOffset + sizeof(*this->globalSurfMutable) + this->globalSurfMutable->InlineDataSize); + this->programScopeTokens.globalPointer[0] = this->globalPointerMutable; + } + + size_t globalVariableTokensOffset = 0U; + iOpenCL::SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo *globalSurfMutable = nullptr; + iOpenCL::SPatchGlobalPointerProgramBinaryInfo *globalPointerMutable = nullptr; +}; + struct ValidEmptyKernel { static NEO::PatchTokenBinary::KernelFromPatchtokens create(std::vector &storage) { NEO::PatchTokenBinary::KernelFromPatchtokens ret; diff --git a/unit_tests/compiler_interface/patchtokens_validator_tests.cpp b/unit_tests/compiler_interface/patchtokens_validator_tests.cpp index b890657d76..389c28ee18 100644 --- a/unit_tests/compiler_interface/patchtokens_validator_tests.cpp +++ b/unit_tests/compiler_interface/patchtokens_validator_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2019-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -120,7 +120,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerBufferTypeThenV PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer prog; std::string error, warning; - prog.constantPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER; + 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()); @@ -155,6 +155,31 @@ TEST(PatchtokensValidator, GivenValidProgramWithValidGlobalPointerThenValidation EXPECT_EQ(0U, warning.size()); } +TEST(PatchtokensValidator, GivenValidProgramWithMixedGlobalVarAndConstSurfacesAndPointersThenValidationSucceeds) { + PatchTokensTestData::ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers prog; + 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()); +} + +TEST(PatchtokensValidator, GivenInvalidProgramWithMixedGlobalVarAndConstSurfacesAndPointersThenValidationSucceeds) { + 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()); + + 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()); +} + TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerBufferIndexThenValidationFails) { PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer prog; std::string error, warning; @@ -179,7 +204,7 @@ TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerBufferTypeThenVal PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer prog; std::string error, warning; - prog.globalPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_CONSTANT_BUFFER; + 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()); diff --git a/unit_tests/mocks/mock_program.h b/unit_tests/mocks/mock_program.h index 978b6204ef..34a1e7356c 100644 --- a/unit_tests/mocks/mock_program.h +++ b/unit_tests/mocks/mock_program.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2019 Intel Corporation + * Copyright (C) 2017-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -58,6 +58,7 @@ 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; diff --git a/unit_tests/program/program_data_tests.cpp b/unit_tests/program/program_data_tests.cpp index fffc292a47..9e19ac9041 100644 --- a/unit_tests/program/program_data_tests.cpp +++ b/unit_tests/program/program_data_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2019 Intel Corporation + * Copyright (C) 2017-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -13,8 +13,11 @@ #include "runtime/platform/platform.h" #include "runtime/program/program.h" #include "test.h" +#include "unit_tests/compiler_interface/patchtokens_tests.h" #include "unit_tests/mocks/mock_buffer.h" #include "unit_tests/mocks/mock_csr.h" +#include "unit_tests/mocks/mock_execution_environment.h" +#include "unit_tests/mocks/mock_memory_manager.h" #include "unit_tests/mocks/mock_program.h" #include "unit_tests/program/program_with_source.h" @@ -718,6 +721,26 @@ TEST_F(ProgramDataTest, ConstantPointerProgramBinaryInfo) { delete[] pConstantPointer; } +TEST(ProgramScopeMetadataTest, WhenPatchingGlobalSurfaceThenPickProperSourceBuffer) { + MockExecutionEnvironment execEnv; + MockDevice device; + execEnv.memoryManager = std::make_unique(); + PatchTokensTestData::ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers decodedProgram; + decodedProgram.globalPointerMutable->GlobalPointerOffset = 0U; + decodedProgram.constantPointerMutable->ConstantPointerOffset = 0U; + memset(decodedProgram.globalSurfMutable + 1, 0U, sizeof(uintptr_t)); + memset(decodedProgram.constSurfMutable + 1, 0U, sizeof(uintptr_t)); + MockProgram program(execEnv); + program.pDevice = &device; + program.processProgramScopeMetadata(decodedProgram); + ASSERT_NE(nullptr, program.globalSurface); + ASSERT_NE(nullptr, program.constantSurface); + ASSERT_NE(nullptr, program.globalSurface->getUnderlyingBuffer()); + ASSERT_NE(nullptr, program.constantSurface->getUnderlyingBuffer()); + EXPECT_EQ(static_cast(program.globalSurface->getGpuAddressToPatch()), *reinterpret_cast(program.constantSurface->getUnderlyingBuffer())); + EXPECT_EQ(static_cast(program.constantSurface->getGpuAddressToPatch()), *reinterpret_cast(program.globalSurface->getUnderlyingBuffer())); +} + TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeConstantBufferPatchTokensAreReadThenConstantPointerOffsetIsPatchedWith32bitPointer) { cl_device_id device = pPlatform->getDevice(0); CreateProgramWithSource(pContext, &device, "CopyBuffer_simd8.cl"); diff --git a/unit_tests/program/program_tests.cpp b/unit_tests/program/program_tests.cpp index 3b6587f5ba..b529bb5eee 100644 --- a/unit_tests/program/program_tests.cpp +++ b/unit_tests/program/program_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2019 Intel Corporation + * Copyright (C) 2017-2020 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -1453,23 +1453,6 @@ class ProgramPatchTokenFromBinaryTest : public ProgramSimpleFixture { }; typedef Test ProgramPatchTokenTests; -TEST_F(ProgramPatchTokenTests, DISABLED_ConstantMemorySurface) { - cl_device_id device = pDevice; - - CreateProgramWithSource(pContext, &device, "CopyBuffer_simd8.cl"); - - ASSERT_NE(nullptr, pProgram); - retVal = pProgram->build( - 1, - &device, - nullptr, - nullptr, - nullptr, - false); - - EXPECT_EQ(CL_SUCCESS, retVal); -} - TEST(ProgramFromBinaryTests, givenBinaryWithInvalidICBEThenErrorIsReturned) { cl_int retVal = CL_INVALID_BINARY;