cuCascade Disk I/O Performance Optimization
Performance optimization of cuCascade's disk I/O backends (GDS and kvikIO) to approach raw hardware throughput on NVMe storage. The disk tier enables persisting GPU data batches to disk and reading them back, but current throughput is 5-11x below what the hardware can deliver. This project closes that gap.
Core Value: Both GDS and kvikIO disk I/O backends achieve within 80% of raw hardware throughput (gdsio/dd baselines) for read and write paths.
- Buffer registration: Cannot assume RMM-allocated GPU memory is pre-registered with cuFile — but CAN register temporarily per-transfer for large I/O
- Thread safety: Disk I/O operations must remain safe for concurrent use
- RAII: All file handles and disk resources must follow existing RAII patterns
- API compatibility: idisk_io_backend interface must not change (backends are swappable)
- Benchmark path: Benchmarks should use /mnt/disk_2 for NVMe-fair comparison with baselines
- C++20 - All library source code (
src/memory/,src/data/) and public headers (include/cucascade/) - CUDA C++20 - GPU kernel code (
test/memory/test_gpu_kernels.cu) and direct CUDA runtime calls throughoutsrc/ - CMake 3.26.4+ - Build system (
CMakeLists.txt,cmake/,CMakePresets.json) - Python - Utility scripts (
scripts/generate_api_docs.py,scripts/compare_benchmarks.py)
- Linux only:
linux-64andlinux-aarch64(enforced viapixi.tomlline 4) - NVIDIA GPU required; compute capability >= 7.5 (Turing or newer)
- CUDA Toolkit 12.9+ (cuda-12 track) or 13+ (cuda-13 track)
- NUMA-aware host: requires
libnuma(installed vianumactlpixi dependency) - Pixi >= 0.59
- Config:
pixi.toml - Lockfile:
pixi.lock(committed) - Channels:
rapidsai-nightly,conda-forge(default);rapidsai,conda-forge(cudf-stable feature)
- RMM (RAPIDS Memory Manager) - GPU/host memory resource abstraction; provides
rmm::mr::device_memory_resource,::cuda::stream_ref,rmm::out_of_memory,rmm::bad_alloc; pulled in viafind_package(rmm REQUIRED CONFIG)from libcudf installation - libcudf 26.12 (nightly) / 26.06 (stable) - Columnar data representation for the
cucascade-cudflayer only (not the core); providescudf::table,cudf::column,cudf::type_id,cudf::pack/unpack; pulled in viafind_package(cudf REQUIRED CONFIG), gated onCUCASCADE_BUILD_CUDF - Catch2 v2.13.10 - Unit test framework; fetched via
FetchContentintest/CMakeLists.txt; test executable:cucascade_tests - Google Benchmark v1.8.3 - Microbenchmark framework; fetched via
FetchContentinbenchmark/CMakeLists.txt; benchmark executable:cucascade_benchmarks - Ninja - Build generator (configured in
CMakePresets.json) - sccache - Compiler cache for C, CXX, and CUDA compilers (
CMAKE_C_COMPILER_LAUNCHER,CMAKE_CXX_COMPILER_LAUNCHER,CMAKE_CUDA_COMPILER_LAUNCHERinCMakePresets.json) - clang-format v20.1.4 - Code formatting enforced via pre-commit (
.clang-formatat repo root) - cmake-format / cmake-lint v0.6.13 - CMake file linting via pre-commit
- black v25.1.0 - Python formatting via pre-commit
- codespell v2.4.1 - Spell checking via pre-commit (ignore list:
.codespell_words) - Doxygen - API documentation generation; config:
Doxyfile; output parsed byscripts/generate_api_docs.py
libcudf26.12 / 26.06 - Data representation for thecucascade-cudflayer (not the cudf-free core);cudf::tableis the GPU-tier data container; all column type handling (LIST, STRUCT, STRING, DICTIONARY32, etc.) delegates to cudfRMM(via cudf) -rmm::mr::device_memory_resourceis the base class for all custom allocators;::cuda::stream_refis used throughout for CUDA stream propagationCUDA::cudart- Direct CUDA runtime API calls (cudaMalloc,cudaMemcpyAsync,cudaStreamSynchronize,cudaFree,cudaMallocHost,cudaFreeHost)CUDA::nvml- GPU topology discovery via NVML insrc/memory/topology_discovery.cppkvikio26.12 / 26.06 - Async disk I/O with automatic GDS/POSIX fallback; used insrc/data/kvikio_io_backend.cppviakvikio::FileHandle; linked PRIVATE viakvikio::kvikiolibcufile(cuFile / GDS) - NVIDIA GPUDirect Storage for direct GPU↔NVMe transfers;<cufile.h>used insrc/data/gds_io_backend.cpp; found viafind_library(CUFILE_LIB cufile ...)— optional at configure time, required at runtime for GDS backendlibnuma- NUMA-aware pinned host memory allocation insrc/memory/numa_region_pinned_host_allocator.cpp; found viafind_library(NUMA_LIB numa REQUIRED)Threads::Threads(pthreads) - Thread support;std::mutex,std::condition_variable,std::asyncthroughoutfmt- Format library (pixi dependency; available in environment)CUDA::nvtx3- Header-only NVIDIA NVTX profiling annotations; ranges use thelibcucascadedomain and become active when a profiler injects NVTX tooling
CUDAARCHS- Set by pixi environment activation to select CUDA architecture targetsCMAKE_PREFIX_PATH- Passed through from pixi environment for dependency resolutionCUCASCADE_BUILD_TESTS(default ON) - Addstest/subdirectoryCUCASCADE_BUILD_BENCHMARKS(default ON) - Addsbenchmark/subdirectoryCUCASCADE_BUILD_SHARED_LIBS(default ON) - Buildslibcucascade.soCUCASCADE_BUILD_STATIC_LIBS(default ON) - Buildslibcucascade.aCUCASCADE_BUILD_CUDF(default ON) - Builds the cudf-coupledcucascade-cudflibrary (cudf representations, built-in converters, bandwidth profiler) and gatesfind_package(cudf); OFF yields a cudf-free core buildCUCASCADE_WARNINGS_AS_ERRORS(default ON) - Treats all compiler warnings as errorsdebug→build/debug/release→build/release/relwithdebinfo→build/relwithdebinfo/
cucascade_shared(libcucascade.so, versioned) - aliascuCascade::cucascade_shared; cudf-free core (RMM + CUDA + numa + kvikIO/cuFile)cucascade_static(libcucascade.a) - aliascuCascade::cucascade_staticcuCascade::cucascade- Default alias pointing to shared if available, else staticcucascade_cudf_shared/cucascade_cudf_static(libcucascade_cudf.{so,a}) - aliasescuCascade::cucascade_cudf[_shared|_static], default aliascuCascade::cucascade_cudf; the cudf-coupled layer (linkscudf::cudf+ the core), built only whenCUCASCADE_BUILD_CUDF=ON. Headers underinclude/cucascade/cudf/cucascade_tests- Core (cudf-free) test executable linked against Catch2 andcucascadecucascade_cudf_tests- cudf-coupled test executable linked againstcucascade_cudf(built only whenCUCASCADE_BUILD_CUDF=ON)cucascade_benchmarks- Benchmark executable linked against Google Benchmark andcucascade_cudf(cudf-coupled; built only whenCUCASCADE_BUILD_CUDF=ON)- Headers installed to
include/; CMake package config atcmake/cuCascadeConfig.cmake.in - Consumers:
find_package(cuCascade)+ linkcuCascade::cucascade(cudf-free core); for the cudf representations + built-in converters usefind_package(cuCascade COMPONENTS cudf)+ linkcuCascade::cucascade_cudf. cudf is a package component (resolved lazily viafind_dependency(cudf)only when requested), so core consumers never need cudf installed even against a full (cudf-ON) install
- Linux x86_64 or aarch64
- NVIDIA GPU with compute capability >= 7.5
- Pixi >= 0.59
- CUDA Toolkit 12.9+ or 13+
- Build runner:
linux-amd64-cpu4 - Test/Benchmark runner:
linux-amd64-gpu-t4-latest-1(NVIDIA T4 GPU)
- Headers:
snake_case.hpp— never.hfor project headers - CUDA headers:
snake_case.cuh(e.g.,test/memory/test_gpu_kernels.cuh) - Source:
snake_case.cppfor C++,snake_case.cufor CUDA kernels - Test files:
test_<module_name>.cpp(e.g.,test/data/test_disk_io_backend.cpp) - Benchmark files:
benchmark_<module_name>.cpp(e.g.,benchmark/benchmark_disk_converter.cpp) snake_casefor all:memory_space,data_batch,disk_data_representation- Interface classes prefixed with
i:idata_representation,idisk_io_backend - Config structs suffixed with
_config:gpu_memory_space_config,disk_memory_space_config - Hash structs suffixed with
_hash:converter_key_hash - RAII handles suffixed with
_handle:data_batch_processing_handle - Error category structs suffixed with
_category:memory_error_category - Exception:
Tierenum uses PascalCase name, UPPER_CASE values:Tier::GPU,Tier::HOST,Tier::DISK - Exception:
MemoryErroruses PascalCase name, UPPER_CASE values:MemoryError::ALLOCATION_FAILED snake_case:get_available_memory(),make_reservation_or_null()- Getters prefixed with
get_:get_tier(),get_device_id(),get_batch_id() - Boolean queries prefixed with
should_,has_, oris_:should_downgrade_memory() - Factory functions prefixed with
make_orcreate_:make_mock_memory_space(),create_simple_cudf_table() - Try-pattern methods prefixed with
try_to_:try_to_create_task(),try_to_lock_for_processing() - Blocking wait methods prefixed with
wait_to_:wait_to_create_task() - Member variables prefixed with underscore:
_id,_capacity,_mutex,_disk_table - Local variables:
snake_case—gpu_device_0,reservation_size - Constants:
snake_case—expected_gpu_capacity,default_block_size - Compile-time constants:
constexpr—static constexpr std::size_t default_size{16}; - Size literal constants use
ullsuffix and bit shifts:2ull << 30for 2 GB,1UL << 20for 1 MB - Benchmark-local byte-unit constants:
constexpr uint64_t KiB = 1024ULL; - Function type aliases: PascalCase —
DeviceMemoryResourceFactoryFn,representation_converter_fn(simpler aliases aresnake_case) - Enum classes:
snake_casefor names and values —batch_state::idle,batch_state::in_transit - All caps with
CUCASCADE_prefix:CUCASCADE_CUDA_TRY,CUCASCADE_FAIL,CUCASCADE_FUNC_RANGE
- Tool: clang-format v20.1.4 (enforced by pre-commit hook via
.clang-format) - Column limit: 100 characters
- Indent width: 2 spaces (tabs never used)
- Standard:
c++20 - Brace style: WebKit (
BreakBeforeBraces: WebKit) — opening braces on same line for most constructs - Pointer alignment: left —
void* ptr, notvoid *ptr AlignConsecutiveAssignments: true— align consecutive assignment operatorsAlignConsecutiveMacros: true— align consecutive macro definitionsBinPackArguments: false— all arguments on one line or each on its own line- No trailing whitespace (enforced by pre-commit
trailing-whitespacehook) - Files must end with a newline (enforced by
end-of-file-fixer) - cmake-format and cmake-lint for CMake files (line width 220, disabled code C0307)
- codespell for spell checking (ignore-words in
.codespell_words) - black for Python files
- clang-format for all C++/CUDA source
CUCASCADE_WARNINGS_AS_ERRORS=ONby default — all warnings are errors-Wall -Wextra -Wpedantic-Wcast-align -Wunused -Wconversion -Wsign-conversion-Wnull-dereference -Wdouble-promotion -Wformat=2 -Wimplicit-fallthrough
#include "utils/cudf_test_utils.hpp" // quoted local #include "utils/mock_test_utils.hpp" #include <cucascade/data/disk_data_representation.hpp> // cucascade #include <cucascade/data/representation_converter.hpp> #include <cudf/column/column_factories.hpp> // cuDF #include <rmm/cuda_stream.hpp> // RMM #include <catch2/catch.hpp> // system with dot #include // STL #include
- Top-level:
cucascade - Subnamespaces:
cucascade::memory,cucascade::utils - Test namespace:
cucascade::test - No namespace indentation
- Close with comment:
} // namespace cucascadeor} // namespace - Nested namespaces use traditional form:
namespace cucascade { namespace test {(not C++17::) - Use anonymous
namespace { }for file-local helpers in.cppand test files using namespace cucascade;at file scope in test files is acceptable- Specific test utilities imported explicitly:
using cucascade::test::create_simple_cudf_table; - C++17 nested namespace shorthand used in
test_memory_resources.hpp:namespace cucascade::test {
CUCASCADE_CUDA_TRY(call)— wraps CUDA runtime calls; throwscucascade::cuda_erroron failureCUCASCADE_CUDA_TRY(call, exception_type)— two-arg form throws custom exception typeCUCASCADE_CUDA_TRY_ALLOC(call)— throwsrmm::out_of_memoryfor OOM,rmm::bad_allocotherwiseCUCASCADE_CUDA_TRY_ALLOC(call, num_bytes)— two-arg form includes requested bytes in messageCUCASCADE_ASSERT_CUDA_SUCCESS(call)— assert-based check for noexcept/destructor contexts; in release builds the call executes but the error is discardedCUCASCADE_FAIL(message)— throwscucascade::logic_errorwith file/line contextCUCASCADE_FAIL(message, exception_type)— throws custom exception typecucascade::cuda_error— inheritsstd::runtime_error; for CUDA runtime failurescucascade::logic_error— inheritsstd::logic_error; for programming errorsrmm::out_of_memory,rmm::bad_alloc— for allocation failurescucascade::memory::cucascade_out_of_memory— extendsrmm::out_of_memorywith diagnostics- Use exceptions for errors; not error codes (except
MemoryErrorwhich bridges tostd::error_code) - Use
std::runtime_errororstd::invalid_argumentfor general errors in constructors - Destructors must be exception-safe: use
CUCASCADE_ASSERT_CUDA_SUCCESS(notCUCASCADE_CUDA_TRY) and wrap filesystem operations in try/catch with silent discard (seedisk_data_representation::~disk_data_representation()insrc/data/disk_data_representation.cpp) - Use
[[nodiscard]]on getters and methods returning important values
@brief— one-line summary@param— parameters@return— return values@throws— exception specifications@tparam— template parameters@note— important caveats@code/@endcode— inline code examples (used ininclude/cucascade/data/representation_converter.hpp)@example— usage examples- Multi-line descriptions separated by a blank
*line after@brief - Trailing member docs use
///< description - Section separators:
//===----------------------------------------------------------------------===// - Inline comments use
// // clang-format off/// clang-format onaround macro blocks needing custom formatting
std::unique_ptrfor exclusive ownership (allocators, data representations, reservations, tables)std::shared_ptrfor shared ownership (data batches, memory spaces in tests)std::weak_ptrfor non-owning references (processing handles to batches)- Explicitly delete copy/move when objects must be pinned:
= delete(e.g.,representation_converter_registry) - Explicitly default move when move-only semantics are desired:
= default mutable std::mutex _mutexfor internal locking in thread-safe classes
std::derived_fromconcept inrequiresclauses:requires std::derived_from<TargetType, idata_representation>static_assertwithstd::is_base_of_vat template registration sites[[nodiscard]]attribute on getters[[maybe_unused]]on interface default parameters (e.g.,clone([[maybe_unused]] ::cuda::stream_ref stream))- Structured bindings:
auto [free_bytes, total_bytes] = rmm::available_device_memory(); std::span(in memory layer)- Three-way comparison
<=>(ininclude/cucascade/memory/common.hpp)
- Always-compiled, with negligible overhead until a profiler injects NVTX tooling
CUCASCADE_FUNC_RANGE()macro at function entry points and named scoped ranges for profiling- Custom domain:
cucascade::libcucascade_domain(ininclude/cucascade/error.hpp) - Links the header-only
CUDA::nvtx3target
- Three memory tiers represented by
Tier::GPU,Tier::HOST,Tier::DISKenum values (include/cucascade/memory/common.hpp) - Strategy pattern for reservation requests; converter registry pattern for data tier transitions
- RAII-first ownership: reservations, processing handles, streams, and disk files all release automatically on destruction
data_batchuses 3-class system withdata_batch,read_only_data_batchandmutable_data_batch- C++20 concepts constrain template parameters at compile time;
std::variantdispatches tier-specific allocator types at runtime
- Purpose: Build memory space configs, optionally from NUMA/GPU topology
- Location:
include/cucascade/memory/reservation_manager_configurator.hpp,include/cucascade/memory/config.hpp - Contains:
reservation_manager_configurator(fluent builder),gpu_memory_space_config,host_memory_space_config,disk_memory_space_config,memory_space_config(variant) - Depends on:
topology_discovery - Used by: Application bootstrap code
- Purpose: Query NVML and Linux sysfs for GPU-NUMA-NIC-storage topology
- Location:
include/cucascade/memory/topology_discovery.hpp,src/memory/topology_discovery.cpp - Contains:
topology_discovery,system_topology_info,gpu_topology_info,network_device_info,storage_device_info,NetworkDeviceVerification - Depends on: NVML, Linux sysfs
- Used by:
reservation_manager_configurator - Purpose: Coordinate reservation requests across all memory spaces via strategy pattern
- Location:
include/cucascade/memory/memory_reservation_manager.hpp,src/memory/memory_reservation_manager.cpp - Contains:
memory_reservation_manager, strategy structs (any_memory_space_in_tier,specific_memory_space,any_memory_space_to_downgrade,any_memory_space_to_upgrade,any_memory_space_in_tier_with_preference,any_memory_space_in_tiers) - Depends on: Memory resource layer,
notification_channel - Used by: Data layer, application code
- Purpose: Tier-specific allocation and deallocation with reservation enforcement
- Location:
include/cucascade/memory/reservation_aware_resource_adaptor.hpp,include/cucascade/memory/fixed_size_host_memory_resource.hpp,include/cucascade/memory/disk_access_limiter.hpp - Contains: Per-tier allocators wrapping RMM upstream resources; per-stream/per-thread tracking via atomic counters
- Depends on: RMM, CUDA runtime,
notification_channel,atomicsutilities - Used by:
memory_space - Purpose: Represent a single tier+device location; own its allocator; provide streams
- Location:
include/cucascade/memory/memory_space.hpp,src/memory/memory_space.cpp - Contains:
memory_space(non-copyable, non-movable),memory_space_id,memory_space_hash _reservation_allocatoris astd::variantselectingreservation_aware_resource_adaptor(GPU),fixed_size_host_memory_resource(HOST), ordisk_access_limiter(DISK) at construction time- Depends on: Config layer, memory resource layer
- Used by:
memory_reservation_manager,idata_representation - Purpose: Tier-specific data storage format; all derive from
idata_representation - Location: core base
include/cucascade/data/common.hppandinclude/cucascade/data/disk_data_representation.hpp; cudf-backed reps ininclude/cucascade/cudf/gpu_data_representation.hpp,include/cucascade/cudf/host_data_representation.hpp - Contains:
idata_representation(abstract:get_size_in_bytes(),get_uncompressed_data_size_in_bytes(),clone(), virtualrecord_writer_event()/get_writer_event()/rebind_stream()no-op defaults, templatedcast<T>()); core concrete typedisk_data_representation; cudf-layer concrete typesgpu_table_representation,host_data_representation,host_data_packed_representation disk_data_representationowns adisk_table_allocation(file path + genericmemory::column_metadatavector with opaqueint32_t type_id); destructor deletes the file (RAII). The disk tier is cudf-free; cudf converters translatecudf::type_id↔ the generic tag- Depends on (core base/disk):
memory_space; cudf reps additionally depend on cuDF (cudf::table) - Used by:
data_batch, converter registry - Purpose: Type-pair dispatch table for converting between representation types
- Location:
include/cucascade/data/representation_converter.hpp,src/data/representation_converter.cpp - Contains:
representation_converter_registry,converter_key({source_type_index, target_type_index}),representation_converter_fn - Registration:
register_converter<SourceType, TargetType>(fn)with static_assert constraints - Lookup:
convert<TargetType>(source, memory_space, stream)usestypeid(source)at runtime - The core converter registry ships empty;
register_builtin_converters()(declared ininclude/cucascade/cudf/builtin_converters.hpp, defined insrc/cudf/representation_converter_builtins.cpp, part ofcucascade-cudf) registers GPU↔HOST and GPU↔DISK and HOST↔DISK converters; overload acceptsshared_ptr<idisk_io_backend>to select I/O backend - Depends on:
idata_representation,idisk_io_backend - Used by:
data_batch::convert_to(),data_batch::clone_to() - Purpose: Abstract disk I/O; concrete backends selectable at runtime
- Location:
include/cucascade/data/disk_io_backend.hpp,src/data/gds_io_backend.cpp,src/data/kvikio_io_backend.cpp,src/data/pipeline_io_backend.cpp,src/data/io_backend_internal.hpp - Contains:
idisk_io_backend(abstract withwrite_device,read_device,write_host,read_host,write_device_batch,read_device_batch),io_backend_typeenum (KVIKIO,GDS,PIPELINE),make_io_backend(type)factory GDSuses raw cuFile batch API;KVIKIOuses kvikIO with automatic GDS/POSIX fallback;PIPELINEuses double-buffered pinned host transfer for D2H overlap with disk writes- Depends on: kvikIO, cuFile (GDS)
- Used by: built-in disk converters registered via
register_builtin_converters() - Purpose: Lifecycle management; substription-count reference counting, read-only and mutable locking
- Location:
include/cucascade/data/data_batch.hpp,src/data/data_batch.cpp - Contains:
data_batch(ownsunique_ptr<idata_representation>),batch_stateenum,data_batch_processing_handle(RAII, holdsweak_ptr<data_batch>),idata_batch_probeinterface,lock_for_processing_result - Allowed state transitions:
idle → in_transit | task_created,task_created → processing | idle,processing → idle,in_transit → idle - Depends on:
idata_representation,representation_converter_registry - Used by:
data_repository, application code - Purpose: Partitioned, thread-safe collections of batches; blocking pop with state transition
- Location:
include/cucascade/data/data_repository.hpp,src/data/data_repository.cpp - Contains:
data_repository(storesshared_ptr<data_batch>) and the compatibility aliasshared_data_repository pop_data_batch(target_state)blocks on condition variable until a batch can transitionpop_data_batch_by_id()/get_data_batch_by_id()for directed retrieval- Depends on:
data_batch - Used by:
data_repository_manager - Purpose: Top-level coordinator; operator-port keyed repository map; unique batch ID generation
- Location:
include/cucascade/data/data_repository_manager.hpp - Contains:
data_repository_manager,operator_port_key, and the compatibility aliasshared_data_repository_manager - Batch IDs generated atomically via
_next_data_batch_id(std::atomic<uint64_t>) add_data_batch_implcopies shared batch pointers to each destination repository- Depends on:
data_repository - Used by: Application pipeline code
data_batchmutex protects all state transitions and_processing_count- Blocking
wait_to_*methods use_internal_cvon the batch mutex data_repositorypropagates state change notifications via_state_change_cvpointer set on each batch
- Purpose: Uniform interface for tier-specific storage formats
- Location:
include/cucascade/data/common.hpp - Pattern: Abstract base with
get_size_in_bytes(),get_uncompressed_data_size_in_bytes(),clone(), and templatedcast<T>()(requiresstd::derived_from<T, idata_representation>) - Concrete types:
disk_data_representation(include/cucascade/data/disk_data_representation.hpp, core);gpu_table_representation(include/cucascade/cudf/gpu_data_representation.hpp),host_data_representation,host_data_packed_representation(include/cucascade/cudf/host_data_representation.hpp) — provided by thecucascade-cudflayer - Purpose: Owns a single tier+device memory budget and its allocator
- Location:
include/cucascade/memory/memory_space.hpp - Pattern: Non-copyable/non-movable; variant-based allocator dispatch; exposes
make_reservation_or_null(),should_downgrade_memory(),get_disk_mount_path() - Template helpers:
get_memory_resource_of<Tier::GPU>()returns correctly typed allocator pointer - Purpose: Type-pair dispatch for tier conversions
- Location:
include/cucascade/data/representation_converter.hpp - Pattern:
unordered_map<converter_key, representation_converter_fn>keyed by{typeid(Source), typeid(Target)}; thread-safe with internal mutex - Purpose: Unit of data movement; read-only and mutable locking
- Location:
include/cucascade/data/data_batch.hpp - Pattern: Owns
unique_ptr<idata_representation>;data_batch_processing_handleholdsweak_ptrso handle doesn't keep batch alive;idata_batch_probefor external state observation callbacks - Purpose: On-disk file descriptor and binary format for a serialized cuDF table
- Location:
include/cucascade/memory/disk_table.hpp,include/cucascade/data/disk_file_format.hpp - Pattern: File starts with 32-byte
disk_file_header(magic0x43554353, version, num_columns, metadata_size, data_offset); column metadata serialized depth-first; column data aligned to 4096-byte boundaries for GDS DMA - Purpose: Abstraction over GDS, kvikIO, and pipeline I/O strategies
- Location:
include/cucascade/data/disk_io_backend.hpp - Pattern: Interface with
write_device/read_device/write_host/read_hostand batch variants;make_io_backend(io_backend_type)factory - Purpose: Cross-component signaling when reservations are released
- Location:
include/cucascade/memory/notification_channel.hpp - Pattern: Shared ownership via
shared_ptr;event_notifierinstances post notifications;wait()blocks until notified or shutdown - Purpose: RAII borrow of a CUDA stream from
exclusive_stream_pool - Location:
include/cucascade/memory/stream_pool.hpp - Pattern: Move-only; destructor calls
release_fnreturning stream to pool; acquire policies:GROW(create new) orBLOCK(wait) - Purpose: Strategy pattern determining candidate
memory_spaceobjects for a reservation - Location:
include/cucascade/memory/memory_reservation_manager.hpp - Pattern: Abstract base
get_candidates(manager), concrete strategies:any_memory_space_in_tier,specific_memory_space,any_memory_space_to_downgrade,any_memory_space_to_upgrade,any_memory_space_in_tier_with_preference,any_memory_space_in_tiers
- Location:
include/cucascade/memory/reservation_manager_configurator.hpp - Triggers: Application initialization
- Responsibilities: Fluent builder collects GPU/HOST/DISK settings →
build()emitsvector<memory_space_config>→ caller passes tomemory_reservation_managerconstructor - Location:
include/cucascade/memory/memory_reservation_manager.hpp - Triggers:
request_reservation(strategy, size) - Responsibilities: Evaluate strategy → iterate candidate
memory_spaceobjects → callmake_reservation_or_null()→ block and wait on_wait_cvif none available - Location:
include/cucascade/data/data_repository_manager.hpp - Triggers: Pipeline operator producing a batch
- Responsibilities: Assign unique batch ID via
get_next_data_batch_id()→add_data_batch()routes to the operator-port's repository →add_data_batchnotifies blocked consumers via_cv - Location:
include/cucascade/data/data_batch.hpp(convert_to<T>()) - Triggers: Memory pressure downgrade or upgrade request
- Responsibilities: Lock batch mutex → check
_processing_count == 0→ callregistry.convert<T>()→ replace_datawith new representation
CUCASCADE_CUDA_TRY(call)— throwscucascade::cuda_erroron CUDA runtime failure (defined ininclude/cucascade/error.hpp)CUCASCADE_CUDA_TRY_ALLOC(call, bytes)— throwsrmm::out_of_memoryforcudaErrorMemoryAllocation,rmm::bad_allocotherwiseCUCASCADE_ASSERT_CUDA_SUCCESS(call)— assert in debug builds; no-op in release; used in destructors andnoexceptpathsCUCASCADE_FAIL(msg)/CUCASCADE_FAIL(msg, exception_type)— throwscucascade::logic_erroror custom type with file/line contextcucascade::memory::cucascade_out_of_memoryextendsrmm::out_of_memorywitherror_kind,requested_bytes,global_usage,pool_handleoom_handling_policyinterface (include/cucascade/memory/oom_handling_policy.hpp) allows pluggable OOM recovery; defaultthrow_on_oom_policyreservation_limit_policyhandles over-reservation:ignore,fail, orincreasestrategies
- All public methods on
memory_space,data_batch,data_repository,data_repository_managerare mutex-protected representation_converter_registryuses internal mutex for concurrent register/lookup- Atomic counters (
atomic_bounded_counter,atomic_peak_trackerininclude/cucascade/utils/atomics.hpp) for lock-free allocation tracking in hot paths notification_channelprovides cross-component async signaling withshutdown()supportmemory_reservation_managerowns allmemory_spaceinstances viavector<unique_ptr<memory_space>>memory_spaceowns its allocator and reservation adaptorreservationreleases bytes back to itsmemory_spaceon destructiondata_batchowns itsidata_representationviaunique_ptrdisk_data_representationowns and deletes its backing file on destructiondata_batch_processing_handleholdsweak_ptr<data_batch>to avoid preventing batch destructiondata_batch::convert_to()andclone_to()assert_processing_count == 0before allowing representation swappop_data_batch(batch_state::processing)throws immediately — callers must usetask_created+try_to_lock_for_processing()disk_data_representation::clone()always throwscucascade::logic_error— disk representations must be materialized to another tier via converterCUCASCADE_FUNC_RANGE()emits an NVTX range in thelibcucascadedomain- Custom domain:
cucascade::libcucascade_domain(defined ininclude/cucascade/error.hpp)
Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync.
Use these entry points:
/gsd:quickfor small fixes, doc updates, and ad-hoc tasks/gsd:debugfor investigation and bug fixing/gsd:execute-phasefor planned phase work
Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it.
Profile not yet configured. Run
/gsd:profile-userto generate your developer profile. This section is managed bygenerate-claude-profile-- do not edit manually.