Skip to content

Commit 60715ad

Browse files
authored
Use PrefetchResourceAdaptor in cuml.accel (#7834)
By default `cuml.accel` enables a `ManagedMemoryResource`, which allocates managed memory. While benchmarking some workloads, I've noticed a measurable performance improvement when wrapping this mr with a `PrefetchResourceAdaptor`. This adaptor schedules a prefetch of memory to the device immediately after allocation. For `cuml`/`cuml.accel` workloads this makes sense - we typically allocate an array, then call a kernel to fill it in, before returning it. This also matches some performance advice noted by other teams (and the official CUDA programming guide) that prefetching may be useful when working with managed memory. This also more closely matches the rmm configuration used by `cudf.pandas` by default (see [here](https://github.com/rapidsai/cudf/blob/dd03be22ab12195be28ed4f4338c26f589485c90/python/cudf/cudf/pandas/__init__.py#L87-L97)). Note that `cudf.pandas` also uses a `PoolMemoryResource` by default, but always enables prefetching of managed memory even without the pool. My intuition is that pooling makes sense when you have many smaller allocations (like might happen with pandas), since it can amortize the upstream allocator cost across calls. cuml workloads typically do fewer and larger allocations, so I don't think investigating pooling is necessary for now. Fixes #7846. Authors: - Jim Crist-Harif (https://github.com/jcrist) Approvers: - Divye Gala (https://github.com/divyegala) URL: #7834
1 parent ea5f72b commit 60715ad

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

‎python/cuml/cuml/accel/core.py‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,13 @@ def install(
186186
import rmm
187187

188188
mr = rmm.mr.get_current_device_resource()
189-
if isinstance(mr, rmm.mr.ManagedMemoryResource):
189+
if (
190+
isinstance(mr, rmm.mr.PrefetchResourceAdaptor)
191+
and isinstance(mr.upstream_mr, rmm.mr.PoolMemoryResource)
192+
and isinstance(
193+
mr.upstream_mr.upstream_mr, rmm.mr.ManagedMemoryResource
194+
)
195+
):
190196
# Nothing to do
191197
pass
192198
elif not isinstance(mr, rmm.mr.CudaMemoryResource):
@@ -196,7 +202,11 @@ def install(
196202
)
197203
else:
198204
rmm.mr.set_current_device_resource(
199-
rmm.mr.ManagedMemoryResource()
205+
rmm.mr.PrefetchResourceAdaptor(
206+
rmm.mr.PoolMemoryResource(
207+
rmm.mr.ManagedMemoryResource()
208+
)
209+
)
200210
)
201211
logger.debug("Enabled managed memory.")
202212
else:

‎python/cuml/cuml_accel_tests/integration/test_svr.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,13 @@ def test_svr_precomputed_train_test():
7777
# Just check it runs and produces reasonable output
7878
predictions = svr.predict(K_test)
7979
assert predictions.shape == y_test.shape
80+
81+
82+
def test_svr_fit_n_support_0():
83+
X = np.eye(3)
84+
y = np.full(3, 1.23)
85+
model = SVR().fit(X, y)
86+
assert (model.intercept_ == 1.23).all()
87+
assert (model.n_support_ == 0).all()
88+
assert model.dual_coef_.shape == (1, 0)
89+
assert (model.predict(X) == y).all()

0 commit comments

Comments
 (0)