Skip to content

Commit 19e9941

Browse files
authored
[SYCL] Improve mock PI plugin (#7198)
The patch adds more logic to default redefinitions of PI APIs: 1. Allocate, refcount and deallocate various handles 2. Handle sub-buffer creation Also the patch adds support for adding PI functions to be called in addition (before or after) to the original function. This allows intercepting PI API calls for introspection while still allowing original function take care of handles. Or add some post processing of the returned values.
1 parent a11a5ed commit 19e9941

38 files changed

+729
-581
lines changed

sycl/unittests/SYCL2020/GetNativeOpenCL.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,18 @@ TEST(GetNative, GetNativeHandle) {
8686
sycl::unittest::PiMock Mock;
8787
sycl::platform Plt = Mock.getPlatform();
8888

89-
Mock.redefine<detail::PiApiKind::piEventGetInfo>(redefinedEventGetInfo);
90-
Mock.redefine<detail::PiApiKind::piContextRetain>(redefinedContextRetain);
91-
Mock.redefine<detail::PiApiKind::piQueueRetain>(redefinedQueueRetain);
92-
Mock.redefine<detail::PiApiKind::piDeviceRetain>(redefinedDeviceRetain);
93-
Mock.redefine<detail::PiApiKind::piProgramRetain>(redefinedProgramRetain);
94-
Mock.redefine<detail::PiApiKind::piEventRetain>(redefinedEventRetain);
95-
Mock.redefine<detail::PiApiKind::piMemRetain>(redefinedMemRetain);
96-
Mock.redefine<sycl::detail::PiApiKind::piMemBufferCreate>(
89+
Mock.redefineBefore<detail::PiApiKind::piEventGetInfo>(redefinedEventGetInfo);
90+
Mock.redefineBefore<detail::PiApiKind::piContextRetain>(
91+
redefinedContextRetain);
92+
Mock.redefineBefore<detail::PiApiKind::piQueueRetain>(redefinedQueueRetain);
93+
Mock.redefineBefore<detail::PiApiKind::piDeviceRetain>(redefinedDeviceRetain);
94+
Mock.redefineBefore<detail::PiApiKind::piProgramRetain>(
95+
redefinedProgramRetain);
96+
Mock.redefineBefore<detail::PiApiKind::piEventRetain>(redefinedEventRetain);
97+
Mock.redefineBefore<detail::PiApiKind::piMemRetain>(redefinedMemRetain);
98+
Mock.redefineBefore<sycl::detail::PiApiKind::piMemBufferCreate>(
9799
redefinedMemBufferCreate);
98-
Mock.redefine<detail::PiApiKind::piextUSMEnqueueMemset>(
100+
Mock.redefineBefore<detail::PiApiKind::piextUSMEnqueueMemset>(
99101
redefinedUSMEnqueueMemset);
100102

101103
context Context(Plt);

sycl/unittests/assert/assert.cpp

Lines changed: 48 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,9 @@ static int MemoryMapCounter = MemoryMapCounterBase;
175175
static constexpr int PauseWaitOnIdx = KernelLaunchCounterBase + 1;
176176

177177
// Mock redifinitions
178-
static pi_result redefinedKernelGetGroupInfo(pi_kernel kernel, pi_device device,
179-
pi_kernel_group_info param_name,
180-
size_t param_value_size,
181-
void *param_value,
182-
size_t *param_value_size_ret) {
178+
static pi_result redefinedKernelGetGroupInfoAfter(
179+
pi_kernel kernel, pi_device device, pi_kernel_group_info param_name,
180+
size_t param_value_size, void *param_value, size_t *param_value_size_ret) {
183181
if (param_name == PI_KERNEL_GROUP_INFO_COMPILE_WORK_GROUP_SIZE) {
184182
if (param_value_size_ret) {
185183
*param_value_size_ret = 3 * sizeof(size_t);
@@ -194,25 +192,23 @@ static pi_result redefinedKernelGetGroupInfo(pi_kernel kernel, pi_device device,
194192
return PI_SUCCESS;
195193
}
196194

197-
static pi_result redefinedEnqueueKernelLaunch(pi_queue, pi_kernel, pi_uint32,
198-
const size_t *, const size_t *,
199-
const size_t *LocalSize,
200-
pi_uint32 N, const pi_event *Deps,
201-
pi_event *RetEvent) {
202-
int *Ret = new int[1];
203-
*Ret = KernelLaunchCounter++;
195+
static pi_result
196+
redefinedEnqueueKernelLaunchAfter(pi_queue, pi_kernel, pi_uint32,
197+
const size_t *, const size_t *,
198+
const size_t *LocalSize, pi_uint32 NDeps,
199+
const pi_event *Deps, pi_event *RetEvent) {
200+
static pi_event UserKernelEvent = *RetEvent;
201+
int Val = KernelLaunchCounter++;
204202
// This output here is to reduce amount of time requried to debug/reproduce a
205203
// failing test upon feature break
206-
printf("Enqueued %i\n", *Ret);
204+
printf("Enqueued %i\n", Val);
207205

208-
if (PauseWaitOnIdx == *Ret) {
206+
if (PauseWaitOnIdx == Val) {
209207
// It should be copier kernel. Check if it depends on user's one.
210-
EXPECT_EQ(N, 1U);
211-
int EventIdx = reinterpret_cast<int *>(Deps[0])[0];
212-
EXPECT_EQ(EventIdx, 0);
208+
EXPECT_EQ(NDeps, 1U);
209+
EXPECT_EQ(Deps[0], UserKernelEvent);
213210
}
214211

215-
*RetEvent = reinterpret_cast<pi_event>(Ret);
216212
return PI_SUCCESS;
217213
}
218214

@@ -243,56 +239,30 @@ static pi_result redefinedEventsWaitNegative(pi_uint32 num_events,
243239
return PI_SUCCESS;
244240
}
245241

246-
static pi_result
247-
redefinedMemBufferCreate(pi_context context, pi_mem_flags flags, size_t size,
248-
void *host_ptr, pi_mem *ret_mem,
249-
const pi_mem_properties *properties = nullptr) {
250-
static size_t MemAddrCounter = 1;
251-
*ret_mem = (pi_mem)MemAddrCounter++;
252-
return PI_SUCCESS;
253-
}
254-
255-
static pi_result redefinedMemRelease(pi_mem mem) { return PI_SUCCESS; }
256-
257-
static pi_result redefinedKernelSetArg(pi_kernel kernel, pi_uint32 arg_index,
258-
size_t arg_size, const void *arg_value) {
259-
return PI_SUCCESS;
260-
}
261-
262-
static pi_result redefinedEnqueueMemBufferMap(
242+
static pi_result redefinedEnqueueMemBufferMapAfter(
263243
pi_queue command_queue, pi_mem buffer, pi_bool blocking_map,
264244
pi_map_flags map_flags, size_t offset, size_t size,
265245
pi_uint32 num_events_in_wait_list, const pi_event *event_wait_list,
266246
pi_event *RetEvent, void **RetMap) {
267-
int *Ret = new int[1];
268-
*Ret = MemoryMapCounter++;
247+
MemoryMapCounter++;
269248
// This output here is to reduce amount of time requried to debug/reproduce a
270249
// failing test upon feature break
271-
printf("Memory map %i\n", *Ret);
272-
*RetEvent = reinterpret_cast<pi_event>(Ret);
250+
printf("Memory map %i\n", MemoryMapCounter);
273251

274252
*RetMap = (void *)&ExpectedToOutput;
275253

276254
return PI_SUCCESS;
277255
}
278256

279-
static pi_result redefinedExtKernelSetArgMemObj(pi_kernel kernel,
280-
pi_uint32 arg_index,
281-
const pi_mem *arg_value) {
282-
return PI_SUCCESS;
283-
}
284-
285257
static void setupMock(sycl::unittest::PiMock &Mock) {
286258
using namespace sycl::detail;
287-
Mock.redefine<PiApiKind::piKernelGetGroupInfo>(redefinedKernelGetGroupInfo);
288-
Mock.redefine<PiApiKind::piEnqueueKernelLaunch>(redefinedEnqueueKernelLaunch);
289-
Mock.redefine<PiApiKind::piMemBufferCreate>(redefinedMemBufferCreate);
290-
Mock.redefine<PiApiKind::piMemRelease>(redefinedMemRelease);
291-
Mock.redefine<PiApiKind::piKernelSetArg>(redefinedKernelSetArg);
292-
Mock.redefine<PiApiKind::piEnqueueMemBufferMap>(redefinedEnqueueMemBufferMap);
293-
Mock.redefine<PiApiKind::piEventsWait>(redefinedEventsWaitPositive);
294-
Mock.redefine<PiApiKind::piextKernelSetArgMemObj>(
295-
redefinedExtKernelSetArgMemObj);
259+
Mock.redefineAfter<PiApiKind::piKernelGetGroupInfo>(
260+
redefinedKernelGetGroupInfoAfter);
261+
Mock.redefineAfter<PiApiKind::piEnqueueKernelLaunch>(
262+
redefinedEnqueueKernelLaunchAfter);
263+
Mock.redefineAfter<PiApiKind::piEnqueueMemBufferMap>(
264+
redefinedEnqueueMemBufferMapAfter);
265+
Mock.redefineBefore<PiApiKind::piEventsWait>(redefinedEventsWaitPositive);
296266
}
297267

298268
namespace TestInteropKernel {
@@ -317,12 +287,15 @@ static pi_result redefinedKernelGetInfo(pi_kernel Kernel,
317287
}
318288

319289
if (PI_KERNEL_INFO_PROGRAM == ParamName) {
320-
cl_program X = (cl_program)1;
290+
pi_program PIProgram = nullptr;
291+
pi_result Res = mock_piProgramCreate(/*pi_context=*/0x0, /**il*/ nullptr,
292+
/*length=*/0, &PIProgram);
293+
assert(PI_SUCCESS == Res);
321294

322295
if (ParamValue)
323-
memcpy(ParamValue, &X, sizeof(X));
296+
memcpy(ParamValue, &PIProgram, sizeof(PIProgram));
324297
if (ParamValueSizeRet)
325-
*ParamValueSizeRet = sizeof(X);
298+
*ParamValueSizeRet = sizeof(PIProgram);
326299

327300
return PI_SUCCESS;
328301
}
@@ -350,13 +323,11 @@ static pi_result redefinedEnqueueKernelLaunch(pi_queue, pi_kernel, pi_uint32,
350323
const size_t *LocalSize,
351324
pi_uint32 N, const pi_event *Deps,
352325
pi_event *RetEvent) {
353-
int *Ret = new int[1];
354-
*Ret = KernelLaunchCounter++;
326+
int Val = KernelLaunchCounter++;
355327
// This output here is to reduce amount of time requried to debug/reproduce a
356328
// failing test upon feature break
357-
printf("Enqueued %i\n", *Ret);
329+
printf("Enqueued %i\n", Val);
358330

359-
*RetEvent = reinterpret_cast<pi_event>(Ret);
360331
return PI_SUCCESS;
361332
}
362333

@@ -426,21 +397,18 @@ static void setupMockForInterop(sycl::unittest::PiMock &Mock,
426397
TestInteropKernel::Device = &Dev;
427398
TestInteropKernel::Context = &Ctx;
428399

429-
Mock.redefine<PiApiKind::piKernelGetGroupInfo>(redefinedKernelGetGroupInfo);
430-
Mock.redefine<PiApiKind::piEnqueueKernelLaunch>(
400+
Mock.redefineAfter<PiApiKind::piKernelGetGroupInfo>(
401+
redefinedKernelGetGroupInfoAfter);
402+
Mock.redefineBefore<PiApiKind::piEnqueueKernelLaunch>(
431403
TestInteropKernel::redefinedEnqueueKernelLaunch);
432-
Mock.redefine<PiApiKind::piMemBufferCreate>(redefinedMemBufferCreate);
433-
Mock.redefine<PiApiKind::piMemRelease>(redefinedMemRelease);
434-
Mock.redefine<PiApiKind::piKernelSetArg>(redefinedKernelSetArg);
435-
Mock.redefine<PiApiKind::piEnqueueMemBufferMap>(redefinedEnqueueMemBufferMap);
436-
Mock.redefine<PiApiKind::piEventsWait>(redefinedEventsWaitNegative);
437-
Mock.redefine<PiApiKind::piextKernelSetArgMemObj>(
438-
redefinedExtKernelSetArgMemObj);
439-
Mock.redefine<PiApiKind::piKernelGetInfo>(
404+
Mock.redefineAfter<PiApiKind::piEnqueueMemBufferMap>(
405+
redefinedEnqueueMemBufferMapAfter);
406+
Mock.redefineBefore<PiApiKind::piEventsWait>(redefinedEventsWaitNegative);
407+
Mock.redefineBefore<PiApiKind::piKernelGetInfo>(
440408
TestInteropKernel::redefinedKernelGetInfo);
441-
Mock.redefine<PiApiKind::piProgramGetInfo>(
409+
Mock.redefineBefore<PiApiKind::piProgramGetInfo>(
442410
TestInteropKernel::redefinedProgramGetInfo);
443-
Mock.redefine<PiApiKind::piProgramGetBuildInfo>(
411+
Mock.redefineBefore<PiApiKind::piProgramGetBuildInfo>(
444412
TestInteropKernel::redefinedProgramGetBuildInfo);
445413
}
446414

@@ -581,10 +549,15 @@ TEST(Assert, TestInteropKernelNegative) {
581549

582550
sycl::queue Queue{Ctx, Dev};
583551

584-
cl_kernel CLKernel = (cl_kernel)(0x01);
552+
pi_kernel PIKernel = nullptr;
553+
554+
pi_result Res = mock_piKernelCreate(
555+
/*pi_program=*/0x0, /*kernel_name=*/"dummy_kernel", &PIKernel);
556+
assert(PI_SUCCESS == Res);
557+
585558
// TODO use make_kernel. This requires a fix in backend.cpp to get plugin
586559
// from context instead of free getPlugin to alllow for mocking of its methods
587-
sycl::kernel KInterop(CLKernel, Ctx);
560+
sycl::kernel KInterop((cl_kernel)PIKernel, Ctx);
588561

589562
Queue.submit([&](sycl::handler &H) { H.single_task(KInterop); });
590563

sycl/unittests/buffer/BufferLocation.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ pi_result redefinedMemBufferCreate(pi_context, pi_mem_flags, size_t size,
4343
return PI_SUCCESS;
4444
}
4545

46-
static pi_result redefinedDeviceGetInfo(pi_device device,
47-
pi_device_info param_name,
48-
size_t param_value_size,
49-
void *param_value,
50-
size_t *param_value_size_ret) {
46+
static pi_result redefinedDeviceGetInfoAfter(pi_device device,
47+
pi_device_info param_name,
48+
size_t param_value_size,
49+
void *param_value,
50+
size_t *param_value_size_ret) {
5151
if (param_name == PI_DEVICE_INFO_TYPE) {
5252
auto *Result = reinterpret_cast<_pi_device_type *>(param_value);
5353
*Result = PI_DEVICE_TYPE_ACC;
@@ -58,9 +58,15 @@ static pi_result redefinedDeviceGetInfo(pi_device device,
5858
}
5959
if (param_name == PI_DEVICE_INFO_EXTENSIONS) {
6060
const std::string name = "cl_intel_mem_alloc_buffer_location";
61+
62+
// Increase size by one for the null terminator
63+
const size_t nameSize = name.size() + 1;
64+
6165
if (!param_value) {
62-
// Increase size by one for the null terminator
63-
*param_value_size_ret = name.size() + 1;
66+
// Choose bigger size so that both original and redefined function
67+
// has enough memory for storing the extension string
68+
*param_value_size_ret =
69+
nameSize > *param_value_size_ret ? nameSize : *param_value_size_ret;
6470
} else {
6571
char *dst = static_cast<char *>(param_value);
6672
strcpy(dst, name.data());
@@ -87,10 +93,10 @@ class BufferTest : public ::testing::Test {
8793

8894
protected:
8995
void SetUp() override {
90-
Mock.redefine<sycl::detail::PiApiKind::piMemBufferCreate>(
96+
Mock.redefineBefore<sycl::detail::PiApiKind::piMemBufferCreate>(
9197
redefinedMemBufferCreate);
92-
Mock.redefine<sycl::detail::PiApiKind::piDeviceGetInfo>(
93-
redefinedDeviceGetInfo);
98+
Mock.redefineAfter<sycl::detail::PiApiKind::piDeviceGetInfo>(
99+
redefinedDeviceGetInfoAfter);
94100
}
95101

96102
protected:

sycl/unittests/event/EventDestruction.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ class EventDestructionTest : public ::testing::Test {
3333

3434
protected:
3535
void SetUp() override {
36-
Mock.redefine<detail::PiApiKind::piEventRelease>(redefinedEventRelease);
37-
Mock.redefine<detail::PiApiKind::piMemBufferCreate>(
36+
Mock.redefineBefore<detail::PiApiKind::piEventRelease>(
37+
redefinedEventRelease);
38+
Mock.redefineBefore<detail::PiApiKind::piMemBufferCreate>(
3839
redefinedMemBufferCreate);
3940
}
4041

0 commit comments

Comments
 (0)