Skip to content

Commit 8a36bbe

Browse files
haijieggbonik
andcommitted
* Add cuda.tile.tune.exhaustive_search API
- Add `exhaustive_search()` and `TunedResult` to public API. - Also add `compiler_timeout()` and `kernel.replace_hints()` to public API. - Mark ct_experimental.autotune as deprecated. - Add a c++ benchmark util using cudagraph Co-authored-by: Greg Bonik <gbonik@nvidia.com> Signed-off-by: Jay Gu <jagu@nvidia.com>
1 parent bdf0bca commit 8a36bbe

25 files changed

Lines changed: 1209 additions & 704 deletions

cext/cuda_helper.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,66 @@ PyObject* get_driver_version(PyObject *self, PyObject *Py_UNUSED(ignored)) {
9696
return Py_BuildValue("(ii)", major, minor);
9797
}
9898

99+
// ========== Context helpers ==========
100+
101+
PyObject* synchronize_context(PyObject* self, PyObject* Py_UNUSED(ignored)) {
102+
Result<const DriverApi*> driver_result = get_driver_api();
103+
if (!driver_result.is_ok()) return NULL;
104+
const DriverApi* d = *driver_result;
105+
106+
CUresult res = d->cuCtxSynchronize();
107+
if (res != CUDA_SUCCESS) {
108+
return PyErr_Format(PyExc_RuntimeError,
109+
"cuCtxSynchronize: %s", get_cuda_error(d, res));
110+
}
111+
Py_RETURN_NONE;
112+
}
113+
114+
// ========== Stream helpers ==========
115+
116+
PyObject* create_stream(PyObject* self, PyObject* Py_UNUSED(ignored)) {
117+
Result<const DriverApi*> driver_result = get_driver_api();
118+
if (!driver_result.is_ok()) return NULL;
119+
const DriverApi* d = *driver_result;
120+
121+
CUstream stream;
122+
CUresult res = d->cuStreamCreate(&stream, CU_STREAM_NON_BLOCKING);
123+
if (res != CUDA_SUCCESS) {
124+
return PyErr_Format(PyExc_RuntimeError,
125+
"cuStreamCreate: %s", get_cuda_error(d, res));
126+
}
127+
return PyLong_FromVoidPtr(stream);
128+
}
129+
130+
PyObject* destroy_stream(PyObject* self, PyObject* arg) {
131+
CUstream stream = static_cast<CUstream>(PyLong_AsVoidPtr(arg));
132+
if (PyErr_Occurred()) return NULL;
133+
134+
Result<const DriverApi*> driver_result = get_driver_api();
135+
if (!driver_result.is_ok()) return NULL;
136+
const DriverApi* d = *driver_result;
137+
138+
CUresult res = d->cuStreamDestroy(stream);
139+
if (res != CUDA_SUCCESS) {
140+
return PyErr_Format(PyExc_RuntimeError,
141+
"cuStreamDestroy: %s", get_cuda_error(d, res));
142+
}
143+
Py_RETURN_NONE;
144+
}
145+
99146
static PyMethodDef functions[] = {
100147
{"get_compute_capability", get_compute_capability, METH_NOARGS,
101148
"Get compute capability of the default CUDA device"},
102149
{"get_driver_version", get_driver_version, METH_NOARGS,
103150
"Get the cuda driver version"},
104151
{"_get_max_grid_size", get_max_grid_size, METH_VARARGS,
105152
"Get max grid size of a CUDA device, given device id"},
153+
{"_synchronize_context", synchronize_context, METH_NOARGS,
154+
"Synchronize the current CUDA context (drain all streams)."},
155+
{"_create_stream", create_stream, METH_NOARGS,
156+
"Create a non-blocking CUDA stream. Returns int handle."},
157+
{"_destroy_stream", destroy_stream, METH_O,
158+
"Destroy a CUDA stream given its int handle."},
106159
NULL
107160
};
108161

