Skip to content

Commit 7a09c51

Browse files
fix(ocl): querying memobj offset
Querying buffer offset via clGetMemObjectInfo should not modify its value. Related-To: NEO-9690 Signed-off-by: Dominik Dabek <[email protected]>
1 parent 134c718 commit 7a09c51

File tree

3 files changed

+43
-17
lines changed

3 files changed

+43
-17
lines changed

opencl/source/mem_obj/mem_obj.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2018-2023 Intel Corporation
2+
* Copyright (C) 2018-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -127,6 +127,7 @@ cl_int MemObj::getMemObjectInfo(cl_mem_info paramName,
127127
size_t srcParamSize = GetInfo::invalidSourceSize;
128128
void *srcParam = nullptr;
129129
cl_bool usesSVMPointer;
130+
size_t clOffset = 0;
130131
cl_uint refCnt = 0;
131132
cl_uint mapCount = 0;
132133
cl_mem clAssociatedMemObject = static_cast<cl_mem>(this->associatedMemObject);
@@ -169,15 +170,16 @@ cl_int MemObj::getMemObjectInfo(cl_mem_info paramName,
169170
break;
170171

171172
case CL_MEM_OFFSET:
173+
clOffset = this->getOffset();
172174
if (nullptr != this->associatedMemObject) {
173175
if (this->getContext()->getBufferPoolAllocator().isPoolBuffer(this->associatedMemObject)) {
174-
offset = 0;
176+
clOffset = 0;
175177
} else {
176-
offset -= this->associatedMemObject->getOffset();
178+
clOffset -= this->associatedMemObject->getOffset();
177179
}
178180
}
179-
srcParamSize = sizeof(offset);
180-
srcParam = &offset;
181+
srcParamSize = sizeof(clOffset);
182+
srcParam = &clOffset;
181183
break;
182184

183185
case CL_MEM_ASSOCIATED_MEMOBJECT:

opencl/test/unit_test/mem_obj/buffer_pool_alloc_tests.cpp

+31-11
Original file line numberDiff line numberDiff line change
@@ -698,36 +698,56 @@ TEST_F(AggregatedSmallBuffersSubBufferApiTest, givenBufferFromPoolWhenCreateSubB
698698
}
699699

700700
TEST_F(AggregatedSmallBuffersSubBufferApiTest, givenSubBufferFromBufferPoolWhenGetMemObjInfoCalledThenReturnValuesLikeForNormalSubBuffer) {
701-
cl_mem buffer = clCreateBuffer(clContext, flags, size, hostPtr, &retVal);
702-
EXPECT_EQ(retVal, CL_SUCCESS);
703-
EXPECT_NE(buffer, nullptr);
704-
MockBuffer *mockBuffer = static_cast<MockBuffer *>(buffer);
705-
EXPECT_TRUE(context->getBufferPoolAllocator().isPoolBuffer(mockBuffer->associatedMemObject));
701+
cl_mem buffer{};
702+
cl_mem buffer1 = clCreateBuffer(clContext, flags, size, hostPtr, &retVal);
703+
EXPECT_EQ(CL_SUCCESS, retVal);
704+
EXPECT_NE(nullptr, buffer1);
705+
auto mockBuffer1 = static_cast<MockBuffer *>(buffer1);
706+
EXPECT_TRUE(context->getBufferPoolAllocator().isPoolBuffer(mockBuffer1->associatedMemObject));
707+
708+
// need buffer to have non-zero offset, to verify offset calculations in clGemMemObjectInfo
709+
// so if we get first pool buffer with offset 0, use a second buffer
710+
if (mockBuffer1->getOffset() != 0u) {
711+
buffer = buffer1;
712+
} else {
713+
cl_mem buffer2 = clCreateBuffer(clContext, flags, size, hostPtr, &retVal);
714+
EXPECT_EQ(CL_SUCCESS, retVal);
715+
EXPECT_NE(nullptr, buffer2);
716+
auto mockBuffer2 = static_cast<MockBuffer *>(buffer2);
717+
EXPECT_TRUE(context->getBufferPoolAllocator().isPoolBuffer(mockBuffer2->associatedMemObject));
718+
EXPECT_NE(0u, mockBuffer2->getOffset());
719+
buffer = buffer2;
720+
retVal = clReleaseMemObject(buffer1);
721+
EXPECT_EQ(retVal, CL_SUCCESS);
722+
}
706723

707724
cl_buffer_region region{};
708725
region.size = 1;
709726
region.origin = size / 2;
710727
cl_mem subBuffer = clCreateSubBuffer(buffer, flags, CL_BUFFER_CREATE_TYPE_REGION, &region, &retVal);
711-
EXPECT_EQ(retVal, CL_SUCCESS);
712-
EXPECT_NE(subBuffer, nullptr);
728+
EXPECT_EQ(CL_SUCCESS, retVal);
729+
EXPECT_NE(nullptr, subBuffer);
713730

714731
cl_mem associatedMemObj = nullptr;
715732
retVal = clGetMemObjectInfo(subBuffer, CL_MEM_ASSOCIATED_MEMOBJECT, sizeof(cl_mem), &associatedMemObj, nullptr);
716-
EXPECT_EQ(retVal, CL_SUCCESS);
733+
EXPECT_EQ(CL_SUCCESS, retVal);
717734
EXPECT_EQ(associatedMemObj, buffer);
718735

736+
auto mockSubBuffer = static_cast<MockBuffer *>(subBuffer);
737+
const auto offsetInternal = mockSubBuffer->getOffset();
719738
size_t offset = 0u;
720739
retVal = clGetMemObjectInfo(subBuffer, CL_MEM_OFFSET, sizeof(size_t), &offset, nullptr);
721-
EXPECT_EQ(retVal, CL_SUCCESS);
722-
EXPECT_EQ(offset, region.origin);
740+
EXPECT_EQ(CL_SUCCESS, retVal);
741+
EXPECT_EQ(region.origin, offset);
742+
EXPECT_EQ(offsetInternal, mockSubBuffer->getOffset()); // internal offset should not be modified after call
723743

724744
retVal = clReleaseMemObject(subBuffer);
725745
EXPECT_EQ(retVal, CL_SUCCESS);
726746

727747
retVal = clReleaseMemObject(buffer);
728748
EXPECT_EQ(retVal, CL_SUCCESS);
729749

730-
EXPECT_EQ(clReleaseContext(context), CL_SUCCESS);
750+
EXPECT_EQ(CL_SUCCESS, clReleaseContext(context));
731751
}
732752

733753
TEST_F(AggregatedSmallBuffersSubBufferApiTest, givenBufferFromPoolWhenCreateSubBufferCalledWithRegionOutsideBufferThenItFails) {

opencl/test/unit_test/mem_obj/get_mem_object_info_subbuffer_tests.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2021 Intel Corporation
2+
* Copyright (C) 2019-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -89,6 +89,10 @@ TEST_F(GetMemObjectSubBufferInfo, GivenMemOffsetWhenGettingMembojectInfoThenCorr
8989
retVal = subBuffer->getMemObjectInfo(CL_MEM_OFFSET, sizeof(offset), &offset, nullptr);
9090
EXPECT_EQ(CL_SUCCESS, retVal);
9191
EXPECT_EQ(region.origin, offset);
92+
93+
retVal = subBuffer->getMemObjectInfo(CL_MEM_OFFSET, sizeof(offset), &offset, nullptr);
94+
EXPECT_EQ(CL_SUCCESS, retVal);
95+
EXPECT_EQ(region.origin, offset);
9296
}
9397

9498
TEST_F(GetMemObjectSubBufferInfo, GivenMemFlagsWhenGettingMembojectInfoThenCorrectValueIsReturned) {

0 commit comments

Comments
 (0)