From 215d9fce814ae896eeffced4c28a7b8e74c453fe Mon Sep 17 00:00:00 2001 From: niranda perera Date: Tue, 1 Sep 2026 10:50:59 -0700 Subject: [PATCH] Add disk resource support --- cmake/thirdparty/get_kvikio.cmake | 12 + .../all_cuda-129_arch-aarch64.yaml | 1 + .../all_cuda-129_arch-x86_64.yaml | 1 + .../all_cuda-133_arch-aarch64.yaml | 1 + .../all_cuda-133_arch-x86_64.yaml | 1 + conda/recipes/librapidsmpf/recipe.yaml | 4 + cpp/CMakeLists.txt | 6 +- cpp/include/rapidsmpf/config_defaults.hpp | 1 + cpp/include/rapidsmpf/disk/disk_resource.hpp | 135 ++++++++++ cpp/src/disk/disk_resource.cpp | 133 ++++++++++ cpp/tests/CMakeLists.txt | 1 + cpp/tests/test_disk_resource.cpp | 246 ++++++++++++++++++ dependencies.yaml | 30 +++ python/librapidsmpf/pyproject.toml | 2 + 14 files changed, 572 insertions(+), 2 deletions(-) create mode 100644 cmake/thirdparty/get_kvikio.cmake create mode 100644 cpp/include/rapidsmpf/disk/disk_resource.hpp create mode 100644 cpp/src/disk/disk_resource.cpp create mode 100644 cpp/tests/test_disk_resource.cpp diff --git a/cmake/thirdparty/get_kvikio.cmake b/cmake/thirdparty/get_kvikio.cmake new file mode 100644 index 000000000..bbe73d617 --- /dev/null +++ b/cmake/thirdparty/get_kvikio.cmake @@ -0,0 +1,12 @@ +# ============================================================================= +# cmake-format: off +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# cmake-format: on +# ============================================================================= + +rapids_find_package( + kvikio REQUIRED + BUILD_EXPORT_SET rapidsmpf-exports + INSTALL_EXPORT_SET rapidsmpf-exports +) diff --git a/conda/environments/all_cuda-129_arch-aarch64.yaml b/conda/environments/all_cuda-129_arch-aarch64.yaml index 970d9f6f5..a2baa36c9 100644 --- a/conda/environments/all_cuda-129_arch-aarch64.yaml +++ b/conda/environments/all_cuda-129_arch-aarch64.yaml @@ -26,6 +26,7 @@ dependencies: - gcc_linux-aarch64=14.* - gdb - ipython +- libkvikio==26.10.*,>=0.0.0a0 - libnuma - libpmix-devel >=5.0,<6.0 - librmm==26.10.*,>=0.0.0a0 diff --git a/conda/environments/all_cuda-129_arch-x86_64.yaml b/conda/environments/all_cuda-129_arch-x86_64.yaml index 9e8fffa1f..8cce2152c 100644 --- a/conda/environments/all_cuda-129_arch-x86_64.yaml +++ b/conda/environments/all_cuda-129_arch-x86_64.yaml @@ -26,6 +26,7 @@ dependencies: - gcc_linux-64=14.* - gdb - ipython +- libkvikio==26.10.*,>=0.0.0a0 - libnuma - libpmix-devel >=5.0,<6.0 - librmm==26.10.*,>=0.0.0a0 diff --git a/conda/environments/all_cuda-133_arch-aarch64.yaml b/conda/environments/all_cuda-133_arch-aarch64.yaml index 108d97678..2674747f7 100644 --- a/conda/environments/all_cuda-133_arch-aarch64.yaml +++ b/conda/environments/all_cuda-133_arch-aarch64.yaml @@ -26,6 +26,7 @@ dependencies: - gcc_linux-aarch64=14.* - gdb - ipython +- libkvikio==26.10.*,>=0.0.0a0 - libnuma - libpmix-devel >=5.0,<6.0 - librmm==26.10.*,>=0.0.0a0 diff --git a/conda/environments/all_cuda-133_arch-x86_64.yaml b/conda/environments/all_cuda-133_arch-x86_64.yaml index 8af165fe3..5798a06d1 100644 --- a/conda/environments/all_cuda-133_arch-x86_64.yaml +++ b/conda/environments/all_cuda-133_arch-x86_64.yaml @@ -26,6 +26,7 @@ dependencies: - gcc_linux-64=14.* - gdb - ipython +- libkvikio==26.10.*,>=0.0.0a0 - libnuma - libpmix-devel >=5.0,<6.0 - librmm==26.10.*,>=0.0.0a0 diff --git a/conda/recipes/librapidsmpf/recipe.yaml b/conda/recipes/librapidsmpf/recipe.yaml index 4159323a4..3eb319a2b 100644 --- a/conda/recipes/librapidsmpf/recipe.yaml +++ b/conda/recipes/librapidsmpf/recipe.yaml @@ -77,6 +77,7 @@ cache: - cuda-version =${{ cuda_version }} - cuda-cupti-dev - cuda-nvml-dev + - libkvikio =${{ minor_version }} - libnuma - libpmix-devel >=5.0,<6.0 - librmm =${{ minor_version }} @@ -111,6 +112,7 @@ outputs: - cuda-version =${{ cuda_version }} - cuda-cupti-dev - cuda-nvml-dev + - libkvikio =${{ minor_version }} - libpmix-devel >=5.0,<6.0 - libucxx ${{ ucxx_version }} - openmpi >=5.0 @@ -118,6 +120,7 @@ outputs: run: - ${{ pin_compatible("cuda-version", upper_bound="x", lower_bound="x") }} - cuda-cupti + - libkvikio =${{ minor_version }} - librmm =${{ minor_version }} - libpmix >=5.0,<6.0 - libucxx ${{ ucxx_version }} @@ -130,6 +133,7 @@ outputs: - ${{ stdlib("c") }} by_name: - cuda-cupti + - libkvikio - librmm - openmpi tests: diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 131c75bb8..322a9a226 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -132,6 +132,7 @@ include(../cmake/thirdparty/get_nvtx.cmake) include(../cmake/thirdparty/get_rmm.cmake) include(../cmake/thirdparty/get_cuco.cmake) include(../cmake/thirdparty/get_cucascade.cmake) +include(../cmake/thirdparty/get_kvikio.cmake) if(RAPIDSMPF_HAVE_UCXX) rapids_find_package( @@ -202,6 +203,7 @@ add_library( src/memory/scoped_memory_record.cpp src/memory/spill.cpp src/memory/spill_manager.cpp + src/disk/disk_resource.cpp src/pausable_thread_loop.cpp src/progress_thread.cpp src/rmm_resource_adaptor.cpp @@ -306,8 +308,8 @@ endif() target_link_libraries( rapidsmpf - PUBLIC rmm::rmm CCCL::CCCL $ $ - CUDA::cudart_static + PUBLIC rmm::rmm CCCL::CCCL kvikio::kvikio $ + $ CUDA::cudart_static PRIVATE cuco::cuco cuCascade::cucascade_topology_discovery $<$:numa> diff --git a/cpp/include/rapidsmpf/config_defaults.hpp b/cpp/include/rapidsmpf/config_defaults.hpp index 3366fb6b0..fd43563e7 100644 --- a/cpp/include/rapidsmpf/config_defaults.hpp +++ b/cpp/include/rapidsmpf/config_defaults.hpp @@ -37,6 +37,7 @@ inline const std::unordered_map DEFAULTS{ {"allow_overbooking_by_default", "true"}, {"log", "WARN"}, {"ucxx_progress_mode", "thread-blocking"}, + {"disk_spill_dir", ""}, }; } // namespace rapidsmpf::config diff --git a/cpp/include/rapidsmpf/disk/disk_resource.hpp b/cpp/include/rapidsmpf/disk/disk_resource.hpp new file mode 100644 index 000000000..2a7145d8f --- /dev/null +++ b/cpp/include/rapidsmpf/disk/disk_resource.hpp @@ -0,0 +1,135 @@ +/** + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include + +#include +#include + +namespace rapidsmpf::disk { + +/** + * @brief Future for a DiskResource read or write. + * + * I/O is submitted before the corresponding DiskResource method returns. The + * pointer passed to write()/read() must remain valid until get() returns. + * + * Concrete implementations live in the translation unit and are returned as + * `std::unique_ptr`. + */ +class DiskFuture { + public: + DiskFuture() = default; + virtual ~DiskFuture() = default; + DiskFuture(DiskFuture&&) = default; ///< Movable. + /** + * @brief Move assignment. + * @returns Moved this. + */ + DiskFuture& operator=(DiskFuture&&) = default; + DiskFuture(DiskFuture const&) = delete; ///< Not copyable. + DiskFuture& operator=(DiskFuture const&) = delete; ///< Not copy-assignable. + + /** + * @brief Whether this future refers to outstanding I/O. + * + * @return True until get() consumes the result. + */ + [[nodiscard]] virtual bool valid() const noexcept = 0; + + /** + * @brief Wait for the transfer, release backend resources, and return the + * byte count. + * + * @return Number of bytes transferred. The caller must check this against + * the requested size. + * + * @note Like `std::future::get()`, this is not thread-safe. Calling get() + * concurrently from multiple threads is undefined behavior. + */ + [[nodiscard]] virtual std::size_t get() = 0; +}; + +/** + * @brief Non-stream-ordered disk I/O for host or device byte buffers. + * + * Uses KvikIO with CompatMode::AUTO (GDS when available, POSIX/compat otherwise). + * + * Callers must synchronize any CUDA stream that produced or consumes a device + * pointer before calling write() or read(). KvikIO is not asked to synchronize + * the default stream (`sync_default_stream=false`). + * + * Disk I/O is intentionally outside the MemoryType / BufferResource taxonomy. + */ +class DiskResource { + public: + DiskResource() = default; + ~DiskResource() = default; + + DiskResource(DiskResource const&) = delete; + DiskResource& operator=(DiskResource const&) = delete; + DiskResource(DiskResource&&) = delete; + DiskResource& operator=(DiskResource&&) = delete; + + /** + * @brief Write bytes to a file. + * + * @param path File path. + * @param data Host or device pointer to the source bytes. + * @param size Number of bytes to write. + * @param mem_type Memory type of @p data. + * @param file_offset Byte offset within the file. + * @return Future that owns backend resources until it is waited. + */ + [[nodiscard]] std::unique_ptr write( + std::filesystem::path const& path, + void const* data, + std::size_t size, + MemoryType mem_type, + std::size_t file_offset = 0 + ); + + /** + * @brief Read bytes from a file. + * + * @param path File path. + * @param data Host or device pointer to the destination buffer. + * @param size Number of bytes to read. + * @param mem_type Memory type of @p data. + * @param file_offset Byte offset within the file. + * @return Future that owns backend resources until it is waited. + */ + [[nodiscard]] std::unique_ptr read( + std::filesystem::path const& path, + void* data, + std::size_t size, + MemoryType mem_type, + std::size_t file_offset = 0 + ); + + /** + * @brief Durably synchronize file data to storage (fdatasync). + * + * Not used on the default spill path; exposed for benchmark durability cases. + * + * @param path File path. + */ + void flush(std::filesystem::path const& path); +}; + +/** + * @brief Spill directory from `disk_spill_dir` (`RAPIDSMPF_DISK_SPILL_DIR`). + * + * An empty option uses the system temporary directory. + * + * @param options Configuration options. + * @return Directory used for spill files. + */ +[[nodiscard]] std::filesystem::path default_spill_directory(config::Options options); + +} // namespace rapidsmpf::disk diff --git a/cpp/src/disk/disk_resource.cpp b/cpp/src/disk/disk_resource.cpp new file mode 100644 index 000000000..757e92ca3 --- /dev/null +++ b/cpp/src/disk/disk_resource.cpp @@ -0,0 +1,133 @@ +/** + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +namespace rapidsmpf::disk { + +namespace { + +class KvikioDiskFuture final : public DiskFuture { + public: + KvikioDiskFuture( + std::unique_ptr file, std::future io + ) + : file_{std::move(file)}, io_{std::move(io)} {} + + ~KvikioDiskFuture() override { + if (io_.valid()) { + try { + std::ignore = get(); + } catch (...) { + } + } + } + + [[nodiscard]] bool valid() const noexcept override { + return io_.valid(); + } + + [[nodiscard]] std::size_t get() override { + auto const n = io_.get(); + file_->close(); + return n; + } + + private: + std::unique_ptr file_; + std::future io_; +}; + +} // namespace + +std::unique_ptr DiskResource::write( + std::filesystem::path const& path, + void const* data, + std::size_t size, + [[maybe_unused]] MemoryType mem_type, + std::size_t file_offset +) { + auto file = std::make_unique( + path.string(), "w+", kvikio::FileHandle::m644, kvikio::CompatMode::AUTO + ); + auto io = file->pwrite( + data, + size, + file_offset, + kvikio::defaults::task_size(), + kvikio::defaults::gds_threshold(), + false // sync_default_stream + ); + return std::make_unique(std::move(file), std::move(io)); +} + +std::unique_ptr DiskResource::read( + std::filesystem::path const& path, + void* data, + std::size_t size, + [[maybe_unused]] MemoryType mem_type, + std::size_t file_offset +) { + auto file = std::make_unique( + path.string(), "r", kvikio::FileHandle::m644, kvikio::CompatMode::AUTO + ); + auto io = file->pread( + data, + size, + file_offset, + kvikio::defaults::task_size(), + kvikio::defaults::gds_threshold(), + false // sync_default_stream + ); + return std::make_unique(std::move(file), std::move(io)); +} + +void DiskResource::flush(std::filesystem::path const& path) { + auto const fd = ::open(path.c_str(), O_RDONLY); + RAPIDSMPF_EXPECTS( + fd >= 0, + "open for fdatasync failed: " + std::string{std::strerror(errno)}, + std::runtime_error + ); + if (::fdatasync(fd) != 0) { + auto const error = std::string{std::strerror(errno)}; + ::close(fd); + RAPIDSMPF_FAIL("fdatasync failed: " + error, std::runtime_error); + } + RAPIDSMPF_EXPECTS( + ::close(fd) == 0, + "close after fdatasync failed: " + std::string{std::strerror(errno)}, + std::runtime_error + ); +} + +std::filesystem::path default_spill_directory(config::Options options) { + return options.get( + "disk_spill_dir", [](std::string const& value) { + if (value.empty()) { + return std::filesystem::temp_directory_path(); + } + return std::filesystem::path{value}; + } + ); +} + +} // namespace rapidsmpf::disk diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index b38f656c2..02bb3a416 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -84,6 +84,7 @@ target_sources( test_config.cpp test_cuda_stream.cpp test_cupti_monitor.cpp + test_disk_resource.cpp test_error_macros.cpp test_host_buffer.cpp test_memory_resources.cpp diff --git a/cpp/tests/test_disk_resource.cpp b/cpp/tests/test_disk_resource.cpp new file mode 100644 index 000000000..2d1d05cda --- /dev/null +++ b/cpp/tests/test_disk_resource.cpp @@ -0,0 +1,246 @@ +/** + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "environment.hpp" + +using namespace rapidsmpf; + +namespace { + +using namespace disk; + +std::string test_path(std::string_view suffix) { + static std::atomic counter{0}; + auto const id = counter.fetch_add(1, std::memory_order_relaxed); + return (default_spill_directory(GlobalEnvironment->options()) + / ("rapidsmpf-disk-test-" + std::to_string(::getpid()) + "-" + + std::to_string(id) + "-" + std::string{suffix} + ".bin")) + .string(); +} + +std::vector make_pattern(std::size_t size) { + std::vector result(size); + for (std::size_t i = 0; i < size; ++i) { + auto const value = + static_cast(((i * 131U) ^ (i >> 7U) ^ 0x5aU) & 0xffU); + result[i] = static_cast(value); + } + return result; +} + +void fill_buffer( + Buffer& buffer, std::vector const& pattern, std::size_t offset +) { + buffer.write_access([&](std::byte* ptr, cuda::stream_ref stream) { + RAPIDSMPF_CUDA_TRY( + cuda_memcpy_async(ptr + offset, pattern.data(), pattern.size(), stream) + ); + }); +} + +// DiskResource is blocking and not stream-ordered; take exclusive access after +// the buffer's latest write has completed. +struct ExclusiveBufferAccess { + explicit ExclusiveBufferAccess(Buffer& buf) : buffer_(buf) { + buffer_.stream().sync(); + ptr_ = buffer_.exclusive_data_access(); + } + + ~ExclusiveBufferAccess() { + buffer_.unlock(); + } + + ExclusiveBufferAccess(ExclusiveBufferAccess const&) = delete; + ExclusiveBufferAccess& operator=(ExclusiveBufferAccess const&) = delete; + ExclusiveBufferAccess(ExclusiveBufferAccess&&) = delete; + ExclusiveBufferAccess& operator=(ExclusiveBufferAccess&&) = delete; + + void write( + DiskResource& disk, + std::filesystem::path const& path, + std::size_t size, + std::size_t ptr_offset = 0, + std::size_t file_offset = 0 + ) { + EXPECT_EQ( + disk.write(path, ptr_ + ptr_offset, size, buffer_.mem_type(), file_offset) + ->get(), + size + ); + } + + void read( + DiskResource& disk, + std::filesystem::path const& path, + std::size_t size, + std::size_t ptr_offset = 0, + std::size_t file_offset = 0 + ) { + EXPECT_EQ( + disk.read(path, ptr_ + ptr_offset, size, buffer_.mem_type(), file_offset) + ->get(), + size + ); + } + + private: + Buffer& buffer_; + std::byte* ptr_{nullptr}; +}; + +std::vector copy_from_buffer( + Buffer const& buffer, std::size_t size, std::size_t offset +) { + std::vector result(size); + RAPIDSMPF_CUDA_TRY( + cuda_memcpy_async(result.data(), buffer.data() + offset, size, buffer.stream()) + ); + buffer.stream().sync(); + return result; +} + +void check_file_contents( + std::filesystem::path const& path, + std::size_t file_offset, + std::vector const& expected +) { + std::vector actual(expected.size()); + std::ifstream file{path, std::ios::binary}; + ASSERT_TRUE(file.good()); + file.seekg(static_cast(file_offset)); + file.read( + reinterpret_cast(actual.data()), + static_cast(actual.size()) + ); + EXPECT_EQ(file.gcount(), static_cast(actual.size())); + EXPECT_EQ(actual, expected); +} + +class DiskResourceTest : public ::testing::TestWithParam { + protected: + void SetUp() override { + if (GlobalEnvironment->type() != TestEnvironmentType::SINGLE) { + GTEST_SKIP() << "Disk I/O tests run only in the single-process environment"; + } + if (GetParam() == MemoryType::PINNED_HOST + && !is_pinned_memory_resources_supported()) + { + GTEST_SKIP() << "Pinned memory resources are not supported on this system"; + } + + auto pinned_pool_properties = is_pinned_memory_resources_supported() + ? PinnedPoolProperties{} + : PinnedMemoryDisabled; + br_ = BufferResource::create( + rmm::mr::get_current_device_resource_ref(), std::move(pinned_pool_properties) + ); + stream_ = cuda::stream_ref{cudaStreamLegacy}; + } + + std::unique_ptr make_buffer(std::size_t size) { + return br_->make_buffer(stream_, br_->reserve_or_fail(size, GetParam())); + } + + DiskResource disk_{}; + std::shared_ptr br_; + cuda::stream_ref stream_{cudaStreamLegacy}; +}; + +INSTANTIATE_TEST_SUITE_P( + MemoryTypes, + DiskResourceTest, + ::testing::ValuesIn(MEMORY_TYPES), + [](::testing::TestParamInfo const& info) { return to_string(info.param); } +); + +TEST_P(DiskResourceTest, RoundTrip) { + auto const path = test_path("roundtrip"); + auto const pattern = make_pattern(64 * 1024); + auto source = make_buffer(pattern.size()); + fill_buffer(*source, pattern, 0); + + ExclusiveBufferAccess{*source}.write(disk_, path, pattern.size()); + + auto destination = make_buffer(pattern.size()); + ExclusiveBufferAccess{*destination}.read(disk_, path, pattern.size()); + + EXPECT_EQ(copy_from_buffer(*destination, pattern.size(), 0), pattern); + ASSERT_TRUE(std::filesystem::remove(path)); +} + +TEST_P(DiskResourceTest, UnalignedOffsetRoundTrip) { + auto const path = test_path("unaligned"); + auto const pattern = make_pattern(16 * 1024); + auto const ptr_offset = std::size_t{1}; + auto const file_offset = std::size_t{1}; + + auto source = make_buffer(pattern.size() + ptr_offset); + fill_buffer(*source, pattern, ptr_offset); + + ExclusiveBufferAccess{*source}.write( + disk_, path, pattern.size(), ptr_offset, file_offset + ); + + EXPECT_EQ(std::filesystem::file_size(path), pattern.size() + file_offset); + check_file_contents(path, file_offset, pattern); + + auto destination = make_buffer(pattern.size() + ptr_offset); + ExclusiveBufferAccess{*destination}.read( + disk_, path, pattern.size(), ptr_offset, file_offset + ); + EXPECT_EQ(copy_from_buffer(*destination, pattern.size(), ptr_offset), pattern); + + ASSERT_TRUE(std::filesystem::remove(path)); +} + +TEST_P(DiskResourceTest, FlushDoesNotThrow) { + auto const path = test_path("flush"); + auto const pattern = make_pattern(4096); + auto source = make_buffer(pattern.size()); + fill_buffer(*source, pattern, 0); + ExclusiveBufferAccess{*source}.write(disk_, path, pattern.size()); + EXPECT_NO_THROW(disk_.flush(path)); + ASSERT_TRUE(std::filesystem::remove(path)); +} + +TEST(DiskSpillDirectory, EmptyOptionUsesTempDir) { + config::Options options; + EXPECT_EQ(default_spill_directory(options), std::filesystem::temp_directory_path()); +} + +TEST(DiskSpillDirectory, UsesConfiguredPath) { + config::Options options{ + {{"disk_spill_dir", config::OptionValue("/tmp/rapidsmpf-spill")}} + }; + EXPECT_EQ( + default_spill_directory(options), std::filesystem::path{"/tmp/rapidsmpf-spill"} + ); +} + +} // namespace diff --git a/dependencies.yaml b/dependencies.yaml index b85bfe9d8..06f23fa01 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -20,6 +20,7 @@ files: - cuda - cuda_version - depends_on_cupy + - depends_on_libkvikio - depends_on_librmm - depends_on_libucxx - depends_on_rmm @@ -45,6 +46,7 @@ files: - cuda - cuda_version - depends_on_cupy + - depends_on_libkvikio - depends_on_librmm - depends_on_libucxx - depends_on_rmm @@ -84,6 +86,7 @@ files: includes: - build-cpp - build-universal + - depends_on_libkvikio - depends_on_librmm - depends_on_libucxx - clang_tidy @@ -118,6 +121,7 @@ files: includes: - build-universal - build-nvml + - depends_on_libkvikio - depends_on_librmm - depends_on_libucxx py_run_librapidsmpf: @@ -126,6 +130,7 @@ files: extras: table: project includes: + - depends_on_libkvikio - depends_on_librmm - depends_on_libucxx py_build_rapidsmpf: @@ -516,6 +521,31 @@ dependencies: - sphinx>=8.1.0 - sphinx-autobuild - sphinx-copybutton + depends_on_libkvikio: + common: + - output_types: conda + packages: + - &libkvikio_unsuffixed libkvikio==26.10.*,>=0.0.0a0 + - output_types: requirements + packages: + # pip recognizes the index as a global option for the requirements.txt file + - --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple + specific: + - output_types: [requirements, pyproject] + matrices: + - matrix: + cuda: "12.*" + cuda_suffixed: "true" + packages: + - libkvikio-cu12==26.10.*,>=0.0.0a0 + - matrix: + cuda: "13.*" + cuda_suffixed: "true" + packages: + - libkvikio-cu13==26.10.*,>=0.0.0a0 + - matrix: + packages: + - *libkvikio_unsuffixed depends_on_librmm: common: - output_types: conda diff --git a/python/librapidsmpf/pyproject.toml b/python/librapidsmpf/pyproject.toml index c989dffa7..6712ef9a1 100644 --- a/python/librapidsmpf/pyproject.toml +++ b/python/librapidsmpf/pyproject.toml @@ -19,6 +19,7 @@ authors = [ license = "Apache-2.0" requires-python = ">=3.11" dependencies = [ + "libkvikio==26.10.*,>=0.0.0a0", "librmm==26.10.*,>=0.0.0a0", "libucxx==0.52.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. @@ -46,6 +47,7 @@ matrix-entry = "cuda_suffixed=true" requires = [ "cmake>=4.0", "cuda-toolkit[nvml]==13.*", + "libkvikio==26.10.*,>=0.0.0a0", "librmm==26.10.*,>=0.0.0a0", "libucxx==0.52.*,>=0.0.0a0", "ninja",