617 lines
24 KiB
C++
617 lines
24 KiB
C++
/*
|
|
* Copyright (C) 2018-2022 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#include "shared/test/common/mocks/mock_device.h"
|
|
#include "shared/test/common/mocks/mock_memory_manager.h"
|
|
|
|
#include "opencl/source/command_queue/command_queue.h"
|
|
#include "opencl/source/context/context.h"
|
|
#include "opencl/source/mem_obj/buffer.h"
|
|
#include "opencl/test/unit_test/mocks/mock_cl_device.h"
|
|
#include "opencl/test/unit_test/mocks/mock_kernel.h"
|
|
#include "opencl/test/unit_test/mocks/mock_program.h"
|
|
|
|
#include "cl_api_tests.h"
|
|
|
|
using namespace NEO;
|
|
|
|
typedef api_tests clCreateBufferTests;
|
|
|
|
namespace ClCreateBufferTests {
|
|
|
|
class ClCreateBufferTemplateTests : public ApiFixture<>,
|
|
public testing::TestWithParam<uint64_t> {
|
|
void SetUp() override {
|
|
ApiFixture::setUp();
|
|
}
|
|
|
|
void TearDown() override {
|
|
ApiFixture::tearDown();
|
|
}
|
|
};
|
|
|
|
struct clCreateBufferValidFlagsTests : public ClCreateBufferTemplateTests {
|
|
cl_uchar pHostPtr[64];
|
|
};
|
|
|
|
TEST_P(clCreateBufferValidFlagsTests, GivenValidFlagsWhenCreatingBufferThenBufferIsCreated) {
|
|
cl_mem_flags flags = GetParam() | CL_MEM_USE_HOST_PTR;
|
|
|
|
auto buffer = clCreateBuffer(pContext, flags, 64, pHostPtr, &retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
clReleaseMemObject(buffer);
|
|
|
|
cl_mem_properties_intel properties[] = {CL_MEM_FLAGS, flags, 0};
|
|
buffer = clCreateBufferWithPropertiesINTEL(pContext, properties, 0, 64, pHostPtr, &retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
clReleaseMemObject(buffer);
|
|
|
|
buffer = clCreateBufferWithPropertiesINTEL(pContext, nullptr, flags, 64, pHostPtr, &retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
clReleaseMemObject(buffer);
|
|
};
|
|
|
|
static cl_mem_flags validFlags[] = {
|
|
CL_MEM_READ_WRITE | CL_MEM_HOST_READ_ONLY,
|
|
CL_MEM_WRITE_ONLY,
|
|
CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY,
|
|
CL_MEM_HOST_READ_ONLY,
|
|
CL_MEM_HOST_WRITE_ONLY,
|
|
CL_MEM_HOST_NO_ACCESS,
|
|
CL_MEM_FORCE_HOST_MEMORY_INTEL};
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
CreateBufferCheckFlags,
|
|
clCreateBufferValidFlagsTests,
|
|
testing::ValuesIn(validFlags));
|
|
|
|
using clCreateBufferInvalidFlagsTests = ClCreateBufferTemplateTests;
|
|
|
|
TEST_P(clCreateBufferInvalidFlagsTests, GivenInvalidFlagsWhenCreatingBufferThenBufferIsNotCreated) {
|
|
cl_mem_flags flags = GetParam();
|
|
|
|
auto buffer = clCreateBuffer(pContext, flags, 64, nullptr, &retVal);
|
|
EXPECT_EQ(nullptr, buffer);
|
|
EXPECT_EQ(CL_INVALID_VALUE, retVal);
|
|
|
|
cl_mem_properties_intel properties[] = {CL_MEM_FLAGS, flags, 0};
|
|
buffer = clCreateBufferWithPropertiesINTEL(pContext, properties, 0, 64, nullptr, &retVal);
|
|
EXPECT_EQ(nullptr, buffer);
|
|
EXPECT_EQ(CL_INVALID_PROPERTY, retVal);
|
|
|
|
buffer = clCreateBufferWithPropertiesINTEL(pContext, nullptr, flags, 64, nullptr, &retVal);
|
|
EXPECT_EQ(nullptr, buffer);
|
|
EXPECT_EQ(CL_INVALID_VALUE, retVal);
|
|
};
|
|
|
|
cl_mem_flags invalidFlags[] = {
|
|
CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY,
|
|
CL_MEM_READ_WRITE | CL_MEM_READ_ONLY,
|
|
CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY,
|
|
CL_MEM_ALLOC_HOST_PTR | CL_MEM_USE_HOST_PTR,
|
|
CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
|
CL_MEM_HOST_NO_ACCESS | CL_MEM_HOST_WRITE_ONLY,
|
|
CL_MEM_HOST_NO_ACCESS | CL_MEM_HOST_READ_ONLY,
|
|
CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY,
|
|
0xffcc,
|
|
};
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
CreateBufferCheckFlags,
|
|
clCreateBufferInvalidFlagsTests,
|
|
testing::ValuesIn(invalidFlags));
|
|
|
|
using clCreateBufferValidFlagsIntelTests = ClCreateBufferTemplateTests;
|
|
|
|
TEST_P(clCreateBufferValidFlagsIntelTests, GivenValidFlagsIntelWhenCreatingBufferThenBufferIsCreated) {
|
|
cl_mem_properties_intel properties[] = {CL_MEM_FLAGS_INTEL, GetParam(), 0};
|
|
|
|
auto buffer = clCreateBufferWithPropertiesINTEL(pContext, properties, 0, 64, nullptr, &retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
|
|
clReleaseMemObject(buffer);
|
|
};
|
|
|
|
static cl_mem_flags validFlagsIntel[] = {
|
|
CL_MEM_LOCALLY_UNCACHED_RESOURCE,
|
|
CL_MEM_LOCALLY_UNCACHED_SURFACE_STATE_RESOURCE,
|
|
CL_MEM_48BIT_RESOURCE_INTEL};
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
CreateBufferCheckFlagsIntel,
|
|
clCreateBufferValidFlagsIntelTests,
|
|
testing::ValuesIn(validFlagsIntel));
|
|
|
|
using clCreateBufferInvalidFlagsIntelTests = ClCreateBufferTemplateTests;
|
|
|
|
TEST_P(clCreateBufferInvalidFlagsIntelTests, GivenInvalidFlagsIntelWhenCreatingBufferThenBufferIsNotCreated) {
|
|
cl_mem_properties_intel properties[] = {CL_MEM_FLAGS_INTEL, GetParam(), 0};
|
|
|
|
auto buffer = clCreateBufferWithPropertiesINTEL(pContext, properties, 0, 64, nullptr, &retVal);
|
|
EXPECT_EQ(nullptr, buffer);
|
|
EXPECT_EQ(CL_INVALID_PROPERTY, retVal);
|
|
};
|
|
|
|
cl_mem_flags invalidFlagsIntel[] = {
|
|
0xffcc,
|
|
};
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
CreateBufferCheckFlagsIntel,
|
|
clCreateBufferInvalidFlagsIntelTests,
|
|
testing::ValuesIn(invalidFlagsIntel));
|
|
|
|
using clCreateBufferInvalidProperties = ClCreateBufferTemplateTests;
|
|
|
|
TEST_F(clCreateBufferInvalidProperties, GivenInvalidPropertyKeyWhenCreatingBufferThenBufferIsNotCreated) {
|
|
cl_mem_properties_intel properties[] = {(cl_mem_properties_intel(1) << 31), 0, 0};
|
|
|
|
auto buffer = clCreateBufferWithPropertiesINTEL(pContext, properties, 0, 64, nullptr, &retVal);
|
|
EXPECT_EQ(nullptr, buffer);
|
|
EXPECT_EQ(CL_INVALID_PROPERTY, retVal);
|
|
};
|
|
|
|
TEST_F(clCreateBufferTests, GivenValidParametersWhenCreatingBufferThenSuccessIsReturned) {
|
|
cl_mem_flags flags = CL_MEM_USE_HOST_PTR;
|
|
static const unsigned int bufferSize = 16;
|
|
cl_mem buffer = nullptr;
|
|
|
|
unsigned char pHostMem[bufferSize];
|
|
memset(pHostMem, 0xaa, bufferSize);
|
|
|
|
buffer = clCreateBuffer(pContext, flags, bufferSize, pHostMem, &retVal);
|
|
|
|
ASSERT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenForceExtendedBufferSizeDebugFlagWhenBufferIsCreatedThenSizeIsProperlyExtended) {
|
|
DebugManagerStateRestore restorer;
|
|
|
|
unsigned char *pHostMem = nullptr;
|
|
cl_mem_flags flags = 0;
|
|
constexpr auto bufferSize = 16;
|
|
|
|
auto pageSizeNumber = 1;
|
|
DebugManager.flags.ForceExtendedBufferSize.set(pageSizeNumber);
|
|
auto extendedBufferSize = bufferSize + MemoryConstants::pageSize * pageSizeNumber;
|
|
|
|
auto buffer = clCreateBuffer(pContext, flags, bufferSize, pHostMem, &retVal);
|
|
|
|
EXPECT_NE(nullptr, buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
|
|
auto bufferObj = NEO::castToObject<Buffer>(buffer);
|
|
EXPECT_EQ(extendedBufferSize, bufferObj->getSize());
|
|
|
|
clReleaseMemObject(buffer);
|
|
|
|
pageSizeNumber = 4;
|
|
DebugManager.flags.ForceExtendedBufferSize.set(pageSizeNumber);
|
|
extendedBufferSize = bufferSize + MemoryConstants::pageSize * pageSizeNumber;
|
|
|
|
buffer = clCreateBufferWithProperties(pContext, nullptr, flags, bufferSize, pHostMem, &retVal);
|
|
|
|
EXPECT_NE(nullptr, buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
|
|
bufferObj = NEO::castToObject<Buffer>(buffer);
|
|
EXPECT_EQ(extendedBufferSize, bufferObj->getSize());
|
|
|
|
clReleaseMemObject(buffer);
|
|
|
|
pageSizeNumber = 6;
|
|
DebugManager.flags.ForceExtendedBufferSize.set(pageSizeNumber);
|
|
extendedBufferSize = bufferSize + MemoryConstants::pageSize * pageSizeNumber;
|
|
|
|
buffer = clCreateBufferWithPropertiesINTEL(pContext, nullptr, flags, bufferSize, pHostMem, &retVal);
|
|
|
|
EXPECT_NE(nullptr, buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
|
|
bufferObj = NEO::castToObject<Buffer>(buffer);
|
|
EXPECT_EQ(extendedBufferSize, bufferObj->getSize());
|
|
|
|
clReleaseMemObject(buffer);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenNullContextWhenCreatingBufferThenInvalidContextErrorIsReturned) {
|
|
unsigned char *pHostMem = nullptr;
|
|
cl_mem_flags flags = 0;
|
|
static const unsigned int bufferSize = 16;
|
|
|
|
clCreateBuffer(nullptr, flags, bufferSize, pHostMem, &retVal);
|
|
ASSERT_EQ(CL_INVALID_CONTEXT, retVal);
|
|
|
|
clCreateBufferWithPropertiesINTEL(nullptr, nullptr, 0, bufferSize, pHostMem, &retVal);
|
|
ASSERT_EQ(CL_INVALID_CONTEXT, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenBufferSizeZeroWhenCreatingBufferThenInvalidBufferSizeErrorIsReturned) {
|
|
uint8_t hostData = 0;
|
|
clCreateBuffer(pContext, CL_MEM_USE_HOST_PTR, 0, &hostData, &retVal);
|
|
ASSERT_EQ(CL_INVALID_BUFFER_SIZE, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenInvalidHostPointerWhenCreatingBufferThenInvalidHostPointerErrorIsReturned) {
|
|
uint32_t hostData = 0;
|
|
cl_mem_flags flags = 0;
|
|
clCreateBuffer(pContext, flags, sizeof(uint32_t), &hostData, &retVal);
|
|
ASSERT_EQ(CL_INVALID_HOST_PTR, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenNullHostPointerAndMemCopyHostPtrFlagWhenCreatingBufferThenInvalidHostPointerErrorIsReturned) {
|
|
cl_mem_flags flags = CL_MEM_COPY_HOST_PTR;
|
|
clCreateBuffer(pContext, flags, sizeof(uint32_t), nullptr, &retVal);
|
|
ASSERT_EQ(CL_INVALID_HOST_PTR, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenNullHostPointerAndMemUseHostPtrFlagWhenCreatingBufferThenInvalidHostPointerErrorIsReturned) {
|
|
cl_mem_flags flags = CL_MEM_USE_HOST_PTR;
|
|
clCreateBuffer(pContext, flags, sizeof(uint32_t), nullptr, &retVal);
|
|
ASSERT_EQ(CL_INVALID_HOST_PTR, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenMemWriteOnlyFlagAndMemReadWriteFlagWhenCreatingBufferThenInvalidValueErrorIsReturned) {
|
|
cl_mem_flags flags = CL_MEM_WRITE_ONLY | CL_MEM_READ_WRITE;
|
|
clCreateBuffer(pContext, flags, 16, nullptr, &retVal);
|
|
ASSERT_EQ(CL_INVALID_VALUE, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeWhenCreatingBufferThenInvalidBufferSizeErrorIsReturned) {
|
|
auto pDevice = pContext->getDevice(0);
|
|
size_t size = static_cast<size_t>(pDevice->getDevice().getDeviceInfo().maxMemAllocSize) + 1;
|
|
|
|
auto buffer = clCreateBuffer(pContext, CL_MEM_ALLOC_HOST_PTR, size, nullptr, &retVal);
|
|
EXPECT_EQ(CL_INVALID_BUFFER_SIZE, retVal);
|
|
EXPECT_EQ(nullptr, buffer);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeWhenCreateBufferWithPropertiesINTELThenInvalidBufferSizeErrorIsReturned) {
|
|
auto pDevice = pContext->getDevice(0);
|
|
size_t size = static_cast<size_t>(pDevice->getDevice().getDeviceInfo().maxMemAllocSize) + 1;
|
|
|
|
auto buffer = clCreateBufferWithPropertiesINTEL(pContext, nullptr, 0, size, nullptr, &retVal);
|
|
EXPECT_EQ(CL_INVALID_BUFFER_SIZE, retVal);
|
|
EXPECT_EQ(nullptr, buffer);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeAndClMemAllowUnrestirctedSizeFlagWhenCreatingBufferThenClSuccessIsReturned) {
|
|
auto pDevice = pContext->getDevice(0);
|
|
uint64_t bigSize = GB * 5;
|
|
size_t size = static_cast<size_t>(bigSize);
|
|
cl_mem_flags flags = CL_MEM_ALLOC_HOST_PTR | CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL;
|
|
auto memoryManager = static_cast<OsAgnosticMemoryManager *>(pDevice->getMemoryManager());
|
|
memoryManager->turnOnFakingBigAllocations();
|
|
|
|
if (memoryManager->peekForce32BitAllocations() || is32bit) {
|
|
GTEST_SKIP();
|
|
}
|
|
|
|
auto buffer = clCreateBuffer(pContext, flags, size, nullptr, &retVal);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeAndClMemAllowUnrestirctedSizeFlagWhenCreatingBufferWithPropertiesINTELThenClSuccesssIsReturned) {
|
|
auto pDevice = pContext->getDevice(0);
|
|
uint64_t bigSize = GB * 5;
|
|
size_t size = static_cast<size_t>(bigSize);
|
|
cl_mem_properties_intel properties[] = {CL_MEM_FLAGS_INTEL, CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL, 0};
|
|
|
|
auto memoryManager = static_cast<OsAgnosticMemoryManager *>(pDevice->getMemoryManager());
|
|
memoryManager->turnOnFakingBigAllocations();
|
|
|
|
if (memoryManager->peekForce32BitAllocations() || is32bit) {
|
|
GTEST_SKIP();
|
|
}
|
|
|
|
auto buffer = clCreateBufferWithPropertiesINTEL(pContext, properties, 0, size, nullptr, &retVal);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeAndDebugFlagSetWhenCreatingBufferThenClSuccessIsReturned) {
|
|
DebugManagerStateRestore restorer;
|
|
DebugManager.flags.AllowUnrestrictedSize.set(1);
|
|
auto pDevice = pContext->getDevice(0);
|
|
size_t size = static_cast<size_t>(pDevice->getDevice().getDeviceInfo().maxMemAllocSize) + 1;
|
|
auto memoryManager = static_cast<OsAgnosticMemoryManager *>(pDevice->getMemoryManager());
|
|
memoryManager->turnOnFakingBigAllocations();
|
|
|
|
if (memoryManager->peekForce32BitAllocations() || is32bit) {
|
|
GTEST_SKIP();
|
|
}
|
|
|
|
auto buffer = clCreateBuffer(pContext, 0, size, nullptr, &retVal);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenNullHostPointerAndMemCopyHostPtrFlagWhenCreatingBufferThenNullIsReturned) {
|
|
cl_mem_flags flags = CL_MEM_USE_HOST_PTR;
|
|
static const unsigned int bufferSize = 16;
|
|
cl_mem buffer = nullptr;
|
|
|
|
unsigned char pHostMem[bufferSize];
|
|
memset(pHostMem, 0xaa, bufferSize);
|
|
|
|
buffer = clCreateBuffer(pContext, flags, bufferSize, pHostMem, nullptr);
|
|
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, WhenCreatingBufferWithPropertiesThenParametersAreCorrectlyPassed) {
|
|
VariableBackup<BufferFunctions::ValidateInputAndCreateBufferFunc> bufferCreateBackup{&BufferFunctions::validateInputAndCreateBuffer};
|
|
|
|
cl_context context = pContext;
|
|
cl_mem_properties *propertiesValues[] = {nullptr, reinterpret_cast<cl_mem_properties *>(0x1234)};
|
|
cl_mem_flags flagsValues[] = {0, 4321};
|
|
size_t bufferSize = 128;
|
|
void *pHostMem = reinterpret_cast<void *>(0x8000);
|
|
|
|
for (auto properties : propertiesValues) {
|
|
for (auto flags : flagsValues) {
|
|
auto mockFunction = [context, properties, flags, bufferSize, pHostMem](cl_context contextArg,
|
|
const cl_mem_properties *propertiesArg,
|
|
cl_mem_flags flagsArg,
|
|
cl_mem_flags_intel flagsIntelArg,
|
|
size_t sizeArg,
|
|
void *hostPtrArg,
|
|
cl_int &retValArg) -> cl_mem {
|
|
cl_mem_flags_intel expectedFlagsIntelArg = 0;
|
|
|
|
EXPECT_EQ(context, contextArg);
|
|
EXPECT_EQ(properties, propertiesArg);
|
|
EXPECT_EQ(flags, flagsArg);
|
|
EXPECT_EQ(expectedFlagsIntelArg, flagsIntelArg);
|
|
EXPECT_EQ(bufferSize, sizeArg);
|
|
EXPECT_EQ(pHostMem, hostPtrArg);
|
|
|
|
return nullptr;
|
|
};
|
|
bufferCreateBackup = mockFunction;
|
|
clCreateBufferWithProperties(context, properties, flags, bufferSize, pHostMem, nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, WhenCreatingBufferWithPropertiesThenErrorCodeIsCorrectlySet) {
|
|
VariableBackup<BufferFunctions::ValidateInputAndCreateBufferFunc> bufferCreateBackup{&BufferFunctions::validateInputAndCreateBuffer};
|
|
|
|
cl_mem_properties *properties = nullptr;
|
|
cl_mem_flags flags = 0;
|
|
size_t bufferSize = 128;
|
|
void *pHostMem = nullptr;
|
|
cl_int errcodeRet;
|
|
|
|
cl_int retValues[] = {CL_SUCCESS, CL_INVALID_PROPERTY};
|
|
|
|
for (auto retValue : retValues) {
|
|
auto mockFunction = [retValue](cl_context contextArg,
|
|
const cl_mem_properties *propertiesArg,
|
|
cl_mem_flags flagsArg,
|
|
cl_mem_flags_intel flagsIntelArg,
|
|
size_t sizeArg,
|
|
void *hostPtrArg,
|
|
cl_int &retValArg) -> cl_mem {
|
|
retValArg = retValue;
|
|
|
|
return nullptr;
|
|
};
|
|
bufferCreateBackup = mockFunction;
|
|
clCreateBufferWithProperties(pContext, properties, flags, bufferSize, pHostMem, &errcodeRet);
|
|
EXPECT_EQ(retValue, errcodeRet);
|
|
}
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, GivenBufferCreatedWithNullPropertiesWhenQueryingPropertiesThenNothingIsReturned) {
|
|
cl_int retVal = CL_SUCCESS;
|
|
size_t size = 10;
|
|
auto buffer = clCreateBufferWithPropertiesINTEL(pContext, nullptr, 0, size, nullptr, &retVal);
|
|
EXPECT_EQ(retVal, CL_SUCCESS);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
size_t propertiesSize;
|
|
retVal = clGetMemObjectInfo(buffer, CL_MEM_PROPERTIES, 0, nullptr, &propertiesSize);
|
|
EXPECT_EQ(retVal, CL_SUCCESS);
|
|
EXPECT_EQ(0u, propertiesSize);
|
|
|
|
clReleaseMemObject(buffer);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTests, WhenCreatingBufferWithPropertiesThenPropertiesAreCorrectlyStored) {
|
|
cl_int retVal = CL_SUCCESS;
|
|
size_t size = 10;
|
|
cl_mem_properties properties[5];
|
|
size_t propertiesSize;
|
|
|
|
std::vector<std::vector<uint64_t>> propertiesToTest{
|
|
{0},
|
|
{CL_MEM_FLAGS, CL_MEM_WRITE_ONLY, 0},
|
|
{CL_MEM_FLAGS_INTEL, CL_MEM_LOCALLY_UNCACHED_RESOURCE, 0},
|
|
{CL_MEM_FLAGS, CL_MEM_WRITE_ONLY, CL_MEM_FLAGS_INTEL, CL_MEM_LOCALLY_UNCACHED_RESOURCE, 0}};
|
|
|
|
for (auto testProperties : propertiesToTest) {
|
|
auto buffer = clCreateBufferWithPropertiesINTEL(pContext, testProperties.data(), 0, size, nullptr, &retVal);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
retVal = clGetMemObjectInfo(buffer, CL_MEM_PROPERTIES, sizeof(properties), properties, &propertiesSize);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_EQ(testProperties.size() * sizeof(cl_mem_properties), propertiesSize);
|
|
for (size_t i = 0; i < testProperties.size(); i++) {
|
|
EXPECT_EQ(testProperties[i], properties[i]);
|
|
}
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
}
|
|
}
|
|
|
|
using clCreateBufferTestsWithRestrictions = api_test_using_aligned_memory_manager;
|
|
|
|
TEST_F(clCreateBufferTestsWithRestrictions, GivenMemoryManagerRestrictionsWhenMinIsLessThanHostPtrThenUseZeroCopy) {
|
|
std::unique_ptr<unsigned char[]> hostMem(nullptr);
|
|
unsigned char *destMem = nullptr;
|
|
cl_mem_flags flags = CL_MEM_USE_HOST_PTR;
|
|
const unsigned int bufferSize = MemoryConstants::pageSize * 3;
|
|
const unsigned int destBufferSize = MemoryConstants::pageSize;
|
|
cl_mem buffer = nullptr;
|
|
|
|
uintptr_t minAddress = 0;
|
|
MockAllocSysMemAgnosticMemoryManager *memMngr = reinterpret_cast<MockAllocSysMemAgnosticMemoryManager *>(device->getMemoryManager());
|
|
memMngr->ptrRestrictions = &memMngr->testRestrictions;
|
|
EXPECT_EQ(minAddress, memMngr->ptrRestrictions->minAddress);
|
|
|
|
hostMem.reset(new unsigned char[bufferSize]);
|
|
|
|
destMem = hostMem.get();
|
|
destMem += MemoryConstants::pageSize;
|
|
destMem -= (reinterpret_cast<uintptr_t>(destMem) % MemoryConstants::pageSize);
|
|
|
|
buffer = clCreateBuffer(context, flags, destBufferSize, destMem, &retVal);
|
|
|
|
ASSERT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
Buffer *bufferObj = NEO::castToObject<Buffer>(buffer);
|
|
EXPECT_TRUE(bufferObj->isMemObjZeroCopy());
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
}
|
|
|
|
TEST_F(clCreateBufferTestsWithRestrictions, GivenMemoryManagerRestrictionsWhenMinIsLessThanHostPtrThenCreateCopy) {
|
|
std::unique_ptr<unsigned char[]> hostMem(nullptr);
|
|
unsigned char *destMem = nullptr;
|
|
cl_mem_flags flags = CL_MEM_USE_HOST_PTR;
|
|
const unsigned int realBufferSize = MemoryConstants::pageSize * 3;
|
|
const unsigned int destBufferSize = MemoryConstants::pageSize;
|
|
cl_mem buffer = nullptr;
|
|
|
|
MockAllocSysMemAgnosticMemoryManager *memMngr = reinterpret_cast<MockAllocSysMemAgnosticMemoryManager *>(device->getMemoryManager());
|
|
memMngr->ptrRestrictions = &memMngr->testRestrictions;
|
|
|
|
hostMem.reset(new unsigned char[realBufferSize]);
|
|
|
|
destMem = hostMem.get();
|
|
destMem += MemoryConstants::pageSize;
|
|
destMem -= (reinterpret_cast<uintptr_t>(destMem) % MemoryConstants::pageSize);
|
|
memMngr->ptrRestrictions->minAddress = reinterpret_cast<uintptr_t>(destMem) + 1;
|
|
|
|
buffer = clCreateBuffer(context, flags, destBufferSize, destMem, &retVal);
|
|
|
|
ASSERT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
Buffer *bufferObj = NEO::castToObject<Buffer>(buffer);
|
|
EXPECT_FALSE(bufferObj->isMemObjZeroCopy());
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
}
|
|
|
|
using clCreateBufferWithMultiDeviceContextTests = ClCreateBufferTemplateTests;
|
|
|
|
TEST_P(clCreateBufferWithMultiDeviceContextTests, GivenBufferCreatedWithContextdWithMultiDeviceThenGraphicsAllocationsAreProperlyFilled) {
|
|
UltClDeviceFactory deviceFactory{2, 0};
|
|
DebugManager.flags.EnableMultiRootDeviceContexts.set(true);
|
|
|
|
cl_device_id devices[] = {deviceFactory.rootDevices[0], deviceFactory.rootDevices[1]};
|
|
auto context = clCreateContext(nullptr, 2u, devices, nullptr, nullptr, &retVal);
|
|
EXPECT_NE(nullptr, context);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
|
|
auto pContext = castToObject<Context>(context);
|
|
|
|
EXPECT_EQ(1u, pContext->getMaxRootDeviceIndex());
|
|
|
|
constexpr auto bufferSize = 64u;
|
|
|
|
auto hostBuffer = alignedMalloc(bufferSize, MemoryConstants::pageSize64k);
|
|
auto ptrHostBuffer = static_cast<uint8_t *>(hostBuffer);
|
|
|
|
cl_mem_flags flags = GetParam();
|
|
|
|
auto buffer = clCreateBuffer(context, flags, bufferSize, flags == 0 ? nullptr : ptrHostBuffer, &retVal);
|
|
ASSERT_EQ(CL_SUCCESS, retVal);
|
|
EXPECT_NE(nullptr, buffer);
|
|
|
|
Buffer *bufferObj = NEO::castToObject<Buffer>(buffer);
|
|
|
|
EXPECT_EQ(bufferObj->getMultiGraphicsAllocation().getGraphicsAllocations().size(), 2u);
|
|
EXPECT_NE(bufferObj->getMultiGraphicsAllocation().getGraphicsAllocation(0u), nullptr);
|
|
EXPECT_NE(bufferObj->getMultiGraphicsAllocation().getGraphicsAllocation(1u), nullptr);
|
|
EXPECT_NE(bufferObj->getMultiGraphicsAllocation().getGraphicsAllocation(0u), bufferObj->getMultiGraphicsAllocation().getGraphicsAllocation(1u));
|
|
|
|
alignedFree(hostBuffer);
|
|
|
|
retVal = clReleaseMemObject(buffer);
|
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
|
|
|
clReleaseContext(context);
|
|
}
|
|
|
|
static cl_mem_flags validFlagsForMultiDeviceContextBuffer[] = {
|
|
CL_MEM_USE_HOST_PTR,
|
|
CL_MEM_COPY_HOST_PTR, 0};
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
CreateBufferWithMultiDeviceContextCheckFlags,
|
|
clCreateBufferWithMultiDeviceContextTests,
|
|
testing::ValuesIn(validFlagsForMultiDeviceContextBuffer));
|
|
|
|
using clCreateBufferWithMultiDeviceContextFaillingAllocationTests = ClCreateBufferTemplateTests;
|
|
|
|
TEST_F(clCreateBufferWithMultiDeviceContextFaillingAllocationTests, GivenContextdWithMultiDeviceFailingAllocationThenBufferAllocateFails) {
|
|
UltClDeviceFactory deviceFactory{3, 0};
|
|
DebugManager.flags.EnableMultiRootDeviceContexts.set(true);
|
|
|
|
cl_device_id devices[] = {deviceFactory.rootDevices[0], deviceFactory.rootDevices[1], deviceFactory.rootDevices[2]};
|
|
|
|
MockContext pContext(ClDeviceVector(devices, 3));
|
|
|
|
EXPECT_EQ(2u, pContext.getMaxRootDeviceIndex());
|
|
|
|
constexpr auto bufferSize = 64u;
|
|
|
|
auto hostBuffer = alignedMalloc(bufferSize, MemoryConstants::pageSize64k);
|
|
auto ptrHostBuffer = static_cast<uint8_t *>(hostBuffer);
|
|
|
|
cl_mem_flags flags = CL_MEM_USE_HOST_PTR;
|
|
|
|
static_cast<MockMemoryManager *>(pContext.memoryManager)->successAllocatedGraphicsMemoryIndex = 0u;
|
|
static_cast<MockMemoryManager *>(pContext.memoryManager)->maxSuccessAllocatedGraphicsMemoryIndex = 2u;
|
|
|
|
auto buffer = clCreateBuffer(&pContext, flags, bufferSize, ptrHostBuffer, &retVal);
|
|
ASSERT_EQ(CL_OUT_OF_HOST_MEMORY, retVal);
|
|
EXPECT_EQ(nullptr, buffer);
|
|
|
|
alignedFree(hostBuffer);
|
|
}
|
|
|
|
} // namespace ClCreateBufferTests
|