Skip to content

Commit 029d798

Browse files
committed
Merge pull request #16568 from rapidsai/branch-24.08
2 parents c5ae820 + 4961512 commit 029d798

File tree

5 files changed

+59
-12
lines changed

5 files changed

+59
-12
lines changed

dependencies.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ dependencies:
631631
common:
632632
- output_types: [conda, requirements, pyproject]
633633
packages:
634-
- polars>=1.0
634+
- polars>=1.0,<1.3
635635
run_dask_cudf:
636636
common:
637637
- output_types: [conda, requirements, pyproject]

docs/cudf/source/cudf_pandas/how-it-works.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,20 @@ allocation may be a bottleneck depending on the workload. Managed memory
4444
enables oversubscribing GPU memory. This allows cudf.pandas to process
4545
data larger than GPU memory in many cases, without CPU (Pandas) fallback.
4646

47+
```{note}
48+
CUDA Managed Memory on Windows, and more specifically Windows Subsystem for
49+
Linux (WSL2), [does not support oversubscription](
50+
https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#system-requirements-for-unified-memory),
51+
only unified addressing. Furthermore, managed memory on WSL2 has undesirable
52+
performance characteristics. Therefore, `cudf.pandas` uses a non-managed pool
53+
allocator on WSL2, so `cudf.pandas` is limited to the physical size of GPU memory.
54+
```
55+
4756
Other memory allocators can be used by changing the environment
48-
variable `CUDF_PANDAS_RMM_MODE` to one of the following.
57+
variable `CUDF_PANDAS_RMM_MODE` to one of the following:
4958

50-
1. "managed_pool" (default): CUDA Unified Memory (managed memory) with RMM's asynchronous pool allocator.
51-
2. "managed": CUDA Unified Memory, (managed memory) with no pool allocator.
52-
3. "async": CUDA's built-in pool asynchronous pool allocator with normal CUDA device memory.
53-
4. "pool": RMM's asynchronous pool allocator with normal CUDA device memory.
54-
5. "cuda": normal CUDA device memory with no pool allocator.
59+
1. `"managed_pool"` (default, if supported): CUDA Unified Memory (managed memory) with RMM's asynchronous pool allocator.
60+
2. `"managed"`: CUDA Unified Memory, (managed memory) with no pool allocator.
61+
3. `"async"`: CUDA's built-in pool asynchronous pool allocator with normal CUDA device memory.
62+
4. `"pool"` (default if `"managed_pool"` is not supported): RMM's asynchronous pool allocator with normal CUDA device memory.
63+
5. `"cuda"`: normal CUDA device memory with no pool allocator.

python/cudf/cudf/_lib/pylibcudf/utils.pyx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ from libc.stdint cimport uintptr_t
66
from libcpp.functional cimport reference_wrapper
77
from libcpp.vector cimport vector
88

9+
from cuda import cudart
10+
911
from cudf._lib.pylibcudf.libcudf.scalar.scalar cimport scalar
1012
from cudf._lib.pylibcudf.libcudf.types cimport bitmask_type
1113

@@ -34,3 +36,23 @@ cdef vector[reference_wrapper[const scalar]] _as_vector(list source):
3436
c_scalars.push_back(
3537
reference_wrapper[constscalar](dereference((<Scalar?>slr).c_obj)))
3638
return c_scalars
39+
40+
41+
def _is_concurrent_managed_access_supported():
42+
"""Check the availability of concurrent managed access (UVM).
43+
44+
Note that WSL2 does not support managed memory.
45+
"""
46+
47+
# Ensure CUDA is initialized before checking cudaDevAttrConcurrentManagedAccess
48+
cudart.cudaFree(0)
49+
50+
device_id = 0
51+
err, supports_managed_access = cudart.cudaDeviceGetAttribute(
52+
cudart.cudaDeviceAttr.cudaDevAttrConcurrentManagedAccess, device_id
53+
)
54+
if err != cudart.cudaError_t.cudaSuccess:
55+
raise RuntimeError(
56+
f"Failed to check cudaDevAttrConcurrentManagedAccess with error {err}"
57+
)
58+
return supports_managed_access != 0

python/cudf/cudf/pandas/__init__.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
}
2727

2828

29-
def _enable_managed_prefetching(rmm_mode):
30-
if "managed" in rmm_mode:
29+
def _enable_managed_prefetching(rmm_mode, managed_memory_is_supported):
30+
if managed_memory_is_supported and "managed" in rmm_mode:
3131
for key in _SUPPORTED_PREFETCHES:
3232
pylibcudf.experimental.enable_prefetching(key)
3333

@@ -40,7 +40,20 @@ def install():
4040
global LOADED
4141
LOADED = loader is not None
4242

43-
rmm_mode = os.getenv("CUDF_PANDAS_RMM_MODE", "managed_pool")
43+
# The default mode is "managed_pool" if UVM is supported, otherwise "pool"
44+
managed_memory_is_supported = (
45+
pylibcudf.utils._is_concurrent_managed_access_supported()
46+
)
47+
default_rmm_mode = (
48+
"managed_pool" if managed_memory_is_supported else "pool"
49+
)
50+
rmm_mode = os.getenv("CUDF_PANDAS_RMM_MODE", default_rmm_mode)
51+
52+
if "managed" in rmm_mode and not managed_memory_is_supported:
53+
raise ValueError(
54+
f"Managed memory is not supported on this system, so the requested {rmm_mode=} is invalid."
55+
)
56+
4457
# Check if a non-default memory resource is set
4558
current_mr = rmm.mr.get_current_device_resource()
4659
if not isinstance(current_mr, rmm.mr.CudaMemoryResource):
@@ -53,6 +66,7 @@ def install():
5366
free_memory, _ = rmm.mr.available_device_memory()
5467
free_memory = int(round(float(free_memory) * 0.80 / 256) * 256)
5568
new_mr = current_mr
69+
5670
if rmm_mode == "pool":
5771
new_mr = rmm.mr.PoolMemoryResource(
5872
current_mr,
@@ -71,8 +85,10 @@ def install():
7185
)
7286
elif rmm_mode != "cuda":
7387
raise ValueError(f"Unsupported {rmm_mode=}")
88+
7489
rmm.mr.set_current_device_resource(new_mr)
75-
_enable_managed_prefetching(rmm_mode)
90+
91+
_enable_managed_prefetching(rmm_mode, managed_memory_is_supported)
7692

7793

7894
def pytest_load_initial_conftests(early_config, parser, args):

python/cudf_polars/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ license = { text = "Apache 2.0" }
2020
requires-python = ">=3.9"
2121
dependencies = [
2222
"cudf==24.8.*",
23-
"polars>=1.0",
23+
"polars>=1.0,<1.3",
2424
] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`.
2525
classifiers = [
2626
"Intended Audience :: Developers",

0 commit comments

Comments
 (0)