cext/cuda_loader.h

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
X(cuGetErrorString, 6000) \
1818
X(cuLaunchKernel, 7000) \
1919
X(cuPointerGetAttribute, 4000) \
20+
X(cuCtxSynchronize, 2000) \
2021
X(cuCtxPushCurrent, 4000) \
2122
X(cuCtxPopCurrent, 4000) \
2223
X(cuCtxGetCurrent, 4000) \
@@ -37,11 +38,23 @@
3738
X(cuMemFreeHost, 2000) \
3839
X(cuMemcpyHtoDAsync, 3020) \
3940
X(cuStreamCreate, 2000) \
41+
X(cuStreamDestroy, 4000) \
4042
X(cuStreamGetCtx, 9020) \
4143
X(cuStreamGetId, 12000) \
4244
X(cuStreamIsCapturing, 10000) \
4345
X(cuStreamSynchronize, 7000) \
44-
X(cuStreamWaitEvent, 7000)
46+
X(cuStreamWaitEvent, 7000) \
47+
X(cuEventElapsedTime, 12080) \
48+
X(cuGraphCreate, 10000) \
49+
X(cuGraphDestroy, 10000) \
50+
X(cuGraphAddEventRecordNode, 11010) \
51+
X(cuGraphAddKernelNode, 12000) \
52+
X(cuGraphAddMemsetNode, 10000) \
53+
X(cuGraphAddMemAllocNode, 11040) \
54+
X(cuGraphAddMemFreeNode, 11040) \
55+
X(cuGraphInstantiateWithFlags, 11040) \
56+
X(cuGraphExecDestroy, 10000) \
57+
X(cuGraphLaunch, 10000)
4558

4659

4760
#define DECLARE_CUDA_FUNC_EXTERN(name, _cuda_version) \
@@ -52,3 +65,73 @@ struct DriverApi {
5265
};
5366

5467
Result<const DriverApi*> get_driver_api();
68+
69+
70+
class CudaGraph {
71+
const DriverApi* d;
72+
CUgraph graph;
73+
public:
74+
CudaGraph(const CudaGraph&) = delete;
75+
void operator=(const CudaGraph&) = delete;
76+
77+
explicit CudaGraph(const DriverApi* d) : d(d), graph(nullptr) {}
78+
79+
CUresult create() {
80+
CHECK(!graph);
81+
return d->cuGraphCreate(&graph, 0);
82+
}
83+
84+
CUgraph get() const {
85+
return graph;
86+
}
87+
88+
~CudaGraph() {
89+
if (graph) d->cuGraphDestroy(graph);
90+
}
91+
};
92+
93+
class CudaGraphExec {
94+
const DriverApi* d;
95+
CUgraphExec exec;
96+
public:
97+
CudaGraphExec(const CudaGraphExec&) = delete;
98+
void operator=(const CudaGraphExec&) = delete;
99+
100+
explicit CudaGraphExec(const DriverApi* d) : d(d), exec(nullptr) {}
101+
102+
CUresult instantiate(const CudaGraph& graph) {
103+
CHECK(!exec);
104+
return d->cuGraphInstantiateWithFlags(&exec, graph.get(), 0);
105+
}
106+
107+
CUgraphExec get() const {
108+
return exec;
109+
}
110+
111+
~CudaGraphExec() {
112+
if (exec) d->cuGraphExecDestroy(exec);
113+
}
114+
};
115+
116+
class CudaEvent {
117+
const DriverApi* d;
118+
CUevent event;
119+
public:
120+
CudaEvent(const CudaEvent&) = delete;
121+
void operator=(const CudaEvent&) = delete;
122+
123+
explicit CudaEvent(const DriverApi* d) : d(d), event(nullptr) {}
124+
125+
CUresult create() {
126+
CHECK(!event);
127+
return d->cuEventCreate(&event, CU_EVENT_DEFAULT);
128+
}
129+
130+
CUevent get() const {
131+
return event;
132+
}
133+
134+
~CudaEvent() {
135+
if (event) d->cuEventDestroy(event);
136+
}
137+
};

cext/stream_buffer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ StreamBufferPool* stream_buffer_pool_new() {
5151
return new StreamBufferPool();
5252
}
5353

54+
void stream_buffer_pool_delete(StreamBufferPool* pool) {
55+
delete pool;
56+
}
57+
5458
static void delete_chunk(const DriverApi* driver, Chunk* chunk) {
5559
dual_ptr_free(driver, chunk->ptr);
5660
driver->cuEventDestroy(chunk->event);

cext/stream_buffer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class StreamBufferTransaction {
7474
};
7575

7676
StreamBufferPool* stream_buffer_pool_new();
77+
void stream_buffer_pool_delete(StreamBufferPool* pool);
7778

7879
StreamBufferTransaction stream_buffer_transaction_open(const DriverApi*,
7980
StreamBufferPool* pool,

0 commit comments

Comments
 (0)