Skip to content

Commit 7e6b3c2

Browse files
authored
[SYCL][CUDA] Fix context setup for device infos (#8124)
Extend the `ScopedContext` to work with just a device, in that case it will simply use the primary context. This is helpful for entry points that only have a `pi_device` and no `pi_context` but that still need some cuda calls that require an active context, such as for the device infos. This addresses a bug where getting the amount of free memory before creating any queues or context, would simply crash. This was partially solved in a previous PR (#7906), however the previous PR was releasing the primary context, but leaving it active on the current thread, so getting the device info twice in a row would end up crashing again since it would just use the active but released primary context. This should address: #8117
1 parent 51144f8 commit 7e6b3c2

File tree

1 file changed

+19
-21
lines changed

1 file changed

+19
-21
lines changed

sycl/plugins/cuda/pi_cuda.cpp

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,30 @@ pi_result check_error(CUresult result, const char *function, int line,
188188
/// contexts to be restored by SYCL.
189189
class ScopedContext {
190190
public:
191-
ScopedContext(pi_context ctxt) {
191+
ScopedContext(pi_context ctxt) : device(nullptr) {
192192
if (!ctxt) {
193193
throw PI_ERROR_INVALID_CONTEXT;
194194
}
195195

196196
set_context(ctxt->get());
197197
}
198198

199-
ScopedContext(CUcontext ctxt) { set_context(ctxt); }
199+
ScopedContext(CUcontext ctxt) : device(nullptr) { set_context(ctxt); }
200200

201-
~ScopedContext() {}
201+
// Creating a scoped context from a device will simply use the primary
202+
// context, this should be used when there is no other appropriate context,
203+
// such as for the device infos.
204+
ScopedContext(pi_device device) : device(device) {
205+
CUcontext ctxt;
206+
cuDevicePrimaryCtxRetain(&ctxt, device->get());
207+
208+
set_context(ctxt);
209+
}
210+
211+
~ScopedContext() {
212+
if (device)
213+
cuDevicePrimaryCtxRelease(device->get());
214+
}
202215

203216
private:
204217
void set_context(CUcontext desired) {
@@ -212,6 +225,8 @@ class ScopedContext {
212225
PI_CHECK_ERROR(cuCtxSetCurrent(desired));
213226
}
214227
}
228+
229+
pi_device device;
215230
};
216231

217232
/// \cond NODOXY
@@ -1946,29 +1961,12 @@ pi_result cuda_piDeviceGetInfo(pi_device device, pi_device_info param_name,
19461961
}
19471962

19481963
case PI_EXT_INTEL_DEVICE_INFO_FREE_MEMORY: {
1949-
// Check the device of the currently set context uses the same device.
1950-
// CUDA_ERROR_INVALID_CONTEXT signifies the absence of an active context.
1951-
CUdevice current_ctx_device;
1952-
CUresult current_ctx_device_ret = cuCtxGetDevice(&current_ctx_device);
1953-
if (current_ctx_device_ret != CUDA_ERROR_INVALID_CONTEXT)
1954-
PI_CHECK_ERROR(current_ctx_device_ret);
1955-
bool need_primary_ctx =
1956-
current_ctx_device_ret == CUDA_ERROR_INVALID_CONTEXT ||
1957-
current_ctx_device != device->get();
1958-
if (need_primary_ctx) {
1959-
// Use the primary context for the device if no context with the device is
1960-
// set.
1961-
CUcontext primary_context;
1962-
PI_CHECK_ERROR(cuDevicePrimaryCtxRetain(&primary_context, device->get()));
1963-
PI_CHECK_ERROR(cuCtxSetCurrent(primary_context));
1964-
}
1964+
ScopedContext active(device);
19651965
size_t FreeMemory = 0;
19661966
size_t TotalMemory = 0;
19671967
sycl::detail::pi::assertion(cuMemGetInfo(&FreeMemory, &TotalMemory) ==
19681968
CUDA_SUCCESS,
19691969
"failed cuMemGetInfo() API.");
1970-
if (need_primary_ctx)
1971-
PI_CHECK_ERROR(cuDevicePrimaryCtxRelease(device->get()));
19721970
return getInfo(param_value_size, param_value, param_value_size_ret,
19731971
FreeMemory);
19741972
}

0 commit comments

Comments
 (0)