Skip to content

Commit 593ea5c

Browse files
committed
[SYCL][UnitTest] Test device global initializer cleanup on program removal
1 parent 8064243 commit 593ea5c

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

sycl/source/detail/context_impl.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ class context_impl : public std::enable_shared_from_this<context_impl> {
200200
removeDeviceGlobalInitializer(ur_program_handle_t Program,
201201
const RTDeviceBinaryImage *BinImage = nullptr);
202202

203+
/// Returns the number of programs with device globals not yet initialized.
204+
size_t getDeviceGlobalNotInitializedCnt() const {
205+
return MDeviceGlobalNotInitializedCnt.load(std::memory_order_relaxed);
206+
}
207+
203208
/// Initializes device globals for a program on the associated queue.
204209
std::vector<ur_event_handle_t>
205210
initializeDeviceGlobals(ur_program_handle_t NativePrg, queue_impl &QueueImpl,

sycl/unittests/program_manager/Cleanup.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,65 @@ TEST(ImageRemoval, NativePrograms) {
369369
EXPECT_TRUE(PM.getNativePrograms().count(ProgramA) > 0);
370370
EXPECT_TRUE(PM.getNativePrograms().count(ProgramB) > 0);
371371
}
372+
373+
// Verify that removeImages cleans up device global initializer entries so that
374+
// a reused program handle does not collide with stale state.
375+
TEST(ImageRemoval, DeviceGlobalInitializerCleanupOnRemoveImages) {
376+
ProgramManagerExposed PM;
377+
378+
// An image with device globals that we will add and then remove.
379+
sycl_device_binary_struct NativeImagesForRemoval[ImagesToRemove.size()];
380+
sycl_device_binaries_struct TestBinaries;
381+
convertAndAddImages(PM, ImagesToRemove, NativeImagesForRemoval, TestBinaries);
382+
383+
PM.addOrInitDeviceGlobalEntry(&DeviceGlobalC,
384+
generateRefName("C", "DeviceGlobal").c_str());
385+
386+
sycl::platform Plt = sycl::platform();
387+
const sycl::device Dev = Plt.get_devices()[0];
388+
sycl::queue Queue{Dev};
389+
auto Ctx = Queue.get_context();
390+
auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx);
391+
392+
// Grab the RTDeviceBinaryImage* for the "C" image that was just added.
393+
ASSERT_EQ(PM.getDeviceImages().size(), 1u);
394+
const sycl::detail::RTDeviceBinaryImage *BinImg =
395+
PM.getDeviceImages().begin()->second.get();
396+
397+
ur_program_handle_t FakeProgram =
398+
reinterpret_cast<ur_program_handle_t>(static_cast<uintptr_t>(0xDEADBEEF));
399+
400+
// Register the fake program in NativePrograms so that removeImages can find
401+
// it and trigger removeDeviceGlobalInitializer, mirroring what
402+
// ProgramManager::build() does.
403+
PM.getNativePrograms().insert({FakeProgram, {CtxImpl, BinImg}});
404+
405+
CtxImpl->addDeviceGlobalInitializer(FakeProgram, CtxImpl->getDevices(),
406+
BinImg);
407+
408+
EXPECT_EQ(CtxImpl->getDeviceGlobalNotInitializedCnt(), 1u)
409+
<< "Counter should be 1 after adding the initializer";
410+
411+
// Simulate program teardown.
412+
PM.removeImages(&TestBinaries);
413+
414+
EXPECT_EQ(CtxImpl->getDeviceGlobalNotInitializedCnt(), 0u)
415+
<< "Counter should be 0 after removeImages cleans up the initializer";
416+
417+
// Re-add the same BinImg under the same (reused) program handle — this is
418+
// what happens when the adapter allocates a fresh program with the same
419+
// handle value. The counter must go back up to 1 cleanly.
420+
sycl_device_binary_struct NativeImagesSecond[ImagesToRemove.size()];
421+
sycl_device_binaries_struct TestBinariesSecond;
422+
convertAndAddImages(PM, ImagesToRemove, NativeImagesSecond,
423+
TestBinariesSecond);
424+
const sycl::detail::RTDeviceBinaryImage *BinImgSecond =
425+
PM.getDeviceImages().begin()->second.get();
426+
427+
CtxImpl->addDeviceGlobalInitializer(FakeProgram, CtxImpl->getDevices(),
428+
BinImgSecond);
429+
430+
EXPECT_EQ(CtxImpl->getDeviceGlobalNotInitializedCnt(), 1u)
431+
<< "Counter should be 1 after re-registering the reused program handle";
432+
}
372433
} // anonymous namespace

0 commit comments

Comments
 (0)