Skip to content

Disk-spilling shuffler #1170

Description

@madsbk

Shuffle extraction is often the OOM point. It acts as a barrier that waits on all data before continuing, so at that point a rank holds its entire local share of the shuffle. In RapidsMPF the normal answer is to spill device memory to host, but on very large datasets host memory is limiting too, and there is no tier below it.

We propose an option for the existing Shuffler to spill shuffled data to disk, and to unspill it back to host or device only when the user extracts it.

Proposal

Add a DiskBuffer, a file-backed handle to a single spilled chunk. Disk becomes a tier the shuffler can move a chunk into, and it stays entirely outside the MemoryType taxonomy.

Concretely, rapidsmpf::shuffler::detail::Chunk gains a disk-resident state, ReceivedChunks::spill gets a disk fallback instead of a throw, and Shuffler::extract rehydrates. Nothing in BufferResource, Buffer, MemoryType, or the general spill machinery changes.

Host limit

The Shuffler takes a host limit, a byte count or percentage mirroring the existing spill_device_limit. Device pressure spills device to host exactly as today, and crossing the host limit is what triggers host to disk. Disk is therefore entered on a threshold the user sets, rather than only once host allocation has already failed.

Why not MemoryType::DISK

A general MemoryType::DISK is something we may well want later, but it is a much bigger change than the enum makes it look, and most of the cost lands downstream.

Within RapidsMPF, Buffer cannot represent disk. Its storage is a std::variant of a device and a host buffer (buffer.hpp:370), and data(), write_access(), and exclusive_data_access() all return a raw pointer that a file-backed buffer does not have. Every cross-tier move funnels through buffer_copy() (buffer.cpp:134), one cuda_memcpy_async between two pointers against a single reservation, so disk cannot join that funnel without turning it into a tier dispatch that affects every BufferResource user. On top of that, once DISK is in MEMORY_TYPES it becomes reachable by accident from the sites that pass the whole array as a preference list.

Downstream is the larger cost. cudf_streaming has its own exhaustive switch over rapidsmpf::MemoryType with a default: RAPIDSMPF_FAIL, reached on the spill path, and it sizes an array by rapidsmpf::MEMORY_TYPES.size().

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions