Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions sycl/source/detail/device_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ device_impl::device_impl(ur_device_handle_t Device, platform_impl &Platform,
: get_info_impl<UR_DEVICE_INFO_PARENT_DEVICE>()),
// TODO catch an exception and put it to list of asynchronous exceptions:
MCache{*this} {
// Interoperability Constructor already calls DeviceRetain in
// urDeviceCreateWithNativeHandle.
getAdapter().call<UrApiKind::urDeviceRetain>(MDevice);
// urDeviceRetain(MDevice) should not be called here,
// because RefCounter is initialized with 1,
// when the device is created.
}

device_impl::~device_impl() {
Expand Down
9 changes: 2 additions & 7 deletions sycl/unittests/context_device/DeviceRefCounter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,7 @@ TEST(DevRefCounter, DevRefCounter) {
sycl::platform Plt = sycl::platform();

Plt.get_devices();
EXPECT_NE(DevRefCounter, 0);
// This is the behavior that SYCL performs at shutdown, but there
// are timing differences Lin/Win and shared/static that make
// it not map correctly into our mock.
// So for this test, we just do it.
sycl::detail::GlobalHandler::instance().getPlatformCache().clear();

EXPECT_EQ(DevRefCounter, 0);
Copy link
Contributor

@againull againull Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems a bit off that ref count is zero here, because callback for urDeviceGet (redefinedDevicesGetAfter) increments the DevRefCounter. So, even if we don't call Retain anymore, ref count is still expected to be at least 1 because of urDevicesGet. It would be nice to either understand why it is normal to have zero ref count here or to update the test if necessary if there is something wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@againull I have debugged this unittest. It calls 3 times platform_impl::getDevicesImplHelper():

void platform_impl::getDevicesImplHelper(ur_device_type_t UrDeviceType,
which calls:

  1. urDeviceGet(NumDevices == 0) what sets DevRefCounter == 0 (using redefinedDevicesGetAfter()):
    MAdapter->call<UrApiKind::urDeviceGet>(MPlatform, UrDeviceType,
    0u, // CP info::device_type::all
    nullptr, &NumDevices);
  2. urDeviceGet(NumDevices == 1) what sets DevRefCounter == 1 (using redefinedDevicesGetAfter()):
    MAdapter->call<UrApiKind::urDeviceGet>(
    MPlatform,
    UrDeviceType, // CP info::device_type::all
    NumDevices, UrDevices.data(), nullptr);
  3. urDeviceRelease() on this device what decrements DevRefCounter to 0 (using redefinedDeviceReleaseAfter()):
    // The reference counter for handles, that we used to create sycl objects, is
    // incremented, so we need to call release here.
    for (ur_device_handle_t &UrDev : UrDevicesToCleanUp)
    MAdapter->call<UrApiKind::urDeviceRelease>(UrDev);

... what looks like:

- redefinedDevicesGetAfter(*params.pphDevices == 0)    DevRefCounter == 0  from urDeviceGet(NumDevices == 0)
- redefinedDevicesGetAfter(*params.pNumEntries == 1)   DevRefCounter == 1  from urDeviceGet(NumDevices == 1)
- redefinedDeviceReleaseAfter()                        DevRefCounter == 0  from urDeviceRelease()

- redefinedDevicesGetAfter(*params.pphDevices == 0)    DevRefCounter == 0  from urDeviceGet(NumDevices == 0)
- redefinedDevicesGetAfter(*params.pNumEntries == 1)   DevRefCounter == 1  from urDeviceGet(NumDevices == 1)
- redefinedDeviceReleaseAfter()                        DevRefCounter == 0  from urDeviceRelease()

- redefinedDevicesGetAfter(*params.pphDevices == 0)    DevRefCounter == 0  from urDeviceGet(NumDevices == 0)
- redefinedDevicesGetAfter(*params.pNumEntries == 1)   DevRefCounter == 1  from urDeviceGet(NumDevices == 1)
- redefinedDeviceReleaseAfter()                        DevRefCounter == 0  from urDeviceRelease()

@againull Does it make sense or is there anything wrong here?

}
EXPECT_EQ(DevRefCounter, 0);
}