/* * Copyright (C) 2019 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "runtime/api/api.h" #include "runtime/memory_manager/unified_memory_manager.h" #include "unit_tests/mocks/mock_context.h" #include "unit_tests/mocks/mock_kernel.h" using namespace NEO; TEST(clUnifiedSharedMemoryTests, whenClHostMemAllocINTELisCalledWithoutContextThenInvalidContextIsReturned) { cl_int retVal = CL_SUCCESS; auto ptr = clHostMemAllocINTEL(0, nullptr, 0, 0, &retVal); EXPECT_EQ(nullptr, ptr); EXPECT_EQ(CL_INVALID_CONTEXT, retVal); } TEST(clUnifiedSharedMemoryTests, whenClHostMemAllocIntelIsCalledThenItAllocatesHostUnifiedMemoryAllocation) { MockContext mockContext; cl_int retVal = CL_SUCCESS; auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, nullptr, 4, 0, &retVal); EXPECT_EQ(CL_SUCCESS, retVal); ASSERT_NE(nullptr, unifiedMemoryHostAllocation); auto allocationsManager = mockContext.getSVMAllocsManager(); EXPECT_EQ(1u, allocationsManager->getNumAllocs()); auto graphicsAllocation = allocationsManager->getSVMAlloc(unifiedMemoryHostAllocation); EXPECT_EQ(graphicsAllocation->size, 4u); EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::HOST_UNIFIED_MEMORY); EXPECT_EQ(graphicsAllocation->gpuAllocation->getGpuAddress(), castToUint64(unifiedMemoryHostAllocation)); retVal = clMemFreeINTEL(&mockContext, unifiedMemoryHostAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClDeviceMemAllocINTELisCalledWithWrongContextThenInvalidContextErrorIsReturned) { cl_int retVal = CL_SUCCESS; auto ptr = clDeviceMemAllocINTEL(0, 0, nullptr, 0, 0, &retVal); EXPECT_EQ(nullptr, ptr); EXPECT_EQ(CL_INVALID_CONTEXT, retVal); } TEST(clUnifiedSharedMemoryTests, whenClDeviceMemAllocIntelIsCalledThenItAllocatesDeviceUnifiedMemoryAllocation) { MockContext mockContext; cl_int retVal = CL_SUCCESS; auto unfiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(&mockContext, mockContext.getDevice(0u), nullptr, 4, 0, &retVal); EXPECT_EQ(CL_SUCCESS, retVal); ASSERT_NE(nullptr, unfiedMemoryDeviceAllocation); auto allocationsManager = mockContext.getSVMAllocsManager(); EXPECT_EQ(1u, allocationsManager->getNumAllocs()); auto graphicsAllocation = allocationsManager->getSVMAlloc(unfiedMemoryDeviceAllocation); EXPECT_EQ(graphicsAllocation->size, 4u); EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::DEVICE_UNIFIED_MEMORY); EXPECT_EQ(graphicsAllocation->gpuAllocation->getGpuAddress(), castToUint64(unfiedMemoryDeviceAllocation)); retVal = clMemFreeINTEL(&mockContext, unfiedMemoryDeviceAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClSharedMemAllocINTELisCalledWithWrongContextThenInvalidContextErrorIsReturned) { cl_int retVal = CL_SUCCESS; auto ptr = clSharedMemAllocINTEL(0, 0, nullptr, 0, 0, &retVal); EXPECT_EQ(nullptr, ptr); EXPECT_EQ(CL_INVALID_CONTEXT, retVal); } TEST(clUnifiedSharedMemoryTests, whenClSharedMemAllocIntelIsCalledThenItAllocatesSharedUnifiedMemoryAllocation) { MockContext mockContext; cl_int retVal = CL_SUCCESS; auto unfiedMemorySharedAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), nullptr, 4, 0, &retVal); EXPECT_EQ(CL_SUCCESS, retVal); ASSERT_NE(nullptr, unfiedMemorySharedAllocation); auto allocationsManager = mockContext.getSVMAllocsManager(); EXPECT_EQ(1u, allocationsManager->getNumAllocs()); auto graphicsAllocation = allocationsManager->getSVMAlloc(unfiedMemorySharedAllocation); EXPECT_EQ(graphicsAllocation->size, 4u); EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::SHARED_UNIFIED_MEMORY); EXPECT_EQ(graphicsAllocation->gpuAllocation->getGpuAddress(), castToUint64(unfiedMemorySharedAllocation)); retVal = clMemFreeINTEL(&mockContext, unfiedMemorySharedAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClMemFreeINTELisCalledWithIncorrectContextThenReturnError) { auto retVal = clMemFreeINTEL(0, nullptr); EXPECT_EQ(CL_INVALID_CONTEXT, retVal); } TEST(clUnifiedSharedMemoryTests, whenClMemFreeINTELisCalledWithValidUmPointerThenMemoryIsFreed) { MockContext mockContext; cl_int retVal = CL_SUCCESS; auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, nullptr, 4, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); EXPECT_EQ(1u, allocationsManager->getNumAllocs()); retVal = clMemFreeINTEL(&mockContext, unifiedMemoryHostAllocation); EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(0u, allocationsManager->getNumAllocs()); } TEST(clUnifiedSharedMemoryTests, whenClMemFreeINTELisCalledWithInvalidUmPointerThenMemoryIsNotFreed) { MockContext mockContext; cl_int retVal = CL_SUCCESS; auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, nullptr, 4, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); EXPECT_EQ(1u, allocationsManager->getNumAllocs()); retVal = clMemFreeINTEL(&mockContext, ptrOffset(unifiedMemoryHostAllocation, 4)); EXPECT_EQ(CL_INVALID_VALUE, retVal); EXPECT_EQ(1u, allocationsManager->getNumAllocs()); retVal = clMemFreeINTEL(&mockContext, unifiedMemoryHostAllocation); EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(0u, allocationsManager->getNumAllocs()); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithoutContextThenInvalidContextIsReturned) { auto retVal = clGetMemAllocInfoINTEL(0, nullptr, 0, 0, nullptr, nullptr); EXPECT_EQ(CL_INVALID_CONTEXT, retVal); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithoutAllocationThenInvalidValueIsReturned) { MockContext mockContext; auto retVal = clGetMemAllocInfoINTEL(&mockContext, nullptr, 0, 0, nullptr, nullptr); EXPECT_EQ(CL_INVALID_VALUE, retVal); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithoutSVMAllocationThenInvalidValueIsReturned) { MockContext mockContext; delete mockContext.svmAllocsManager; mockContext.svmAllocsManager = nullptr; auto retVal = clGetMemAllocInfoINTEL(&mockContext, nullptr, 0, 0, nullptr, nullptr); EXPECT_EQ(CL_INVALID_VALUE, retVal); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithValidUnifiedMemoryHostAllocationThenProperFieldsAreSet) { MockContext mockContext; cl_int retVal = CL_SUCCESS; size_t paramValueSize = sizeof(cl_int); cl_int paramValue = 0; size_t paramValueSizeRet = 0; auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, nullptr, 4, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); auto graphicsAllocation = allocationsManager->getSVMAlloc(unifiedMemoryHostAllocation); retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemoryHostAllocation, CL_MEM_ALLOC_TYPE_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::HOST_UNIFIED_MEMORY); EXPECT_EQ(CL_MEM_TYPE_HOST_INTEL, paramValue); EXPECT_EQ(sizeof(cl_int), paramValueSizeRet); EXPECT_EQ(CL_SUCCESS, retVal); retVal = clMemFreeINTEL(&mockContext, unifiedMemoryHostAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithValidUnifiedMemoryDeviceAllocationThenProperFieldsAreSet) { MockContext mockContext; cl_int retVal = CL_SUCCESS; size_t paramValueSize = sizeof(cl_int); cl_int paramValue = 0; size_t paramValueSizeRet = 0; auto unifiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(&mockContext, mockContext.getDevice(0u), nullptr, 4, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); auto graphicsAllocation = allocationsManager->getSVMAlloc(unifiedMemoryDeviceAllocation); retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemoryDeviceAllocation, CL_MEM_ALLOC_TYPE_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::DEVICE_UNIFIED_MEMORY); EXPECT_EQ(CL_MEM_TYPE_DEVICE_INTEL, paramValue); EXPECT_EQ(sizeof(cl_int), paramValueSizeRet); EXPECT_EQ(CL_SUCCESS, retVal); retVal = clMemFreeINTEL(&mockContext, unifiedMemoryDeviceAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithValidUnifiedMemorySharedAllocationThenProperFieldsAreSet) { MockContext mockContext; cl_int retVal = CL_SUCCESS; size_t paramValueSize = sizeof(cl_int); cl_int paramValue = 0; size_t paramValueSizeRet = 0; auto unifiedMemorySharedAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), nullptr, 4, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); auto graphicsAllocation = allocationsManager->getSVMAlloc(unifiedMemorySharedAllocation); retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemorySharedAllocation, CL_MEM_ALLOC_TYPE_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::SHARED_UNIFIED_MEMORY); EXPECT_EQ(CL_MEM_TYPE_SHARED_INTEL, paramValue); EXPECT_EQ(sizeof(cl_int), paramValueSizeRet); EXPECT_EQ(CL_SUCCESS, retVal); retVal = clMemFreeINTEL(&mockContext, unifiedMemorySharedAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithAllocationBasePtrParamNameThenProperFieldsAreSet) { MockContext mockContext; cl_int retVal = CL_SUCCESS; size_t paramValueSize = sizeof(uint64_t); uint64_t paramValue = 0; size_t paramValueSizeRet = 0; auto unifiedMemorySharedAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), nullptr, 4, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); auto graphicsAllocation = allocationsManager->getSVMAlloc(unifiedMemorySharedAllocation); retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemorySharedAllocation, CL_MEM_ALLOC_BASE_PTR_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::SHARED_UNIFIED_MEMORY); EXPECT_EQ(graphicsAllocation->gpuAllocation->getGpuAddress(), paramValue); EXPECT_EQ(sizeof(uint64_t), paramValueSizeRet); EXPECT_EQ(CL_SUCCESS, retVal); retVal = clMemFreeINTEL(&mockContext, unifiedMemorySharedAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithAllocationSizeParamNameThenProperFieldsAreSet) { MockContext mockContext; cl_int retVal = CL_SUCCESS; size_t paramValueSize = sizeof(size_t); size_t paramValue = 0; size_t paramValueSizeRet = 0; auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, nullptr, 4, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); auto graphicsAllocation = allocationsManager->getSVMAlloc(unifiedMemoryHostAllocation); retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemoryHostAllocation, CL_MEM_ALLOC_SIZE_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::HOST_UNIFIED_MEMORY); EXPECT_EQ(graphicsAllocation->size, paramValue); EXPECT_EQ(sizeof(size_t), paramValueSizeRet); EXPECT_EQ(CL_SUCCESS, retVal); retVal = clMemFreeINTEL(&mockContext, unifiedMemoryHostAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithoutParamNameThenInvalidValueIsReturned) { MockContext mockContext; cl_int retVal = CL_SUCCESS; size_t paramValueSize = sizeof(cl_uint); cl_uint paramValue = 0; size_t paramValueSizeRet = 0; auto unifiedMemorySharedAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), nullptr, 4, 0, &retVal); retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemorySharedAllocation, 0, paramValueSize, ¶mValue, ¶mValueSizeRet); EXPECT_EQ(CL_INVALID_VALUE, retVal); retVal = clMemFreeINTEL(&mockContext, unifiedMemorySharedAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenClSetKernelArgMemPointerINTELisCalledWithInvalidKernelThenInvaliKernelErrorIsReturned) { auto retVal = clSetKernelArgMemPointerINTEL(0, 0, nullptr); EXPECT_EQ(CL_INVALID_KERNEL, retVal); } TEST(clUnifiedSharedMemoryTests, whenClSetKernelArgMemPointerINTELisCalledWithValidUnifiedMemoryAllocationThenProperFieldsAreSet) { auto mockContext = std::make_unique(); cl_int retVal = CL_SUCCESS; auto unfiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(mockContext.get(), mockContext->getDevice(0u), nullptr, 4, 0, &retVal); EXPECT_EQ(CL_SUCCESS, retVal); MockKernelWithInternals mockKernel(*mockContext->getDevice(0u), mockContext.get(), true); retVal = clSetKernelArgMemPointerINTEL(mockKernel.mockKernel, 0, unfiedMemoryDeviceAllocation); EXPECT_EQ(CL_SUCCESS, retVal); auto svmAlloc = mockContext->getSVMAllocsManager()->getSVMAlloc(unfiedMemoryDeviceAllocation); EXPECT_EQ(mockKernel.mockKernel->kernelArguments[0].object, svmAlloc->gpuAllocation); retVal = clMemFreeINTEL(mockContext.get(), unfiedMemoryDeviceAllocation); EXPECT_EQ(CL_SUCCESS, retVal); } TEST(clUnifiedSharedMemoryTests, whenclEnqueueMemsetINTELisCalledWithoutIncorrectCommandQueueThenInvaliQueueErrorIsReturned) { auto retVal = clEnqueueMemsetINTEL(0, nullptr, 0, 0, 0, nullptr, nullptr); EXPECT_EQ(CL_INVALID_COMMAND_QUEUE, retVal); } TEST(clUnifiedSharedMemoryTests, whenclEnqueueMemsetINTELisCalledWithProperParametersThenParametersArePassedCorrectly) { auto mockContext = std::make_unique(); cl_int retVal = CL_SUCCESS; auto unfiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(mockContext.get(), mockContext->getDevice(0u), nullptr, 400, 0, &retVal); struct MockedCommandQueue : public CommandQueue { cl_int enqueueSVMMemFill(void *svmPtr, const void *pattern, size_t patternSize, size_t size, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) override { EXPECT_EQ(12, *reinterpret_cast(pattern)); EXPECT_EQ(expectedDstPtr, svmPtr); EXPECT_EQ(400u, size); EXPECT_EQ(1u, patternSize); EXPECT_EQ(0u, numEventsInWaitList); EXPECT_EQ(nullptr, eventWaitList); EXPECT_EQ(nullptr, event); return CL_SUCCESS; } void *expectedDstPtr = nullptr; }; MockedCommandQueue queue; queue.expectedDstPtr = unfiedMemoryDeviceAllocation; cl_int setValue = 12u; retVal = clEnqueueMemsetINTEL(&queue, unfiedMemoryDeviceAllocation, setValue, 400u, 0, nullptr, nullptr); EXPECT_EQ(CL_SUCCESS, retVal); clMemFreeINTEL(mockContext.get(), unfiedMemoryDeviceAllocation); } TEST(clUnifiedSharedMemoryTests, whenClEnqueueMemcpyINTELisCalledWithWrongQueueThenInvalidQueueErrorIsReturned) { auto retVal = clEnqueueMemcpyINTEL(0, 0, nullptr, nullptr, 0, 0, nullptr, nullptr); EXPECT_EQ(CL_INVALID_COMMAND_QUEUE, retVal); } TEST(clUnifiedSharedMemoryTests, givenTwoUnifiedMemoryAllocationsWhenTheyAreCopiedThenProperParamtersArePassed) { auto mockContext = std::make_unique(); cl_int retVal = CL_SUCCESS; auto unfiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(mockContext.get(), mockContext->getDevice(0u), nullptr, 400, 0, &retVal); auto unfiedMemorySharedAllocation = clSharedMemAllocINTEL(mockContext.get(), mockContext->getDevice(0u), nullptr, 400, 0, &retVal); struct MockedCommandQueue : public CommandQueue { cl_int enqueueSVMMemcpy(cl_bool blockingCopy, void *dstPtr, const void *srcPtr, size_t size, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) override { EXPECT_EQ(0u, blockingCopy); EXPECT_EQ(expectedDstPtr, dstPtr); EXPECT_EQ(expectedSrcPtr, srcPtr); EXPECT_EQ(400u, size); EXPECT_EQ(0u, numEventsInWaitList); EXPECT_EQ(nullptr, eventWaitList); EXPECT_EQ(nullptr, event); return CL_SUCCESS; } void *expectedDstPtr = nullptr; const void *expectedSrcPtr = nullptr; }; MockedCommandQueue queue; queue.expectedDstPtr = unfiedMemoryDeviceAllocation; queue.expectedSrcPtr = unfiedMemorySharedAllocation; retVal = clEnqueueMemcpyINTEL(&queue, 0, unfiedMemoryDeviceAllocation, unfiedMemorySharedAllocation, 400u, 0, nullptr, nullptr); EXPECT_EQ(retVal, CL_SUCCESS); clMemFreeINTEL(mockContext.get(), unfiedMemoryDeviceAllocation); clMemFreeINTEL(mockContext.get(), unfiedMemorySharedAllocation); } TEST(clUnifiedSharedMemoryTests, whenClEnqueueMigrateMemINTELisCalledThenOutOfHostMemoryErrorIsReturned) { auto retVal = clEnqueueMigrateMemINTEL(0, nullptr, 0, 0, 0, nullptr, nullptr); EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal); } TEST(clUnifiedSharedMemoryTests, whenClEnqueueMemAdviseINTELisCalledThenOutOfHostMemoryErrorIsReturned) { auto retVal = clEnqueueMemAdviseINTEL(0, nullptr, 0, 0, 0, nullptr, nullptr); EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal); }