Skip to content

Commit f82589c

Browse files
committed
Don't switch CUDA context prematurely
In c2c53d3, the call to cuCtxPushCurrent() was moved earlier in the launch sequence, so that we could call cuContextGetDevice() before we get the kernel from the cache. The problem is that we run an arbitrary amount of Python code in compile() in case we have a cache miss, which may switch the context to something else. So we should be performing our switch after the compilation is done. This seems to have caused a CI flake with a random failure in test_list.py. Signed-off-by: Greg Bonik <gbonik@nvidia.com>
1 parent cb7d671 commit f82589c

3 files changed

Lines changed: 66 additions & 65 deletions

File tree

cext/cuda_loader.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ F get_proc_address(cuGetProcAddress_v2_t getter,
4444
} // anonymous namespace
4545

4646

47-
#define DEFINE_CUDA_FUNCTION_GLOBAL(name, _cuda_version) \
47+
#define DEFINE_CUDA_FUNCTION_GLOBAL(name, _key, _cuda_version) \
4848
decltype(name)* g_##name;
4949

5050
FOREACH_CUDA_FUNCTION_TO_LOAD(DEFINE_CUDA_FUNCTION_GLOBAL)
5151

52-
#define GET_PROC_ADDRESS(name, cuda_ver) \
52+
#define GET_PROC_ADDRESS(name, key, cuda_ver) \
5353
if (!(driver_api.name = \
54-
get_proc_address<decltype(name)*>(_cuGetProcAddress, #name, cuda_ver))) \
54+
get_proc_address<decltype(name)*>(_cuGetProcAddress, key, cuda_ver))) \
5555
return ErrorRaised;
5656

5757

cext/cuda_loader.h

Lines changed: 59 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,64 +10,65 @@
1010
#include <cuda.h>
1111

1212
#define FOREACH_CUDA_FUNCTION_TO_LOAD(X) \
13-
X(cuInit, 2000) \
14-
X(cuLibraryLoadData, 12000) \
15-
X(cuLibraryUnload, 12000) \
16-
X(cuLibraryGetKernel, 12000) \
17-
X(cuGetErrorString, 6000) \
18-
X(cuLaunchKernel, 7000) \
19-
X(cuLaunchKernelEx, 11060) \
20-
X(cuPointerGetAttribute, 4000) \
21-
X(cuCtxSynchronize, 2000) \
22-
X(cuCtxPushCurrent, 4000) \
23-
X(cuCtxPopCurrent, 4000) \
24-
X(cuCtxGetCurrent, 4000) \
25-
X(cuCtxSetCurrent, 4000) \
26-
X(cuCtxGetDevice, 2000) \
27-
X(cuCtxGetId, 12000) \
28-
X(cuDeviceGet, 2000) \
29-
X(cuDeviceGetCount, 2000) \
30-
X(cuDeviceGetAttribute, 2000) \
31-
X(cuDevicePrimaryCtxRetain, 7000) \
32-
X(cuDriverGetVersion, 2020) \
33-
X(cuEventCreate, 2000) \
34-
X(cuEventDestroy, 2000) \
35-
X(cuEventQuery, 2000) \
36-
X(cuEventRecord, 2000) \
37-
X(cuKernelGetFunction, 12000) \
38-
X(cuKernelGetAttribute, 12000) \
39-
X(cuKernelSetAttribute, 12000) \
40-
X(cuMemAlloc, 3020) \
41-
X(cuMemAllocHost, 3020) \
42-
X(cuMemFree, 3020) \
43-
X(cuMemFreeHost, 2000) \
44-
X(cuMemGetAddressRange, 3020) \
45-
X(cuIpcGetMemHandle, 4010) \
46-
X(cuIpcOpenMemHandle, 4010) \
47-
X(cuIpcCloseMemHandle, 4010) \
48-
X(cuMemcpyHtoDAsync, 3020) \
49-
X(cuStreamCreate, 2000) \
50-
X(cuStreamDestroy, 4000) \
51-
X(cuStreamGetCtx, 9020) \
52-
X(cuStreamGetId, 12000) \
53-
X(cuStreamIsCapturing, 10000) \
54-
X(cuStreamSynchronize, 7000) \
55-
X(cuStreamWaitEvent, 7000) \
56-
X(cuEventElapsedTime, 12080) \
57-
X(cuGraphCreate, 10000) \
58-
X(cuGraphDestroy, 10000) \
59-
X(cuGraphAddEventRecordNode, 11010) \
60-
X(cuGraphAddKernelNode, 12000) \
61-
X(cuGraphAddMemsetNode, 10000) \
62-
X(cuGraphAddMemAllocNode, 11040) \
63-
X(cuGraphAddMemFreeNode, 11040) \
64-
X(cuGraphInstantiateWithFlags, 11040) \
65-
X(cuGraphExecDestroy, 10000) \
66-
X(cuGraphLaunch, 10000) \
67-
X(cuTensorMapEncodeTiled, 12000)
68-
69-
70-
#define DECLARE_CUDA_FUNC_EXTERN(name, _cuda_version) \
13+
X(cuInit, "cuInit", 2000) \
14+
X(cuLibraryLoadData, "cuLibraryLoadData", 12000) \
15+
X(cuLibraryUnload, "cuLibraryUnload", 12000) \
16+
X(cuLibraryGetKernel, "cuLibraryGetKernel", 12000) \
17+
X(cuGetErrorString, "cuGetErrorString", 6000) \
18+
X(cuLaunchKernel, "cuLaunchKernel", 7000) \
19+
X(cuLaunchKernelEx, "cuLaunchKernelEx", 11060) \
20+
X(cuPointerGetAttribute, "cuPointerGetAttribute", 4000) \
21+
X(cuCtxSynchronize, "cuCtxSynchronize", 2000) \
22+
X(cuCtxPushCurrent, "cuCtxPushCurrent", 4000) \
23+
X(cuCtxPopCurrent, "cuCtxPopCurrent", 4000) \
24+
X(cuCtxGetCurrent, "cuCtxGetCurrent", 4000) \
25+
X(cuCtxSetCurrent, "cuCtxSetCurrent", 4000) \
26+
X(cuCtxGetDevice, "cuCtxGetDevice", 2000) \
27+
X(cuCtxGetDevice_v2, "cuCtxGetDevice", 13000) \
28+
X(cuCtxGetId, "cuCtxGetId", 12000) \
29+
X(cuDeviceGet, "cuDeviceGet", 2000) \
30+
X(cuDeviceGetCount, "cuDeviceGetCount", 2000) \
31+
X(cuDeviceGetAttribute, "cuDeviceGetAttribute", 2000) \
32+
X(cuDevicePrimaryCtxRetain, "cuDevicePrimaryCtxRetain", 7000) \
33+
X(cuDriverGetVersion, "cuDriverGetVersion", 2020) \
34+
X(cuEventCreate, "cuEventCreate", 2000) \
35+
X(cuEventDestroy, "cuEventDestroy", 2000) \
36+
X(cuEventQuery, "cuEventQuery", 2000) \
37+
X(cuEventRecord, "cuEventRecord", 2000) \
38+
X(cuKernelGetFunction, "cuKernelGetFunction", 12000) \
39+
X(cuKernelGetAttribute, "cuKernelGetAttribute", 12000) \
40+
X(cuKernelSetAttribute, "cuKernelSetAttribute", 12000) \
41+
X(cuMemAlloc, "cuMemAlloc", 3020) \
42+
X(cuMemAllocHost, "cuMemAllocHost", 3020) \
43+
X(cuMemFree, "cuMemFree", 3020) \
44+
X(cuMemFreeHost, "cuMemFreeHost", 2000) \
45+
X(cuMemGetAddressRange, "cuMemGetAddressRange", 3020) \
46+
X(cuIpcGetMemHandle, "cuIpcGetMemHandle", 4010) \
47+
X(cuIpcOpenMemHandle, "cuIpcOpenMemHandle", 4010) \
48+
X(cuIpcCloseMemHandle, "cuIpcCloseMemHandle", 4010) \
49+
X(cuMemcpyHtoDAsync, "cuMemcpyHtoDAsync", 3020) \
50+
X(cuStreamCreate, "cuStreamCreate", 2000) \
51+
X(cuStreamDestroy, "cuStreamDestroy", 4000) \
52+
X(cuStreamGetCtx, "cuStreamGetCtx", 9020) \
53+
X(cuStreamGetId, "cuStreamGetId", 12000) \
54+
X(cuStreamIsCapturing, "cuStreamIsCapturing", 10000) \
55+
X(cuStreamSynchronize, "cuStreamSynchronize", 7000) \
56+
X(cuStreamWaitEvent, "cuStreamWaitEvent", 7000) \
57+
X(cuEventElapsedTime, "cuEventElapsedTime", 12080) \
58+
X(cuGraphCreate, "cuGraphCreate", 10000) \
59+
X(cuGraphDestroy, "cuGraphDestroy", 10000) \
60+
X(cuGraphAddEventRecordNode, "cuGraphAddEventRecordNode", 11010) \
61+
X(cuGraphAddKernelNode, "cuGraphAddKernelNode", 12000) \
62+
X(cuGraphAddMemsetNode, "cuGraphAddMemsetNode", 10000) \
63+
X(cuGraphAddMemAllocNode, "cuGraphAddMemAllocNode", 11040) \
64+
X(cuGraphAddMemFreeNode, "cuGraphAddMemFreeNode", 11040) \
65+
X(cuGraphInstantiateWithFlags, "cuGraphInstantiateWithFlags", 11040) \
66+
X(cuGraphExecDestroy, "cuGraphExecDestroy", 10000) \
67+
X(cuGraphLaunch, "cuGraphLaunch", 10000) \
68+
X(cuTensorMapEncodeTiled, "cuTensorMapEncodeTiled", 12000)
69+
70+
71+
#define DECLARE_CUDA_FUNC_EXTERN(name, _key, _cuda_version) \
7172
decltype(::name)* name;
7273

7374
struct DriverApi {

cext/tile_kernel.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3433,13 +3433,10 @@ static Result<PreparedLaunch> prepare_launch(
34333433
return ErrorRaised;
34343434
}
34353435

3436-
if (!ctx_guard.switch_to(helper->cuda_context))
3437-
return ErrorRaised;
3438-
34393436
// Get the compute capability of the device this launch targets.
34403437
// Devices with the same compute capability can share a compiled kernel.
34413438
CUdevice dev;
3442-
CUresult dev_res = driver->cuCtxGetDevice(&dev);
3439+
CUresult dev_res = driver->cuCtxGetDevice_v2(&dev, helper->cuda_context);
34433440
if (dev_res != CUDA_SUCCESS) {
34443441
return raise(PyExc_RuntimeError, "Failed to get current CUDA device: %s",
34453442
get_cuda_error(driver, dev_res));
@@ -3483,6 +3480,9 @@ static Result<PreparedLaunch> prepare_launch(
34833480
kernel_item = kernel_map.insert(std::move(helper->constants), std::move(*res));
34843481
}
34853482

3483+
if (!ctx_guard.switch_to(helper->cuda_context))
3484+
return ErrorRaised;
3485+
34863486
if (stage_list_args
34873487
&& !stage_list_args_on_stream(driver, launch_stream, helper->cuda_context,
34883488
helper->arena, helper->list_args,

0 commit comments

Comments
 (0)