/* * Copyright (c) 2017 - 2018, Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include "runtime/program/kernel_info.h" #include "runtime/memory_manager/os_agnostic_memory_manager.h" #include "gtest/gtest.h" #include #include using namespace OCLRT; TEST(KernelInfo, NonCopyable) { EXPECT_FALSE(std::is_move_constructible::value); EXPECT_FALSE(std::is_copy_constructible::value); } TEST(KernelInfo, NonAssignable) { EXPECT_FALSE(std::is_move_assignable::value); EXPECT_FALSE(std::is_copy_assignable::value); } TEST(KernelInfo, defaultBehavior) { KernelInfo *pKernelInfo = KernelInfo::create(); EXPECT_FALSE(pKernelInfo->usesSsh); EXPECT_FALSE(pKernelInfo->isValid); delete pKernelInfo; } TEST(KernelInfo, decodeConstantMemoryKernelArgument) { uint32_t argumentNumber = 0; KernelInfo *pKernelInfo = KernelInfo::create(); SPatchStatelessConstantMemoryObjectKernelArgument arg; arg.Token = 0xa; arg.Size = 0x20; arg.ArgumentNumber = argumentNumber; arg.SurfaceStateHeapOffset = 0x30; arg.DataParamOffset = 0x40; arg.DataParamSize = 0x4; arg.LocationIndex = static_cast(-1); arg.LocationIndex2 = static_cast(-1); pKernelInfo->storeKernelArgument(&arg); EXPECT_TRUE(pKernelInfo->usesSsh); const auto &argInfo = pKernelInfo->kernelArgInfo[argumentNumber]; EXPECT_EQ(arg.SurfaceStateHeapOffset, argInfo.offsetHeap); EXPECT_FALSE(argInfo.isImage); const auto &patchInfo = pKernelInfo->patchInfo; EXPECT_EQ(1u, patchInfo.statelessGlobalMemObjKernelArgs.size()); delete pKernelInfo; } TEST(KernelInfo, decodeGlobalMemoryKernelArgument) { uint32_t argumentNumber = 1; KernelInfo *pKernelInfo = KernelInfo::create(); SPatchStatelessGlobalMemoryObjectKernelArgument arg; arg.Token = 0xb; arg.Size = 0x30; arg.ArgumentNumber = argumentNumber; arg.SurfaceStateHeapOffset = 0x40; arg.DataParamOffset = 050; arg.DataParamSize = 0x8; arg.LocationIndex = static_cast(-1); arg.LocationIndex2 = static_cast(-1); pKernelInfo->storeKernelArgument(&arg); EXPECT_TRUE(pKernelInfo->usesSsh); const auto &argInfo = pKernelInfo->kernelArgInfo[argumentNumber]; EXPECT_EQ(arg.SurfaceStateHeapOffset, argInfo.offsetHeap); EXPECT_FALSE(argInfo.isImage); const auto &patchInfo = pKernelInfo->patchInfo; EXPECT_EQ(1u, patchInfo.statelessGlobalMemObjKernelArgs.size()); delete pKernelInfo; } TEST(KernelInfo, decodeImageKernelArgument) { uint32_t argumentNumber = 1; KernelInfo *pKernelInfo = KernelInfo::create(); SPatchImageMemoryObjectKernelArgument arg; arg.Token = 0xc; arg.Size = 0x20; arg.ArgumentNumber = argumentNumber; arg.Type = 0x4; arg.Offset = 0x40; arg.LocationIndex = static_cast(-1); arg.LocationIndex2 = static_cast(-1); arg.Writeable = true; pKernelInfo->storeKernelArgument(&arg); EXPECT_TRUE(pKernelInfo->usesSsh); const auto &argInfo = pKernelInfo->kernelArgInfo[argumentNumber]; //EXPECT_EQ(???, argInfo.argSize); EXPECT_EQ(arg.Offset, argInfo.offsetHeap); EXPECT_TRUE(argInfo.isImage); EXPECT_EQ(static_cast(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); delete pKernelInfo; } TEST(KernelInfoTest, givenKernelInfoWhenCreateKernelAllocationThenCopyWholeKernelHeapToKernelAllocation) { KernelInfo kernelInfo; OsAgnosticMemoryManager memoryManager; SKernelBinaryHeaderCommon kernelHeader; const size_t heapSize = 0x40; char heap[heapSize]; kernelHeader.KernelHeapSize = heapSize; kernelInfo.heapInfo.pKernelHeader = &kernelHeader; kernelInfo.heapInfo.pKernelHeap = &heap; for (size_t i = 0; i < heapSize; i++) { heap[i] = static_cast(i); } auto retVal = kernelInfo.createKernelAllocation(&memoryManager); EXPECT_TRUE(retVal); auto allocation = kernelInfo.kernelAllocation; EXPECT_EQ(0, memcmp(allocation->getUnderlyingBuffer(), heap, heapSize)); EXPECT_EQ(heapSize, allocation->getUnderlyingBufferSize()); memoryManager.checkGpuUsageAndDestroyGraphicsAllocations(allocation); } class MyMemoryManager : public OsAgnosticMemoryManager { public: GraphicsAllocation *createInternalGraphicsAllocation(const void *ptr, size_t allocationSize) override { return nullptr; } }; TEST(KernelInfoTest, givenKernelInfoWhenCreateKernelAllocationAndCannotAllocateMemoryThenReturnsFalse) { KernelInfo kernelInfo; MyMemoryManager memoryManager; SKernelBinaryHeaderCommon kernelHeader; kernelInfo.heapInfo.pKernelHeader = &kernelHeader; auto retVal = kernelInfo.createKernelAllocation(&memoryManager); EXPECT_FALSE(retVal); } TEST(KernelInfo, decodeGlobalMemObjectKernelArgument) { uint32_t argumentNumber = 1; KernelInfo *pKernelInfo = KernelInfo::create(); SPatchGlobalMemoryObjectKernelArgument arg; arg.Token = 0xb; arg.Size = 0x10; arg.ArgumentNumber = argumentNumber; arg.Offset = 0x40; arg.LocationIndex = static_cast(-1); arg.LocationIndex2 = static_cast(-1); pKernelInfo->storeKernelArgument(&arg); EXPECT_TRUE(pKernelInfo->usesSsh); const auto &argInfo = pKernelInfo->kernelArgInfo[argumentNumber]; EXPECT_EQ(arg.Offset, argInfo.offsetHeap); EXPECT_TRUE(argInfo.isBuffer); delete pKernelInfo; } TEST(KernelInfo, decodeSamplerKernelArgument) { uint32_t argumentNumber = 1; KernelInfo *pKernelInfo = KernelInfo::create(); SPatchSamplerKernelArgument arg; arg.ArgumentNumber = argumentNumber; arg.Token = 0x10; arg.Size = 0x18; arg.LocationIndex = static_cast(-1); arg.LocationIndex2 = static_cast(-1); arg.Offset = 0x40; arg.Type = iOpenCL::SAMPLER_OBJECT_TEXTURE; pKernelInfo->usesSsh = true; pKernelInfo->storeKernelArgument(&arg); const auto &argInfo = pKernelInfo->kernelArgInfo[argumentNumber]; EXPECT_EQ(arg.Offset, argInfo.offsetHeap); EXPECT_FALSE(argInfo.isImage); EXPECT_TRUE(argInfo.isSampler); EXPECT_TRUE(pKernelInfo->usesSsh); delete pKernelInfo; } typedef KernelInfo KernelInfo_resolveKernelInfo; TEST(KernelInfo_resolveKernelInfo, basicArgument) { KernelInfo *pKernelInfo = KernelInfo::create(); 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_READ_ONLY), kernelArgInfo.accessQualifier); EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_GLOBAL), kernelArgInfo.addressQualifier); EXPECT_EQ(static_cast(CL_KERNEL_ARG_TYPE_RESTRICT), kernelArgInfo.typeQualifier); delete pKernelInfo; } TEST(KernelInfo_resolveKernelInfo, complexArgumentType) { KernelInfo *pKernelInfo = KernelInfo::create(); 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_READ_ONLY), kernelArgInfo.accessQualifier); EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_GLOBAL), kernelArgInfo.addressQualifier); EXPECT_EQ(static_cast(CL_KERNEL_ARG_TYPE_RESTRICT | CL_KERNEL_ARG_TYPE_CONST), kernelArgInfo.typeQualifier); delete pKernelInfo; } TEST(KernelInfo, givenKernelInfoWhenStoreTransformableArgThenArgInfoIsTransformable) { uint32_t argumentNumber = 1; std::unique_ptr kernelInfo(KernelInfo::create()); SPatchImageMemoryObjectKernelArgument arg; arg.ArgumentNumber = argumentNumber; arg.Transformable = true; kernelInfo->storeKernelArgument(&arg); const auto &argInfo = kernelInfo->kernelArgInfo[argumentNumber]; EXPECT_TRUE(argInfo.isTransformable); } TEST(KernelInfo, givenKernelInfoWhenStoreNonTransformableArgThenArgInfoIsNotTransformable) { uint32_t argumentNumber = 1; std::unique_ptr kernelInfo(KernelInfo::create()); SPatchImageMemoryObjectKernelArgument arg; arg.ArgumentNumber = argumentNumber; arg.Transformable = false; kernelInfo->storeKernelArgument(&arg); const auto &argInfo = kernelInfo->kernelArgInfo[argumentNumber]; EXPECT_FALSE(argInfo.isTransformable); }