Dry Run Protocol - #2961
Conversation
…mory Introduce a dry-run execution framework that replaces device and host memory resources with lightweight fake allocators to measure peak memory usage without holding real memory. New files: - dry_run_memory_resource.hpp: dry_run_allocator (lock-free bump allocator), dry_run_device_memory_resource, dry_run_host_memory_resource, dry_run_resource_manager (RAII), and dry_run_execute() helper. - dry_run_flag.hpp: boolean dry-run flag as a raft resource, allowing algorithms to skip kernel execution during profiling. - tests/util/dry_run_memory_resource.cpp: unit tests. The dry_run_allocator probes the upstream once to obtain a base address, then atomically bumps a pointer for each allocation — no mutex, no map, no real memory held after the initial probe.
…pinned_memory_resource Add pinned and managed resources to the raft::resources handle to make it possible to customize / temporarily replace these resources
…aking change due to transitive includes in downstream libraries
Merges Remove deprecated headers (NVIDIA#2939). Conflict resolutions: - rsvd.cuh: Use new mdspan-based raft::matrix::sqrt and reciprocal APIs (they have internal dry-run guards); kept cudaMemsetAsync guard - svd.cuh: Use raft::matrix::weighted_sqrt (has internal dry-run guard) - matrix.cuh: Accept deletion (deprecated, removed in main) Co-authored-by: Cursor <cursoragent@cursor.com>
A non-breaking src-only changes to modernize the use of raft primitives across cuVS source code. The general rule applied here is to prefer raft helpers taking `raft::resources` as an argument over other raft helpers over third-party libraries. - thrust::fill / thrust::fill_n → raft::matrix::fill - thrust::transform → raft::linalg::map - thrust::sequence / thrust::tabulate → raft::linalg::map_offset - raft::linalg::unaryOp / raft::linalg::binaryOp → raft::linalg::map - raft::linalg::add (pointer-based) → raft::linalg::add (mdspan-based) - raft::copy (pointer-based) → raft::copy (mdspan-based) - raft::update_device / raft::update_host → raft::copy (mdspan-based) - raft::linalg::rowNorm → raft::linalg::norm - raft::linalg::reduce (pointer-based) → raft::linalg::reduce (mdspan-based) - cudaMemsetAsync → raft::matrix::fill The purpose of this PR is to improve the consistency in using the library code (even though sometimes at the cost of a bit more auxiliary code). This is also a prerequisite to achieving dry run compliance in cuVS if we choose to merge that in NVIDIA/raft#2961 Authors: - Artem M. Chirkin (https://github.com/achirkin) Approvers: - Dante Gama Dessavre (https://github.com/dantegd) URL: NVIDIA#1837
huuanhhuyn
left a comment
There was a problem hiding this comment.
Thanks @achirkin for the heavy-lifting! I have went through this PR halfway.
| */ | ||
| inline void sync_stream(const resources& res, rmm::cuda_stream_view stream) | ||
| { | ||
| if (raft::resource::get_dry_run_flag(res)) { return; } |
There was a problem hiding this comment.
What is the motivation for guarding sync_stream?
Your dry_run_protocol.md suggests the opposite that sync_stream is safe without guard.
There was a problem hiding this comment.
The guide says it's safe to call this function, because it is dry-run compliant (takes the raft::resources as an argument) - hence it guards from any CUDA work inside.
cudaStreamSynchronize is cuda CUDA and it takes time, so we must guard it.
There was a problem hiding this comment.
If I understand dry-run correctly, when res is in dry-run mode, the stream contains no CUDA work and contains only light-weight fake memory operations. Therefore it would be fast to sync.
If user intentionally adds a CUDA/memory work to the stream without guarding, he wants the sync_stream to work I suppose.
I mean this guarding on sync stream wouldn't bring any benefit but limit its usage a little.
There was a problem hiding this comment.
It is still CUDA work and a call to cuda context, which may briefly lock. In dry run mode, nobody should ever call CUDA, that is a hard constraint.
|
|
||
| 1. **Allocations must not be guarded.** Every `rmm::device_uvector`, `rmm::device_scalar`, `rmm::device_buffer`, `raft::make_(device|host|pinned|managed)_(mdarray|matrix|vector|scalar)` allocation must execute in both modes so the tracker sees it. | ||
|
|
||
| 2. **CUDA work must be guarded.** Kernel launches, Thrust algorithms, cuBLAS/cuSOLVER/cuSPARSE compute calls, `cudaMemcpyAsync`, `cudaMemsetAsync`, and `raft::interruptible::synchronize` must not run in dry-run mode. |
There was a problem hiding this comment.
if all CUDA work is guarded / skipped in dry-run. How do we measure allocations whose allocation sizes are produced by a kernel?
If that kernel is dependent on earlier kernels and so on, dry-run must then execute all of them without guarding?
There was a problem hiding this comment.
The case you're describing falls under "allocation size depends on values/data". This is indeed generally a problem and we resort to providing safe upper bounds on allocations. Have a look at the sparse namespace - we have a lot cases like this.
In tests, this is covered by DATA_DRIVEN provenance: we compare that dry run produced stats are not smaller than the real produced stats.
There was a problem hiding this comment.
Is finding the upper bound always possible? And what if the upper bound is 3x, 10x?
| * This ensures the memory is released promptly. | ||
| */ | ||
| void reallocate(size_type size) | ||
| { |
There was a problem hiding this comment.
Although your implementation avoids peak data (old + new) when the new size is larger than the current size, it has two issues:
- when the new size is the same -> it does NOT reallocate while its name is "reallocate"
- when the new size is smaller -> it DOES allocate while it could more efficiently shrink the current buffer (similar to what
resize()already does)
I would suggest to do the current implementation only when the new size is larger. When the new size is less or equal, simply call resize() and clear the buffer.
I am not sure about clearing the buffer. It adds some overhead, but it sounds safer to me.
There was a problem hiding this comment.
Funny enough, both of these are pretty much intentional features. Here's a bit more context for this.
By design, mdarrays and mdspans are not supposed to be resizeable at all. However, at some point we decided to implement sparse matrices using the same container policies as mdarrays. For sparse data, one needs the resize functionality to allow changing sparsity pattern. So the resize function is exclusively used for sparse data and only to allocate a new sparse matrix storage of the required size (initialize_sparsity).
Back to reallocate addressing your concerns. The intention here is to always free up the memory as soon as requested: the released buffer may be huge (e.g. half of GPU memory); the user may want to use the memory as soon as possible, so we want it to be available.
Essentially reallocate is almost the same as running resize + shrink_to_fit on an underlying RMM container. But there's a catch: reallocate guarantees to NOT copy the data. This catch is important for dry run: we fake the memory allocations, so any memory copy would cause OOM / break the program.
There was a problem hiding this comment.
Thank you for sharing the context with sparse matrix.
I still don't understand why when the new size is less than or equal to the current size, we don't simply free the redundant memory and keep the remaining new size part. This will give back immediately current_size - new_size to the user. Or do you mean we have to free everything at the current address and then allocate the new size some where else? If so, why?
There was a problem hiding this comment.
The current implementation makes sense to me only when the new size is greater than the current size
| @@ -0,0 +1,92 @@ | |||
| # Dry Run Protocol | |||
|
|
|||
| The dry run protocol lets callers estimate an algorithm's memory footprint without executing it. When enabled, the runtime swaps memory resources for lightweight trackers that record every allocation and deallocation, producing peak-usage statistics at the end. | |||
There was a problem hiding this comment.
I suppose we are not able to track non-raft allocations with dry-run. It is probably fine but we should be aware and document it somewhere.
Are we using third-party libraries which do allocations without RAFT somewhere? I am not aware about it.
There was a problem hiding this comment.
Plenty of rapids org libraries use the rmm memory resources directly. They are tracked though.
There was a problem hiding this comment.
And non-rapidsai libraries like Cutlass, CUB, Thrust, etc.? Are their allocations tracked?
There was a problem hiding this comment.
This is covered in the same file below in the section "What Needs Guarding". In general, I don't think it's sustainable to maintain a list of all possible libraries to tell whether they use rmm or not. But it's normally clear from the API or documentation of those libraries.
Please also refer to the presentation for the relevant overview https://drive.google.com/file/d/1uMkM-Xzhi-2ZAKe_z3zvCfHoefn0bAAx/view?usp=drive_link
divyegala
left a comment
There was a problem hiding this comment.
Would you consider guarding the kernel launch behind a dispatch function/macro where the dry run flag is checked, like we talked in your offline brown bag session?
|
Hi @divyegala , I definitely want to do that, but maybe in a separate PR in parallel, where we could focus on discussing the pros and cons of different approaches to do that? The main issue I see is that for being useful for dry run, the dispatcher should take |
|
@achirkin thank you, that makes sense to me. I will start reviewing the PR in its current form. 👍 |
There was a problem hiding this comment.
Actionable comments posted: 1
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
cpp/include/raft/matrix/detail/select_radix.cuh (1)
1280-1337: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftDo not query CUDA occupancy during dry-run.
Lines 1302-1337 dispatch to
radix_topk_one_blockorradix_topk. Both functions callcalc_chunk_sizebefore theirif (dry_run)return.calc_chunk_sizecallscudaOccupancyMaxActiveBlocksPerMultiprocessor. The multi-block path can also callcalc_grid_dim, which makes the same CUDA Runtime call.A dry-run invocation therefore enters CUDA Runtime before it returns. Guard the occupancy queries. Use a dry-run workspace sizing path that does not call CUDA Runtime APIs.
#!/bin/bash set -euo pipefail file="cpp/include/raft/matrix/detail/select_radix.cuh" # Inspect the dry-run return placement relative to occupancy queries. sed -n '806,837p;880,920p;1153,1190p;1275,1340p' "$file" # Confirm all occupancy-query call sites and dry-run guards. rg -n -C 3 'cudaOccupancyMaxActiveBlocksPerMultiprocessor|calc_chunk_size|calc_grid_dim|if \(dry_run\)' "$file"As per path instructions, “functions using raw streams or CUDA work must guard execution with
resource::get_dry_run_flag(res).”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/matrix/detail/select_radix.cuh` around lines 1280 - 1337, Ensure dry-run execution in the radix top-k dispatch does not invoke CUDA Runtime occupancy APIs. Update calc_chunk_size and calc_grid_dim, and the radix_topk_one_block/radix_topk paths that call them, to use a deterministic workspace-sizing path when dry_run is true and only query CUDA occupancy for real execution; preserve normal dispatch and sizing behavior otherwise.cpp/include/raft/linalg/power.cuh (1)
79-95: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winMove the dry-run guard below the input validation.
In both
powerandpower_scalar, the guard returns before theRAFT_EXPECTSchecks. In dry-run mode, contiguity and size mismatches are therefore not reported, and the caller receives a memory estimate for an input that will fail in the real run.Neither function allocates memory, so moving the guard after the validation block does not change allocation tracking. It only skips the kernel launch, which is the intent.
cpp/include/raft/stats/stddev.cuhandcpp/include/raft/stats/dispersion.cuhin this PR already keep theirRAFT_EXPECTSchecks ahead of the dry-run dispatch.🛡️ Proposed fix for both overloads
void power(raft::resources const& handle, InType in1, InType in2, OutType out) { - if (resource::get_dry_run_flag(handle)) { return; } using in_value_t = typename InType::value_type; using out_value_t = typename OutType::value_type; RAFT_EXPECTS(raft::is_row_or_column_major(out), "Output must be contiguous"); RAFT_EXPECTS(raft::is_row_or_column_major(in1), "Input 1 must be contiguous"); RAFT_EXPECTS(raft::is_row_or_column_major(in2), "Input 2 must be contiguous"); RAFT_EXPECTS(out.size() == in1.size() && in1.size() == in2.size(), "Size mismatch between Output and Inputs"); + if (resource::get_dry_run_flag(handle)) { return; } power<in_value_t, out_value_t, typename OutType::index_type>({ - if (resource::get_dry_run_flag(handle)) { return; } using in_value_t = typename InType::value_type; using out_value_t = typename OutType::value_type; RAFT_EXPECTS(raft::is_row_or_column_major(out), "Output must be contiguous"); RAFT_EXPECTS(raft::is_row_or_column_major(in), "Input must be contiguous"); RAFT_EXPECTS(out.size() == in.size(), "Size mismatch between Output and Input"); + if (resource::get_dry_run_flag(handle)) { return; } powerScalar<in_value_t, out_value_t, typename OutType::index_type>(One caveat:
power_scalardereferences*scalar.data_handle()after the guard. That host read is safe only if the scalar is a real host allocation. Confirm thatmake_host_scalarin dry-run mode still yields a readable pointer, becausecpp/include/raft/core/host_mdarray.hppskips value initialization in dry-run mode.Also applies to: 118-132
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/linalg/power.cuh` around lines 79 - 95, Move the dry-run guard below all RAFT_EXPECTS validation in both power and power_scalar, so contiguity and size checks always execute before skipping the kernel launch. Preserve the existing validation and dry-run behavior, and verify that power_scalar’s dereference of scalar.data_handle() remains safe with make_host_scalar in dry-run mode; adjust only if that pointer is not readable.
🟠 Major comments (20)
cpp/include/raft/sparse/op/detail/reduce.cuh-137-149 (1)
137-149: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winReject scan sizes that do not fit CUB's item count.
Lines 137 and 149 narrow
diff.size()toint. IfnnzexceedsINT_MAX, the CUB scan receives a truncated or invalid item count. The later read fromdiff.back()then does not represent a scan over all nonzeros. Validate the bound before the workspace query, or use a supported CUB interface with a wider item-count type.As per coding guidelines, add input validation when invalid dimensions can cause incorrect behavior.
#!/bin/bash set -euo pipefail rg -n -C 4 'max_duplicates|static_cast<int>\(diff.size\(\)\)|nnz_t' \ cpp/include/raft/sparse/op/detail/reduce.cuh cpp/include/raft/sparse🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/sparse/op/detail/reduce.cuh` around lines 137 - 149, Validate before both CUB scan calls that diff.size() is no greater than the maximum representable int, and reject the input with the established validation mechanism when it exceeds that bound. Update the workspace query and scan in the surrounding reduction flow to use only a validated item count, preserving full coverage of all nonzeros and preventing narrowing overflow.cpp/include/raft/sparse/op/detail/reduce.cuh-136-149 (1)
136-149: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winCheck both CUB scan calls.
Lines 136-137 and 148-149 ignore the CUDA status from
cub::DeviceScan::ExclusiveSum. A failed workspace query can leavescan_ws_bytesinvalid. A failed scan can continue to the host copy and use invalid scan data. Wrap both calls withRAFT_CUDA_TRY.Proposed fix
- cub::DeviceScan::ExclusiveSum( - nullptr, scan_ws_bytes, diff.data(), diff.data(), static_cast<int>(diff.size()), stream); + RAFT_CUDA_TRY(cub::DeviceScan::ExclusiveSum( + nullptr, scan_ws_bytes, diff.data(), diff.data(), static_cast<int>(diff.size()), stream)); ... - cub::DeviceScan::ExclusiveSum( - scan_ws.data(), scan_ws_bytes, diff.data(), diff.data(), static_cast<int>(diff.size()), stream); + RAFT_CUDA_TRY(cub::DeviceScan::ExclusiveSum( + scan_ws.data(), scan_ws_bytes, diff.data(), diff.data(), static_cast<int>(diff.size()), stream));As per coding guidelines, “kernel launches, memory operations, and synchronization must use RAFT/CUDA error checking.” As per path instructions, use checked CUDA macros.
#!/bin/bash set -euo pipefail rg -n -C 3 'DeviceScan::ExclusiveSum|RAFT_CUDA_TRY' \ cpp/include/raft/sparse/op/detail/reduce.cuh🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/sparse/op/detail/reduce.cuh` around lines 136 - 149, Wrap both cub::DeviceScan::ExclusiveSum calls in RAFT_CUDA_TRY, including the workspace-size query and the actual scan, so CUDA failures are propagated before scan_ws allocation or subsequent data use.cpp/include/raft/linalg/detail/lstsq.cuh-213-216 (1)
213-216: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winUse exception-safe cleanup for
gesvdj_params.The dry-run branch destroys
gesvdj_params, but the normal path does not destroy it. A later allocation failure or checked cuSOLVER failure also bypasses this cleanup. Use an RAII owner or a scope guard immediately aftercusolverDnCreateGesvdjInfosucceeds.As per path instructions, review CUDA call sites for “leaks or exception-path cleanup failures.”
#!/bin/bash set -euo pipefail rg -n -C 8 \ 'lstsqSvdJacobi|cusolverDnCreateGesvdjInfo|cusolverDnDestroyGesvdjInfo' \ cpp/include/raft/linalg/detail/lstsq.cuh🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/linalg/detail/lstsq.cuh` around lines 213 - 216, Make cleanup of gesvdj_params exception-safe in the code surrounding cusolverDnCreateGesvdjInfo: establish an RAII owner or scope guard immediately after successful creation that calls cusolverDnDestroyGesvdjInfo exactly once on every exit path, including dry-run returns, allocation failures, and checked cuSOLVER errors. Remove the manual dry-run-only destruction in the lstsqSvdJacobi flow to avoid double cleanup.cpp/include/raft/sparse/convert/detail/bitset_to_csr.cuh-123-126 (1)
123-126: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winCheck both CUB scan calls.
cub::DeviceScan::ExclusiveSumreturns a CUDA status. If either call fails, the code can continue with invalid workspace or CSR row-offset data. Wrap both calls withRAFT_CUDA_TRY.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/sparse/convert/detail/bitset_to_csr.cuh` around lines 123 - 126, Wrap both cub::DeviceScan::ExclusiveSum calls in RAFT_CUDA_TRY, including the workspace-size query and the actual scan execution. Ensure any CUDA failure is propagated before using scan_ws or the generated CSR row offsets.Sources: Coding guidelines, Path instructions
cpp/include/raft/stats/detail/scores.cuh-183-183 (1)
183-183: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winMove host-vector allocations after the dry-run return.
std::vector<double> h_sorted_abs_diffs(n)allocates host memory before this check. A large dry-run request can consume or exhaust host memory without contributing to RAFT allocation statistics. Keep the RMM allocations before this check, but constructmean_errorsandh_sorted_abs_diffsonly after dry-run mode returns.Proposed fix
- std::vector<double> mean_errors(2); - std::vector<double> h_sorted_abs_diffs(n); int thread_cnt = 256; int block_cnt = raft::ceildiv(n, thread_cnt); if (dry_run) { return; } + std::vector<double> mean_errors(2); + std::vector<double> h_sorted_abs_diffs(n); RAFT_CUDA_TRY(cudaMemsetAsync(tmp_sums.data(), 0, 2 * sizeof(double), stream));As per path instructions, dry-run implementations must suppress real allocations while leaving RMM/RAFT allocation attempts unguarded.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/stats/detail/scores.cuh` at line 183, Move the dry_run return in the surrounding score computation before constructing the host vectors mean_errors and h_sorted_abs_diffs, while keeping the existing RMM/RAFT allocation attempts before that return. Ensure dry-run mode performs no host-vector allocations and exits immediately after those allocation attempts.Source: Path instructions
cpp/tests/sparse/reduce.cu-65-82 (1)
65-82: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy liftThe COO output
outis allocated inside the dry-run scope but declared outside it.
outis constructed at Line 65, outside the wrapper. During the dry-run pass,max_duplicatesreaches the dry-run branch incpp/include/raft/sparse/op/detail/reduce.cuhand callsout.allocate(nnz, m, n, false, stream). That allocation uses the temporary dry-run memory resource installed byexecute_with_dry_run_check. When the wrapper exits,outstill owns those probe-backed buffers, and they are later freed or reallocated against the restored resource.This is the same hazard that
cpp/tests/core/bitset.cudocuments at Lines 201-203, where the whole object lifetime is kept inside the dry-run scope. Declareoutinside the callback, or confirm that the dry-run resource outlives every object it allocated.The inline comment at Lines 66-67 states that the COO output is not tracked. That statement does not match the implementation, which allocates the output during the dry-run pass.
#!/bin/bash # Check the lifetime semantics of the dry-run resource wrapper and the COO allocate path. set -euo pipefail fd -t f 'dry_run_resources.hpp' cpp/include | while IFS= read -r f; do echo "=== $f ===" cat -n "$f" done echo "=== execute_with_dry_run_check definition ===" rg -n -C 25 'execute_with_dry_run_check' cpp/include cpp/tests --glob '*.{hpp,cuh,h}' echo "=== COO::allocate ===" rg -n -C 15 'void allocate' cpp/include/raft/sparse/coo.hpp🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/tests/sparse/reduce.cu` around lines 65 - 82, Move construction of the COO variable out of the surrounding scope and into the dry-run callback containing max_duplicates, keeping its entire lifetime within execute_with_dry_run_check. Remove or update the inaccurate comments claiming the COO output is not tracked, and ensure the callback’s output remains available to the subsequent test logic as required.cpp/tests/core/bitset.cu-388-399 (1)
388-399: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winGate the
anyandnoneassertions on the dry-run flag.Lines 390-391 assert values without checking
resource::get_dry_run_flag(h), but every other value-dependent assertion in this callback is gated. In the dry-run pass,my_bitset.reset(h, false)performs no CUDA work, soany(h)andnone(h)read probe-backed memory whose contents are undefined. These two assertions can fail during the dry-run pass.The assertions at Lines 395-399 already cover the same two calls correctly.
💚 Proposed fix
// Test count() operations my_bitset.reset(h, false); - ASSERT_EQ(my_bitset.any(h), false); - ASSERT_EQ(my_bitset.none(h), true); + if (!resource::get_dry_run_flag(h)) { + ASSERT_EQ(my_bitset.any(h), false); + ASSERT_EQ(my_bitset.none(h), true); + } raft::linalg::map_offset(h, query_device.view(), raft::cast_op<index_t>{});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/tests/core/bitset.cu` around lines 388 - 399, Gate the initial my_bitset.any(h) and my_bitset.none(h) assertions after reset on resource::get_dry_run_flag(h), matching the existing guarded value-dependent assertions below. Keep the reset and subsequent setup unchanged, and preserve the assertions during non-dry-run execution.cpp/include/raft/solver/detail/lap_functions.cuh-269-271 (1)
269-271: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winCalculate dry-run allocation counts in
size_t.Both sites evaluate
SP * Nbeforedevice_uvectorreceives the value. If the product exceeds the source integer type, overflow produces an invalid allocation size and an incorrect peak-memory estimate.
cpp/include/raft/solver/detail/lap_functions.cuh#L269-L271: derive a checkedsize_t matrix_sizebefore allocatingpredicates_v,addresses_v, andcsr_neighbors_v.cpp/include/raft/solver/detail/lap_functions.cuh#L432-L436: derive the same checkedsize_t matrix_sizebefore allocatingpredicates_v,addresses_v, andelements_v.#!/bin/bash set -euo pipefail rg -n -C 3 'device_uvector<.*>\([^;]*SP \* N' cpp/include/raft/solver/detail/lap_functions.cuh🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/solver/detail/lap_functions.cuh` around lines 269 - 271, In cpp/include/raft/solver/detail/lap_functions.cuh at lines 269-271 and 432-436, compute a checked size_t matrix_size from SP and N before constructing the device_uvector instances; use that variable for predicates_v, addresses_v, csr_neighbors_v, and elements_v at the respective sites, preserving the existing allocation behavior while preventing source-type overflow.cpp/include/raft/stats/detail/contingencyMatrix.cuh-209-219 (1)
209-219: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPrevent overflow in the dry-run workspace estimate.
Line 217 evaluates
4 * nSamplesasint. IfnSamples > INT_MAX / 4, signed overflow occurs before conversion tosize_t. The dry-run estimate can then under-report or corrupt the required workspace size.Validate
nSamplesand promote it before every size calculation.Proposed fix
+ RAFT_EXPECTS(nSamples >= 0, "nSamples must be non-negative"); + auto sample_count = static_cast<size_t>(nSamples); if (dry_run) { - auto tmpStagingMemorySize = raft::alignTo<size_t>(nSamples * sizeof(T), 256); + auto tmpStagingMemorySize = raft::alignTo<size_t>(sample_count * sizeof(T), 256); tmpStagingMemorySize *= 2; - size_t cubWorkspaceUpperBound = 4 * nSamples * sizeof(T); + size_t cubWorkspaceUpperBound = size_t{4} * sample_count * sizeof(T);#!/bin/bash set -euo pipefail python3 - <<'PY' import ctypes max_int = (1 << (ctypes.sizeof(ctypes.c_int) * 8 - 1)) - 1 print(f"INT_MAX={max_int}") print(f"First overflowing nSamples for 4 * nSamples: {max_int // 4 + 1}") PY🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/stats/detail/contingencyMatrix.cuh` around lines 209 - 219, Prevent signed overflow in the dry-run calculations within the contingency-matrix workspace sizing block by validating nSamples against the supported range and promoting it to size_t before every multiplication, including the tmpStagingMemorySize and cubWorkspaceUpperBound expressions. Preserve the existing alignment and workspace estimate behavior for valid sample counts, and reject or otherwise handle values that cannot be represented safely.cpp/include/raft/stats/detail/meanvar.cuh-212-223 (1)
212-223: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winGuard the occupancy CUDA call during dry runs.
Line 212 guards the memset and kernel launches, but lines 203-207 still call
cudaOccupancyMaxActiveBlocksPerMultiprocessorwhendry_runis true. This makes a memory-only probe issue a CUDA runtime query. Move the occupancy calculation andgs.yadjustment into the!dry_runbranch.As per path instructions, dry-run implementations must suppress CUDA work while preserving allocation tracking.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/stats/detail/meanvar.cuh` around lines 212 - 223, Move the cudaOccupancyMaxActiveBlocksPerMultiprocessor call and related gs.y adjustment into the existing !dry_run branch around meanvar_kernel_rowmajor and meanvar_kernel_fill. Ensure dry_run performs no CUDA runtime queries or kernel work while retaining the existing buffer allocation and tracking behavior.Source: Path instructions
cpp/include/raft/sparse/solver/detail/lanczos.cuh-158-169 (1)
158-169: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winCheck all five CUDA kernel launches with
RAFT_CUDA_TRY(cudaPeekAtLastError()).Add the check immediately after
kernel_triangular_populate,kernel_triangular_beta_k,kernel_clamp_down,kernel_clamp_down_vector, andkernel_normalize.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/sparse/solver/detail/lanczos.cuh` around lines 158 - 169, Add RAFT_CUDA_TRY(cudaPeekAtLastError()) immediately after each of the five CUDA launches in lanczos.cuh: kernel_triangular_populate and kernel_triangular_beta_k in lines 158-169, plus kernel_clamp_down, kernel_clamp_down_vector, and kernel_normalize in lines 386-415. Keep the checks directly adjacent to their respective launches.Sources: Coding guidelines, Path instructions
cpp/include/raft/sparse/convert/detail/bitmap_to_csr.cuh-309-315 (1)
309-315: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winAllocate
scan_wsfromdevice_memory. The current constructor uses the default device resource, so custom workspace-resource accounting and isolation do not include the CUB scan workspace.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/sparse/convert/detail/bitmap_to_csr.cuh` around lines 309 - 315, Construct scan_ws with device_memory, matching the resource used for sub_nnz, so the CUB scan workspace is accounted for by the configured workspace resource.Sources: Coding guidelines, Path instructions
cpp/include/raft/sparse/solver/detail/lanczos.cuh-198-227 (1)
198-227: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse the handle-bound Thrust policy.
thrust::deviceruns on the default CUDA stream, while neighboring operations use the handle stream. This can break ordering for non-default handle streams. Useauto thrust_policy = resource::get_thrust_policy(handle)forthrust::sequenceand boththrust::sortcalls.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/sparse/solver/detail/lanczos.cuh` around lines 198 - 227, Use a handle-bound Thrust execution policy for all operations in this selection block: define thrust_policy via resource::get_thrust_policy(handle), then pass it to thrust::sequence and both thrust::sort calls instead of thrust::device. Preserve the existing index ordering and eigenvalue selection logic.Sources: Coding guidelines, Path instructions
cpp/include/raft/matrix/detail/select_k-inl.cuh-131-132 (1)
131-132: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winCheck each CUB sort status before the dry-run return.
SortPairsandSortPairsDescendingreturn CUDA status. The dry-run path returns after an unchecked workspace query. If that query fails, dry-run can report memory usage instead of returning the CUDA error. Wrap both workspace queries and both execution calls withRAFT_CUDA_TRY.#!/bin/bash set -euo pipefail sed -n '90,170p' cpp/include/raft/matrix/detail/select_k-inl.cuh rg -n -C 2 'RAFT_CUDA_TRY' cpp/include/raft/core/detail/macros.hpp cpp/include/raft🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/matrix/detail/select_k-inl.cuh` around lines 131 - 132, Update the CUB sort calls in the select-k implementation, including both SortPairs and SortPairsDescending workspace-size queries and execution calls, to use RAFT_CUDA_TRY. Ensure each status is checked before the resource::get_dry_run_flag(handle) early return so failed dry-run workspace queries propagate the CUDA error.cpp/include/raft/stats/detail/silhouette_score.cuh-229-230 (1)
229-230: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftUse one ordered stream for dependent operations.
pairwise_distance(handle, ...)andmatrix_vector_op(handle, ...)use the stream inhandle. The dependent operations usestream. If these streams differ, the reductions can readdistanceMatrixoraverageDistanceBetweenSampleAndClusterbefore the producer work completes.Use
resource::get_cuda_stream(handle)for all operations in this function, or add explicit event ordering between the two streams. As per path instructions, maintain asynchronous stream ordering and use RAFT-managed streams for internal work.Also applies to: 268-276
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/stats/detail/silhouette_score.cuh` around lines 229 - 230, Update the operations in the silhouette-score function, including pairwise_distance and the dependent matrix_vector_op/reduction calls, to use the same RAFT-managed stream obtained via resource::get_cuda_stream(handle). Preserve asynchronous ordering and ensure every producer and consumer of distanceMatrix and averageDistanceBetweenSampleAndCluster is submitted to that stream.Source: Path instructions
cpp/include/raft/matrix/threshold.cuh-38-38 (1)
38-38: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winKeep the dimension check outside the dry-run guard.
RAFT_EXPECTS(in.size() == out.size(), ...)is skipped when dry-run mode is enabled. Dry-run then accepts an input/output shape that normal execution rejects. This can produce a memory estimate for a call that cannot run.Move the dry-run guard after the size check, while still skipping
detail::setSmallValuesZero.Proposed fix
- if (resource::get_dry_run_flag(handle)) { return; } RAFT_EXPECTS(in.size() == out.size(), "Input and output matrices must have same size"); + if (resource::get_dry_run_flag(handle)) { return; }As per coding guidelines, validate invalid dimensions where they can cause incorrect behavior. As per path instructions, dry-run guards should suppress CUDA work without bypassing required precondition checks.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/matrix/threshold.cuh` at line 38, Move the resource::get_dry_run_flag(handle) guard in the threshold operation after the RAFT_EXPECTS input/output size validation, so dimension mismatches are rejected in both modes while dry-run still skips detail::setSmallValuesZero and other CUDA work.Sources: Coding guidelines, Path instructions
cpp/include/raft/mr/dry_run_resource.hpp-181-207 (1)
181-207: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winThe probe ignores the alignment of later allocations.
std::call_oncecreates the probe with the alignment of the first request only. A later request with a larger alignment receives the same pointer, which can be under-aligned for that request. Aligned vector loads and stores on that pointer are then invalid, and the returned pointer breaks the alignment contract of the memory-resource API.The probe is also 256 bytes for every request size. Any code path that is not dry-run guarded and writes to the returned pointer overruns the probe.
Allocate the probe with the maximum alignment RAFT can request, or reallocate the probe when a request needs a stricter alignment.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/mr/dry_run_resource.hpp` around lines 181 - 207, Update allocate_sync and allocate so the shared state_->probe always satisfies the strictest alignment requested by RAFT, rather than preserving the first allocation’s alignment; reallocate or otherwise replace the probe when a later request requires greater alignment. Also size the probe to accommodate the requested bytes, or otherwise ensure returned storage cannot be overrun by an unguarded request, while preserving allocation/deallocation accounting.Source: Coding guidelines
cpp/include/raft/core/host_container_policy.hpp-118-127 (1)
118-127: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winReset
bytesize_when you free the buffer.Line 122 frees
data_and Line 123 setsdata_tonullptr, butbytesize_keeps the old value. If the allocation on Line 125 throws, the container is left withdata_ == nullptrand a non-zerobytesize_. Any lateroperator[]on that object dereferences a null pointer.The destructor is safe because it tests both fields, so this is an invariant defect and not a double free.
🛠️ Proposed fix
if (data_ != nullptr) { mr_.deallocate_sync(data_, bytesize_); data_ = nullptr; + bytesize_ = 0; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/core/host_container_policy.hpp` around lines 118 - 127, Update host_container::reallocate so bytesize_ is reset to zero immediately after deallocating data_ and clearing data_. Preserve the existing allocation and swap flow, ensuring an allocation failure cannot leave a null data_ pointer paired with a stale nonzero size.Source: Coding guidelines
cpp/include/raft/random/detail/rng_impl.cuh-16-23 (1)
16-23: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAdd the
dry_run_flag.hppinclude.Line 396 calls
resource::get_dry_run_flag(res)and Line 397 callsresource::get_cuda_stream(res), but this header does not include<raft/core/resource/dry_run_flag.hpp>or<raft/core/resource/cuda_stream.hpp>. The build then depends on transitive includes and can break when an upstream header changes.🛠️ Proposed fix
`#include` <raft/core/detail/macros.hpp> `#include` <raft/core/device_mdarray.hpp> `#include` <raft/core/math.hpp> `#include` <raft/core/operators.cuh> +#include <raft/core/resource/cuda_stream.hpp> +#include <raft/core/resource/dry_run_flag.hpp> `#include` <raft/linalg/map.cuh>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/random/detail/rng_impl.cuh` around lines 16 - 23, Add direct includes for the declarations used by the RNG implementation: include the dry-run flag and CUDA stream resource headers before the code calling resource::get_dry_run_flag and resource::get_cuda_stream. Keep the existing scatter and CUB includes unchanged.cpp/include/raft/spectral/detail/matrix_wrappers.hpp-393-396 (1)
393-396: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win
auto handle = get_handle()copies theraft::resourcesobject in bothmvoverrides.sparse_matrix_t::get_handle()returnsresources const&(Line 323), soautodeducesraft::resourcesby value and each call constructs and destroys a full handle copy. Both overrides run once per solver iteration, so the copy is repeated on a hot path.
cpp/include/raft/spectral/detail/matrix_wrappers.hpp#L393-L396: changeauto handletoauto const& handleinlaplacian_matrix_t::mv.cpp/include/raft/spectral/detail/matrix_wrappers.hpp#L459-L462: changeauto handletoauto const& handleinmodularity_matrix_t::mv.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/spectral/detail/matrix_wrappers.hpp` around lines 393 - 396, Update the handle declarations in both laplacian_matrix_t::mv (cpp/include/raft/spectral/detail/matrix_wrappers.hpp:393-396) and modularity_matrix_t::mv (cpp/include/raft/spectral/detail/matrix_wrappers.hpp:459-462) to bind the resources returned by sparse_matrix_t::get_handle() as a const reference instead of copying them; leave the cublas, stream, and dry-run retrieval unchanged.
🟡 Minor comments (1)
docs/source/developer_guide.md-325-329 (1)
325-329: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winLine 329 renders as part of the last nested bullet.
All attempted allocations in the above resources are tracked...immediately follows a nested list item with no blank line. CommonMark and MyST treat that as a lazy continuation of the list item, so the sentence renders inside the bullet instead of as a standalone paragraph. Insert a blank line.📝 Proposed fix
- workspace memory resources managed by `raft::resources`. + All attempted allocations in the above resources are tracked and reported, thus enabling planning of the memory usage with a relatively small overhead of simulated execution.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/source/developer_guide.md` around lines 325 - 329, Insert a blank line after the final nested bullet under the listed memory resources and before “All attempted allocations...” so that sentence renders as a standalone paragraph rather than as continuation text within the bullet.
🧹 Nitpick comments (3)
cpp/tests/sparse/preprocess.cu (1)
166-180: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAlign the TF-IDF dry-run expectation with the BM25 expectation.
encode_tfidfandencode_bm25follow the same allocation pattern in this test, but the BM25 branches usealloc_behavior::DATA_DRIVENwithsizeof(float) * coo_a.nnz, while the TF-IDF branches usealloc_behavior::ARGUMENT_DRIVENwith1. An expected allocation of1byte makes the check almost unconditional, so a regression in TF-IDF allocation estimation would not fail the test.If
encode_tfidfreally allocates independently ofnnz, add a short comment that states why. Otherwise use the same data-driven bound as the BM25 branches.🧪 Proposed alignment with the BM25 branches
if (coo_on) { raft::execute_with_dry_run_check( handle, [&](raft::resources const& h) { raft::sparse::matrix::encode_tfidf<float, int>(h, coo_a_matrix, result.view()); }, - raft::alloc_behavior::ARGUMENT_DRIVEN, - 1); + raft::alloc_behavior::DATA_DRIVEN, + sizeof(float) * coo_a.nnz); } else { raft::execute_with_dry_run_check( handle, [&](raft::resources const& h) { raft::sparse::matrix::encode_tfidf<float, int>(h, csr_matrix, result.view()); }, - raft::alloc_behavior::ARGUMENT_DRIVEN, - 1); + raft::alloc_behavior::DATA_DRIVEN, + sizeof(float) * coo_a.nnz); }#!/bin/bash # Inspect the encode_tfidf / encode_bm25 implementations to compare their allocation patterns. set -euo pipefail fd -t f 'preprocessing.cuh' cpp/include | while IFS= read -r f; do echo "=== $f ===" rg -n -C 12 'encode_tfidf|encode_bm25|get_dry_run_flag|device_uvector|make_device_' "$f" done🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/tests/sparse/preprocess.cu` around lines 166 - 180, Align both encode_tfidf dry-run checks in the preprocessing test with the BM25 branches by using DATA_DRIVEN allocation behavior and a bound based on sizeof(float) multiplied by coo_a.nnz. If encode_tfidf intentionally allocates independently of nnz, retain the current expectation and add a concise comment explaining that behavior.cpp/tests/util/dry_run_resources.cpp (1)
364-387: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for
dry_run_resourcesnested insidedry_run_resources.
dry_run_resourcescomputesactive_(!resource::get_dry_run_flag(existing))and returns an emptymemory_statsfromget_bytes_peak()when inactive. This test covers dry-run nested in stats, but no test covers dry-run nested in dry-run. That inactive path controls whether the inner object skipsinit()and whether the destructor restores globals, so a regression there would silently produce zero statistics.💚 Proposed additional test
TEST(DryRunResources, NestedDryRunIsInactive) { raft::resources res; dry_run_resources outer(res); { dry_run_resources inner(outer); EXPECT_TRUE(resource::get_dry_run_flag(inner)); // Inner is inactive: it reports no statistics of its own. EXPECT_EQ(inner.get_bytes_peak().total(), 0UL); } // The outer handle must still be in dry-run mode after the inner one is destroyed. EXPECT_TRUE(resource::get_dry_run_flag(outer)); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/tests/util/dry_run_resources.cpp` around lines 364 - 387, Add a test alongside NestedDryRunInStats that constructs an outer dry_run_resources and an inner dry_run_resources using the outer resource. Verify the inner remains marked as dry-run, reports zero from get_bytes_peak().total(), and that the outer still reports the dry-run flag after the inner is destroyed.cpp/tests/test_utils.cuh (1)
368-389: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThe diagnostic
printffires for expectedDATA_DRIVENmismatches.In
DATA_DRIVENmodedry >= actualis the expected outcome, not a failure. The condition at Lines 368-371 triggers on any inequality, so every conformingDATA_DRIVENtest prints a full six-category dump. Gate the diagnostic on the assertion actually failing, or restrict it to theARGUMENT_DRIVENandNO_ALLOCATIONSmodes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/tests/test_utils.cuh` around lines 368 - 389, Update the mismatch diagnostic around the dry/actual workspace comparison so it does not print for expected DATA_DRIVEN cases where dry exceeds actual. Gate the printf using the same assertion-failure condition, or limit it to ARGUMENT_DRIVEN and NO_ALLOCATIONS modes, while preserving diagnostics for genuine mismatches.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cpp/include/raft/mr/dry_run_resource.hpp`:
- Around line 90-105: Update probe_container’s three-argument construction and
destructor to track whether allocation used allocate_sync or the asynchronous
allocate API. Use that stored allocation mode to call the corresponding
deallocate_sync or deallocate function, rather than selecting solely via
cuda::mr::resource<MR>, while preserving the existing stream choice for
asynchronous deallocation.
---
Outside diff comments:
In `@cpp/include/raft/linalg/power.cuh`:
- Around line 79-95: Move the dry-run guard below all RAFT_EXPECTS validation in
both power and power_scalar, so contiguity and size checks always execute before
skipping the kernel launch. Preserve the existing validation and dry-run
behavior, and verify that power_scalar’s dereference of scalar.data_handle()
remains safe with make_host_scalar in dry-run mode; adjust only if that pointer
is not readable.
In `@cpp/include/raft/matrix/detail/select_radix.cuh`:
- Around line 1280-1337: Ensure dry-run execution in the radix top-k dispatch
does not invoke CUDA Runtime occupancy APIs. Update calc_chunk_size and
calc_grid_dim, and the radix_topk_one_block/radix_topk paths that call them, to
use a deterministic workspace-sizing path when dry_run is true and only query
CUDA occupancy for real execution; preserve normal dispatch and sizing behavior
otherwise.
---
Major comments:
In `@cpp/include/raft/core/host_container_policy.hpp`:
- Around line 118-127: Update host_container::reallocate so bytesize_ is reset
to zero immediately after deallocating data_ and clearing data_. Preserve the
existing allocation and swap flow, ensuring an allocation failure cannot leave a
null data_ pointer paired with a stale nonzero size.
In `@cpp/include/raft/linalg/detail/lstsq.cuh`:
- Around line 213-216: Make cleanup of gesvdj_params exception-safe in the code
surrounding cusolverDnCreateGesvdjInfo: establish an RAII owner or scope guard
immediately after successful creation that calls cusolverDnDestroyGesvdjInfo
exactly once on every exit path, including dry-run returns, allocation failures,
and checked cuSOLVER errors. Remove the manual dry-run-only destruction in the
lstsqSvdJacobi flow to avoid double cleanup.
In `@cpp/include/raft/matrix/detail/select_k-inl.cuh`:
- Around line 131-132: Update the CUB sort calls in the select-k implementation,
including both SortPairs and SortPairsDescending workspace-size queries and
execution calls, to use RAFT_CUDA_TRY. Ensure each status is checked before the
resource::get_dry_run_flag(handle) early return so failed dry-run workspace
queries propagate the CUDA error.
In `@cpp/include/raft/matrix/threshold.cuh`:
- Line 38: Move the resource::get_dry_run_flag(handle) guard in the threshold
operation after the RAFT_EXPECTS input/output size validation, so dimension
mismatches are rejected in both modes while dry-run still skips
detail::setSmallValuesZero and other CUDA work.
In `@cpp/include/raft/mr/dry_run_resource.hpp`:
- Around line 181-207: Update allocate_sync and allocate so the shared
state_->probe always satisfies the strictest alignment requested by RAFT, rather
than preserving the first allocation’s alignment; reallocate or otherwise
replace the probe when a later request requires greater alignment. Also size the
probe to accommodate the requested bytes, or otherwise ensure returned storage
cannot be overrun by an unguarded request, while preserving
allocation/deallocation accounting.
In `@cpp/include/raft/random/detail/rng_impl.cuh`:
- Around line 16-23: Add direct includes for the declarations used by the RNG
implementation: include the dry-run flag and CUDA stream resource headers before
the code calling resource::get_dry_run_flag and resource::get_cuda_stream. Keep
the existing scatter and CUB includes unchanged.
In `@cpp/include/raft/solver/detail/lap_functions.cuh`:
- Around line 269-271: In cpp/include/raft/solver/detail/lap_functions.cuh at
lines 269-271 and 432-436, compute a checked size_t matrix_size from SP and N
before constructing the device_uvector instances; use that variable for
predicates_v, addresses_v, csr_neighbors_v, and elements_v at the respective
sites, preserving the existing allocation behavior while preventing source-type
overflow.
In `@cpp/include/raft/sparse/convert/detail/bitmap_to_csr.cuh`:
- Around line 309-315: Construct scan_ws with device_memory, matching the
resource used for sub_nnz, so the CUB scan workspace is accounted for by the
configured workspace resource.
In `@cpp/include/raft/sparse/convert/detail/bitset_to_csr.cuh`:
- Around line 123-126: Wrap both cub::DeviceScan::ExclusiveSum calls in
RAFT_CUDA_TRY, including the workspace-size query and the actual scan execution.
Ensure any CUDA failure is propagated before using scan_ws or the generated CSR
row offsets.
In `@cpp/include/raft/sparse/op/detail/reduce.cuh`:
- Around line 137-149: Validate before both CUB scan calls that diff.size() is
no greater than the maximum representable int, and reject the input with the
established validation mechanism when it exceeds that bound. Update the
workspace query and scan in the surrounding reduction flow to use only a
validated item count, preserving full coverage of all nonzeros and preventing
narrowing overflow.
- Around line 136-149: Wrap both cub::DeviceScan::ExclusiveSum calls in
RAFT_CUDA_TRY, including the workspace-size query and the actual scan, so CUDA
failures are propagated before scan_ws allocation or subsequent data use.
In `@cpp/include/raft/sparse/solver/detail/lanczos.cuh`:
- Around line 158-169: Add RAFT_CUDA_TRY(cudaPeekAtLastError()) immediately
after each of the five CUDA launches in lanczos.cuh: kernel_triangular_populate
and kernel_triangular_beta_k in lines 158-169, plus kernel_clamp_down,
kernel_clamp_down_vector, and kernel_normalize in lines 386-415. Keep the checks
directly adjacent to their respective launches.
- Around line 198-227: Use a handle-bound Thrust execution policy for all
operations in this selection block: define thrust_policy via
resource::get_thrust_policy(handle), then pass it to thrust::sequence and both
thrust::sort calls instead of thrust::device. Preserve the existing index
ordering and eigenvalue selection logic.
In `@cpp/include/raft/spectral/detail/matrix_wrappers.hpp`:
- Around line 393-396: Update the handle declarations in both
laplacian_matrix_t::mv
(cpp/include/raft/spectral/detail/matrix_wrappers.hpp:393-396) and
modularity_matrix_t::mv
(cpp/include/raft/spectral/detail/matrix_wrappers.hpp:459-462) to bind the
resources returned by sparse_matrix_t::get_handle() as a const reference instead
of copying them; leave the cublas, stream, and dry-run retrieval unchanged.
In `@cpp/include/raft/stats/detail/contingencyMatrix.cuh`:
- Around line 209-219: Prevent signed overflow in the dry-run calculations
within the contingency-matrix workspace sizing block by validating nSamples
against the supported range and promoting it to size_t before every
multiplication, including the tmpStagingMemorySize and cubWorkspaceUpperBound
expressions. Preserve the existing alignment and workspace estimate behavior for
valid sample counts, and reject or otherwise handle values that cannot be
represented safely.
In `@cpp/include/raft/stats/detail/meanvar.cuh`:
- Around line 212-223: Move the cudaOccupancyMaxActiveBlocksPerMultiprocessor
call and related gs.y adjustment into the existing !dry_run branch around
meanvar_kernel_rowmajor and meanvar_kernel_fill. Ensure dry_run performs no CUDA
runtime queries or kernel work while retaining the existing buffer allocation
and tracking behavior.
In `@cpp/include/raft/stats/detail/scores.cuh`:
- Line 183: Move the dry_run return in the surrounding score computation before
constructing the host vectors mean_errors and h_sorted_abs_diffs, while keeping
the existing RMM/RAFT allocation attempts before that return. Ensure dry-run
mode performs no host-vector allocations and exits immediately after those
allocation attempts.
In `@cpp/include/raft/stats/detail/silhouette_score.cuh`:
- Around line 229-230: Update the operations in the silhouette-score function,
including pairwise_distance and the dependent matrix_vector_op/reduction calls,
to use the same RAFT-managed stream obtained via
resource::get_cuda_stream(handle). Preserve asynchronous ordering and ensure
every producer and consumer of distanceMatrix and
averageDistanceBetweenSampleAndCluster is submitted to that stream.
In `@cpp/tests/core/bitset.cu`:
- Around line 388-399: Gate the initial my_bitset.any(h) and my_bitset.none(h)
assertions after reset on resource::get_dry_run_flag(h), matching the existing
guarded value-dependent assertions below. Keep the reset and subsequent setup
unchanged, and preserve the assertions during non-dry-run execution.
In `@cpp/tests/sparse/reduce.cu`:
- Around line 65-82: Move construction of the COO variable out of the
surrounding scope and into the dry-run callback containing max_duplicates,
keeping its entire lifetime within execute_with_dry_run_check. Remove or update
the inaccurate comments claiming the COO output is not tracked, and ensure the
callback’s output remains available to the subsequent test logic as required.
---
Minor comments:
In `@docs/source/developer_guide.md`:
- Around line 325-329: Insert a blank line after the final nested bullet under
the listed memory resources and before “All attempted allocations...” so that
sentence renders as a standalone paragraph rather than as continuation text
within the bullet.
---
Nitpick comments:
In `@cpp/tests/sparse/preprocess.cu`:
- Around line 166-180: Align both encode_tfidf dry-run checks in the
preprocessing test with the BM25 branches by using DATA_DRIVEN allocation
behavior and a bound based on sizeof(float) multiplied by coo_a.nnz. If
encode_tfidf intentionally allocates independently of nnz, retain the current
expectation and add a concise comment explaining that behavior.
In `@cpp/tests/test_utils.cuh`:
- Around line 368-389: Update the mismatch diagnostic around the dry/actual
workspace comparison so it does not print for expected DATA_DRIVEN cases where
dry exceeds actual. Gate the printf using the same assertion-failure condition,
or limit it to ARGUMENT_DRIVEN and NO_ALLOCATIONS modes, while preserving
diagnostics for genuine mismatches.
In `@cpp/tests/util/dry_run_resources.cpp`:
- Around line 364-387: Add a test alongside NestedDryRunInStats that constructs
an outer dry_run_resources and an inner dry_run_resources using the outer
resource. Verify the inner remains marked as dry-run, reports zero from
get_bytes_peak().total(), and that the outer still reports the dry-run flag
after the inner is destroyed.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
…t concurrently changing rmm'current device'
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cpp/REVIEW_GUIDELINES.md`:
- Around line 52-54: Revise the dry-run early-return guidance to remove the
broad “or when no other compliant structure works” exception. Permit an early
return only with documented proof that the skipped path and all callees cannot
allocate, backed by a dry-run test; otherwise require unconditional delegation
through public wrappers and guard only meaningful CUDA work, consistent with
docs/source/dry_run_protocol.md and the critical wrapper example.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: c3955160-feeb-42cd-b405-d71bcff7eb40
📒 Files selected for processing (3)
.coderabbit.yamlcpp/REVIEW_GUIDELINES.mdcpp/include/raft/core/dry_run_resources.hpp
🚧 Files skipped from review as they are similar to previous changes (1)
- cpp/include/raft/core/dry_run_resources.hpp
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cpp/include/raft/sparse/linalg/detail/sddmm.hpp`:
- Around line 70-71: Move the resource::get_dry_run_flag(handle) check in the
surrounding SDDMM function to immediately after the workspace query and tmp
allocation, before resource::sync_stream(handle). Preserve those dry-run setup
operations, while ensuring synchronization and subsequent cuSPARSE execution
occur only on the non-dry-run path.
In `@cpp/REVIEW_GUIDELINES.md`:
- Line 216: Update both opening fenced code blocks in cpp/REVIEW_GUIDELINES.md
at lines 216-216 and 228-228 to include the text language identifier, changing
each fence to ```text.
In `@cpp/tests/sparse/solver/randomized_svds.cu`:
- Around line 527-571: Add a dry-run guard in both apply and apply_transpose
after the base operation and local allocations, using
resource::get_dry_run_flag(handle) to return before map, gemv, and gemm
operations. Keep the base_op_ call and allocations before the guard so
allocation requirements remain visible, while preventing CUDA work from
accessing dry-run buffers.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 43afc17c-4abd-45c0-a29f-51b135a6aab1
📒 Files selected for processing (231)
.coderabbit.yamlcpp/REVIEW_GUIDELINES.mdcpp/include/raft/core/bitset.cuhcpp/include/raft/core/bitset.hppcpp/include/raft/core/coo_matrix.hppcpp/include/raft/core/copy.cuhcpp/include/raft/core/copy.hppcpp/include/raft/core/csr_matrix.hppcpp/include/raft/core/detail/copy.hppcpp/include/raft/core/device_container_policy.hppcpp/include/raft/core/device_mdarray.hppcpp/include/raft/core/dry_run_resources.hppcpp/include/raft/core/host_container_policy.hppcpp/include/raft/core/host_mdarray.hppcpp/include/raft/core/managed_mdarray.hppcpp/include/raft/core/pinned_mdarray.hppcpp/include/raft/core/resource/cuda_stream.hppcpp/include/raft/core/resource/dry_run_flag.hppcpp/include/raft/core/resource/resource_types.hppcpp/include/raft/core/sparse_types.hppcpp/include/raft/label/classlabels.cuhcpp/include/raft/label/detail/classlabels.cuhcpp/include/raft/linalg/add.cuhcpp/include/raft/linalg/coalesced_reduction.cuhcpp/include/raft/linalg/detail/axpy.cuhcpp/include/raft/linalg/detail/cholesky_r1_update.cuhcpp/include/raft/linalg/detail/coalesced_reduction-inl.cuhcpp/include/raft/linalg/detail/cublaslt_wrappers.hppcpp/include/raft/linalg/detail/eig.cuhcpp/include/raft/linalg/detail/gemv.hppcpp/include/raft/linalg/detail/lstsq.cuhcpp/include/raft/linalg/detail/map.cuhcpp/include/raft/linalg/detail/matrix_vector_op.cuhcpp/include/raft/linalg/detail/norm.cuhcpp/include/raft/linalg/detail/pca.cuhcpp/include/raft/linalg/detail/qr.cuhcpp/include/raft/linalg/detail/reduce.cuhcpp/include/raft/linalg/detail/rsvd.cuhcpp/include/raft/linalg/detail/svd.cuhcpp/include/raft/linalg/detail/transpose.cuhcpp/include/raft/linalg/divide.cuhcpp/include/raft/linalg/dot.cuhcpp/include/raft/linalg/map_reduce.cuhcpp/include/raft/linalg/matrix_vector_op.cuhcpp/include/raft/linalg/mean_squared_error.cuhcpp/include/raft/linalg/multiply.cuhcpp/include/raft/linalg/norm.cuhcpp/include/raft/linalg/normalize.cuhcpp/include/raft/linalg/power.cuhcpp/include/raft/linalg/reduce.cuhcpp/include/raft/linalg/reduce_cols_by_key.cuhcpp/include/raft/linalg/reduce_rows_by_key.cuhcpp/include/raft/linalg/sqrt.cuhcpp/include/raft/linalg/strided_reduction.cuhcpp/include/raft/linalg/subtract.cuhcpp/include/raft/linalg/unary_op.cuhcpp/include/raft/matrix/argmax.cuhcpp/include/raft/matrix/argmin.cuhcpp/include/raft/matrix/col_wise_sort.cuhcpp/include/raft/matrix/copy.cuhcpp/include/raft/matrix/detail/columnWiseSort.cuhcpp/include/raft/matrix/detail/gather.cuhcpp/include/raft/matrix/detail/gather_inplace.cuhcpp/include/raft/matrix/detail/math.cuhcpp/include/raft/matrix/detail/matrix.cuhcpp/include/raft/matrix/detail/scatter_inplace.cuhcpp/include/raft/matrix/detail/select_k-inl.cuhcpp/include/raft/matrix/detail/select_radix.cuhcpp/include/raft/matrix/detail/select_warpsort.cuhcpp/include/raft/matrix/detail/shift.cuhcpp/include/raft/matrix/diagonal.cuhcpp/include/raft/matrix/gather.cuhcpp/include/raft/matrix/init.cuhcpp/include/raft/matrix/linewise_op.cuhcpp/include/raft/matrix/norm.cuhcpp/include/raft/matrix/power.cuhcpp/include/raft/matrix/print.cuhcpp/include/raft/matrix/reciprocal.cuhcpp/include/raft/matrix/reverse.cuhcpp/include/raft/matrix/sign_flip.cuhcpp/include/raft/matrix/slice.cuhcpp/include/raft/matrix/sqrt.cuhcpp/include/raft/matrix/threshold.cuhcpp/include/raft/matrix/triangular.cuhcpp/include/raft/mr/dry_run_resource.hppcpp/include/raft/random/detail/make_blobs.cuhcpp/include/raft/random/detail/make_regression.cuhcpp/include/raft/random/detail/multi_variable_gaussian.cuhcpp/include/raft/random/detail/rmat_rectangular_generator.cuhcpp/include/raft/random/detail/rng_impl.cuhcpp/include/raft/random/detail/rng_impl_deprecated.cuhcpp/include/raft/random/make_blobs.cuhcpp/include/raft/random/permute.cuhcpp/include/raft/random/rng.cuhcpp/include/raft/random/sample_without_replacement.cuhcpp/include/raft/solver/detail/lap_functions.cuhcpp/include/raft/sparse/convert/detail/adj_to_csr.cuhcpp/include/raft/sparse/convert/detail/bitmap_to_csr.cuhcpp/include/raft/sparse/convert/detail/bitset_to_csr.cuhcpp/include/raft/sparse/convert/detail/csr.cuhcpp/include/raft/sparse/linalg/detail/laplacian.cuhcpp/include/raft/sparse/linalg/detail/sddmm.hppcpp/include/raft/sparse/linalg/detail/spmm.hppcpp/include/raft/sparse/linalg/detail/symmetrize.cuhcpp/include/raft/sparse/linalg/detail/utils.cuhcpp/include/raft/sparse/linalg/spmm.hppcpp/include/raft/sparse/linalg/transpose.cuhcpp/include/raft/sparse/matrix/detail/preprocessing.cuhcpp/include/raft/sparse/matrix/preprocessing.cuhcpp/include/raft/sparse/op/detail/filter.cuhcpp/include/raft/sparse/op/detail/reduce.cuhcpp/include/raft/sparse/op/detail/sort.hcpp/include/raft/sparse/op/sort.cuhcpp/include/raft/sparse/solver/detail/cholesky_qr.cuhcpp/include/raft/sparse/solver/detail/lanczos.cuhcpp/include/raft/sparse/solver/detail/randomized_svds.cuhcpp/include/raft/sparse/solver/detail/svds_sign_correction.cuhcpp/include/raft/spectral/detail/matrix_wrappers.hppcpp/include/raft/spectral/detail/modularity_maximization.hppcpp/include/raft/spectral/detail/partition.hppcpp/include/raft/spectral/detail/spectral_util.cuhcpp/include/raft/stats/accuracy.cuhcpp/include/raft/stats/adjusted_rand_index.cuhcpp/include/raft/stats/completeness_score.cuhcpp/include/raft/stats/contingency_matrix.cuhcpp/include/raft/stats/detail/adjusted_rand_index.cuhcpp/include/raft/stats/detail/batched/silhouette_score.cuhcpp/include/raft/stats/detail/contingencyMatrix.cuhcpp/include/raft/stats/detail/cov.cuhcpp/include/raft/stats/detail/dispersion.cuhcpp/include/raft/stats/detail/entropy.cuhcpp/include/raft/stats/detail/homogeneity_score.cuhcpp/include/raft/stats/detail/kl_divergence.cuhcpp/include/raft/stats/detail/mean.cuhcpp/include/raft/stats/detail/mean_center.cuhcpp/include/raft/stats/detail/meanvar.cuhcpp/include/raft/stats/detail/mutual_info_score.cuhcpp/include/raft/stats/detail/neighborhood_recall.cuhcpp/include/raft/stats/detail/rand_index.cuhcpp/include/raft/stats/detail/scores.cuhcpp/include/raft/stats/detail/silhouette_score.cuhcpp/include/raft/stats/detail/stddev.cuhcpp/include/raft/stats/detail/sum.cuhcpp/include/raft/stats/detail/trustworthiness_score.cuhcpp/include/raft/stats/detail/v_measure.cuhcpp/include/raft/stats/detail/weighted_mean.cuhcpp/include/raft/stats/dispersion.cuhcpp/include/raft/stats/entropy.cuhcpp/include/raft/stats/histogram.cuhcpp/include/raft/stats/homogeneity_score.cuhcpp/include/raft/stats/information_criterion.cuhcpp/include/raft/stats/kl_divergence.cuhcpp/include/raft/stats/mean.cuhcpp/include/raft/stats/mean_center.cuhcpp/include/raft/stats/meanvar.cuhcpp/include/raft/stats/minmax.cuhcpp/include/raft/stats/mutual_info_score.cuhcpp/include/raft/stats/neighborhood_recall.cuhcpp/include/raft/stats/r2_score.cuhcpp/include/raft/stats/rand_index.cuhcpp/include/raft/stats/regression_metrics.cuhcpp/include/raft/stats/stddev.cuhcpp/include/raft/stats/sum.cuhcpp/include/raft/stats/v_measure.cuhcpp/include/raft/stats/weighted_mean.cuhcpp/tests/CMakeLists.txtcpp/tests/core/bitmap.cucpp/tests/core/bitset.cucpp/tests/core/mdarray.cucpp/tests/core/mdbuffer.cucpp/tests/core/mdspan_copy.cucpp/tests/core/mdspan_utils.cucpp/tests/core/sparse_matrix.cucpp/tests/core/temporary_device_buffer.cucpp/tests/linalg/add.cucpp/tests/linalg/axpy.cucpp/tests/linalg/binary_op.cucpp/tests/linalg/coalesced_reduction.cucpp/tests/linalg/divide.cucpp/tests/linalg/dot.cucpp/tests/linalg/eig.cucpp/tests/linalg/gemm_basic.cppcpp/tests/linalg/gemm_layout.cucpp/tests/linalg/map.cucpp/tests/linalg/matrix_vector_op.cucpp/tests/linalg/mean_squared_error.cucpp/tests/linalg/multiply.cucpp/tests/linalg/norm.cucpp/tests/linalg/normalize.cucpp/tests/linalg/pca.cucpp/tests/linalg/power.cucpp/tests/linalg/reduce.cucpp/tests/linalg/rsvd.cucpp/tests/linalg/strided_reduction.cucpp/tests/linalg/subtract.cucpp/tests/linalg/svd.cucpp/tests/linalg/ternary_op.cucpp/tests/linalg/transpose.cucpp/tests/linalg/unary_op.cucpp/tests/matrix/gather.cucpp/tests/matrix/sample_rows.cucpp/tests/sparse/convert_csr.cucpp/tests/sparse/csr_transpose.cucpp/tests/sparse/diagonal.cucpp/tests/sparse/filter.cucpp/tests/sparse/masked_matmul.cucpp/tests/sparse/norm.cucpp/tests/sparse/preprocess.cucpp/tests/sparse/reduce.cucpp/tests/sparse/sddmm.cucpp/tests/sparse/select_k_csr.cucpp/tests/sparse/solver/lanczos.cucpp/tests/sparse/solver/randomized_svds.cucpp/tests/sparse/spmm.cucpp/tests/sparse/symmetrize.cucpp/tests/stats/cov.cucpp/tests/stats/homogeneity_score.cucpp/tests/stats/mean.cucpp/tests/stats/meanvar.cucpp/tests/stats/minmax.cucpp/tests/stats/stddev.cucpp/tests/stats/sum.cucpp/tests/stats/weighted_mean.cucpp/tests/test_utils.cuhcpp/tests/util/dry_run_guards.cucpp/tests/util/dry_run_resources.cppcpp/tests/util/memory_type_dispatcher.cucpp/tests/util/popc.cudocs/source/cpp_api/core_resources.rstdocs/source/developer_guide.mddocs/source/dry_run_protocol.md
💤 Files with no reviewable changes (1)
- cpp/include/raft/stats/detail/sum.cuh
🚧 Files skipped from review as they are similar to previous changes (226)
- cpp/tests/CMakeLists.txt
- cpp/include/raft/matrix/detail/select_k-inl.cuh
- cpp/include/raft/core/coo_matrix.hpp
- cpp/include/raft/linalg/map_reduce.cuh
- cpp/include/raft/matrix/reverse.cuh
- cpp/include/raft/sparse/convert/detail/adj_to_csr.cuh
- cpp/include/raft/matrix/threshold.cuh
- cpp/include/raft/linalg/divide.cuh
- cpp/include/raft/linalg/reduce_rows_by_key.cuh
- cpp/include/raft/linalg/detail/map.cuh
- cpp/include/raft/linalg/detail/axpy.cuh
- cpp/include/raft/linalg/reduce_cols_by_key.cuh
- cpp/include/raft/matrix/print.cuh
- cpp/include/raft/sparse/linalg/detail/symmetrize.cuh
- cpp/include/raft/matrix/argmax.cuh
- cpp/include/raft/linalg/unary_op.cuh
- cpp/include/raft/stats/detail/homogeneity_score.cuh
- cpp/include/raft/linalg/normalize.cuh
- cpp/include/raft/stats/detail/cov.cuh
- cpp/include/raft/linalg/detail/cublaslt_wrappers.hpp
- cpp/include/raft/stats/detail/rand_index.cuh
- cpp/include/raft/matrix/reciprocal.cuh
- cpp/include/raft/matrix/slice.cuh
- cpp/include/raft/linalg/detail/eig.cuh
- cpp/include/raft/linalg/dot.cuh
- cpp/include/raft/label/classlabels.cuh
- cpp/tests/linalg/add.cu
- cpp/include/raft/matrix/triangular.cuh
- cpp/include/raft/linalg/norm.cuh
- cpp/include/raft/sparse/matrix/preprocessing.cuh
- cpp/include/raft/stats/adjusted_rand_index.cuh
- cpp/include/raft/stats/sum.cuh
- cpp/include/raft/linalg/detail/coalesced_reduction-inl.cuh
- cpp/include/raft/stats/v_measure.cuh
- cpp/include/raft/sparse/convert/detail/csr.cuh
- cpp/tests/stats/minmax.cu
- cpp/include/raft/sparse/op/detail/filter.cuh
- cpp/include/raft/core/copy.cuh
- docs/source/cpp_api/core_resources.rst
- cpp/tests/stats/meanvar.cu
- cpp/tests/core/bitmap.cu
- cpp/include/raft/sparse/solver/detail/svds_sign_correction.cuh
- cpp/include/raft/core/detail/copy.hpp
- cpp/include/raft/random/permute.cuh
- cpp/include/raft/linalg/strided_reduction.cuh
- cpp/include/raft/core/resource/cuda_stream.hpp
- cpp/include/raft/stats/detail/kl_divergence.cuh
- cpp/tests/linalg/mean_squared_error.cu
- cpp/include/raft/matrix/linewise_op.cuh
- cpp/include/raft/core/bitset.cuh
- cpp/include/raft/matrix/argmin.cuh
- cpp/include/raft/linalg/detail/svd.cuh
- cpp/include/raft/core/host_mdarray.hpp
- cpp/include/raft/linalg/detail/cholesky_r1_update.cuh
- cpp/include/raft/linalg/mean_squared_error.cuh
- cpp/include/raft/linalg/multiply.cuh
- cpp/tests/linalg/gemm_basic.cpp
- cpp/include/raft/matrix/init.cuh
- cpp/include/raft/core/sparse_types.hpp
- cpp/include/raft/matrix/detail/matrix.cuh
- cpp/include/raft/matrix/power.cuh
- cpp/include/raft/core/device_mdarray.hpp
- cpp/include/raft/sparse/convert/detail/bitmap_to_csr.cuh
- cpp/tests/core/mdbuffer.cu
- cpp/tests/core/mdspan_copy.cu
- cpp/include/raft/sparse/solver/detail/randomized_svds.cuh
- cpp/tests/linalg/strided_reduction.cu
- cpp/tests/linalg/multiply.cu
- cpp/include/raft/matrix/detail/math.cuh
- cpp/include/raft/stats/mutual_info_score.cuh
- cpp/include/raft/random/detail/make_regression.cuh
- cpp/include/raft/sparse/linalg/detail/utils.cuh
- cpp/include/raft/stats/detail/batched/silhouette_score.cuh
- cpp/include/raft/core/resource/resource_types.hpp
- cpp/include/raft/stats/accuracy.cuh
- cpp/include/raft/random/sample_without_replacement.cuh
- cpp/include/raft/matrix/detail/scatter_inplace.cuh
- cpp/include/raft/stats/detail/neighborhood_recall.cuh
- cpp/tests/sparse/masked_matmul.cu
- cpp/include/raft/stats/detail/weighted_mean.cuh
- cpp/include/raft/spectral/detail/modularity_maximization.hpp
- cpp/include/raft/stats/detail/dispersion.cuh
- cpp/include/raft/stats/minmax.cuh
- cpp/tests/core/sparse_matrix.cu
- cpp/include/raft/linalg/detail/rsvd.cuh
- cpp/tests/sparse/csr_transpose.cu
- cpp/include/raft/linalg/subtract.cuh
- cpp/tests/sparse/select_k_csr.cu
- cpp/include/raft/stats/meanvar.cuh
- cpp/include/raft/core/managed_mdarray.hpp
- cpp/include/raft/stats/detail/mean.cuh
- cpp/include/raft/sparse/linalg/detail/laplacian.cuh
- cpp/include/raft/linalg/add.cuh
- cpp/include/raft/core/resource/dry_run_flag.hpp
- cpp/include/raft/random/detail/rng_impl_deprecated.cuh
- cpp/include/raft/linalg/sqrt.cuh
- cpp/include/raft/stats/stddev.cuh
- cpp/include/raft/linalg/detail/reduce.cuh
- cpp/include/raft/sparse/linalg/transpose.cuh
- cpp/tests/linalg/power.cu
- cpp/include/raft/linalg/detail/transpose.cuh
- cpp/include/raft/stats/detail/contingencyMatrix.cuh
- cpp/tests/core/mdarray.cu
- cpp/include/raft/random/detail/rng_impl.cuh
- cpp/include/raft/random/detail/rmat_rectangular_generator.cuh
- cpp/tests/linalg/norm.cu
- cpp/tests/linalg/transpose.cu
- cpp/include/raft/matrix/detail/shift.cuh
- cpp/include/raft/stats/information_criterion.cuh
- cpp/include/raft/stats/histogram.cuh
- cpp/include/raft/sparse/op/detail/reduce.cuh
- cpp/include/raft/stats/weighted_mean.cuh
- cpp/include/raft/matrix/detail/gather_inplace.cuh
- cpp/include/raft/core/copy.hpp
- cpp/tests/linalg/binary_op.cu
- cpp/tests/linalg/gemm_layout.cu
- cpp/tests/sparse/sddmm.cu
- cpp/tests/sparse/norm.cu
- cpp/tests/util/popc.cu
- cpp/include/raft/stats/rand_index.cuh
- cpp/include/raft/matrix/norm.cuh
- cpp/tests/linalg/matrix_vector_op.cu
- cpp/include/raft/linalg/power.cuh
- cpp/tests/core/temporary_device_buffer.cu
- cpp/tests/linalg/divide.cu
- cpp/include/raft/label/detail/classlabels.cuh
- cpp/include/raft/linalg/detail/qr.cuh
- cpp/tests/linalg/dot.cu
- cpp/include/raft/matrix/gather.cuh
- cpp/tests/linalg/map.cu
- cpp/include/raft/matrix/detail/gather.cuh
- cpp/include/raft/stats/neighborhood_recall.cuh
- cpp/tests/linalg/ternary_op.cu
- cpp/include/raft/linalg/reduce.cuh
- cpp/include/raft/random/detail/multi_variable_gaussian.cuh
- cpp/tests/stats/sum.cu
- .coderabbit.yaml
- cpp/include/raft/stats/r2_score.cuh
- cpp/include/raft/linalg/coalesced_reduction.cuh
- cpp/include/raft/stats/regression_metrics.cuh
- cpp/include/raft/sparse/matrix/detail/preprocessing.cuh
- cpp/tests/sparse/diagonal.cu
- cpp/tests/stats/homogeneity_score.cu
- cpp/include/raft/matrix/diagonal.cuh
- cpp/include/raft/sparse/linalg/spmm.hpp
- cpp/include/raft/matrix/detail/columnWiseSort.cuh
- cpp/tests/matrix/sample_rows.cu
- cpp/tests/linalg/svd.cu
- cpp/include/raft/stats/homogeneity_score.cuh
- cpp/tests/linalg/unary_op.cu
- cpp/include/raft/matrix/sign_flip.cuh
- cpp/include/raft/linalg/detail/matrix_vector_op.cuh
- docs/source/developer_guide.md
- cpp/tests/util/dry_run_guards.cu
- cpp/include/raft/stats/completeness_score.cuh
- cpp/include/raft/sparse/op/detail/sort.h
- cpp/include/raft/linalg/detail/pca.cuh
- cpp/include/raft/stats/detail/adjusted_rand_index.cuh
- cpp/include/raft/core/dry_run_resources.hpp
- cpp/include/raft/sparse/op/sort.cuh
- cpp/include/raft/stats/detail/trustworthiness_score.cuh
- cpp/include/raft/spectral/detail/partition.hpp
- cpp/include/raft/stats/mean_center.cuh
- cpp/tests/linalg/pca.cu
- cpp/tests/util/memory_type_dispatcher.cu
- cpp/include/raft/random/detail/make_blobs.cuh
- cpp/include/raft/sparse/linalg/detail/spmm.hpp
- cpp/tests/linalg/coalesced_reduction.cu
- docs/source/dry_run_protocol.md
- cpp/include/raft/linalg/detail/gemv.hpp
- cpp/tests/linalg/axpy.cu
- cpp/include/raft/matrix/detail/select_warpsort.cuh
- cpp/tests/sparse/spmm.cu
- cpp/tests/linalg/subtract.cu
- cpp/tests/sparse/preprocess.cu
- cpp/include/raft/solver/detail/lap_functions.cuh
- cpp/tests/linalg/normalize.cu
- cpp/tests/stats/cov.cu
- cpp/include/raft/core/pinned_mdarray.hpp
- cpp/tests/sparse/symmetrize.cu
- cpp/include/raft/matrix/sqrt.cuh
- cpp/tests/linalg/reduce.cu
- cpp/include/raft/stats/detail/mean_center.cuh
- cpp/include/raft/matrix/copy.cuh
- cpp/include/raft/random/rng.cuh
- cpp/include/raft/sparse/solver/detail/lanczos.cuh
- cpp/include/raft/linalg/detail/lstsq.cuh
- cpp/include/raft/stats/contingency_matrix.cuh
- cpp/include/raft/linalg/matrix_vector_op.cuh
- cpp/include/raft/spectral/detail/spectral_util.cuh
- cpp/tests/sparse/solver/lanczos.cu
- cpp/include/raft/sparse/convert/detail/bitset_to_csr.cuh
- cpp/include/raft/stats/detail/entropy.cuh
- cpp/include/raft/stats/detail/meanvar.cuh
- cpp/tests/sparse/filter.cu
- cpp/tests/sparse/reduce.cu
- cpp/include/raft/stats/detail/silhouette_score.cuh
- cpp/include/raft/stats/detail/scores.cuh
- cpp/tests/linalg/eig.cu
- cpp/tests/stats/weighted_mean.cu
- cpp/include/raft/stats/detail/v_measure.cuh
- cpp/include/raft/stats/detail/mutual_info_score.cuh
- cpp/tests/test_utils.cuh
- cpp/include/raft/sparse/solver/detail/cholesky_qr.cuh
- cpp/include/raft/stats/kl_divergence.cuh
- cpp/include/raft/matrix/detail/select_radix.cuh
- cpp/include/raft/mr/dry_run_resource.hpp
- cpp/include/raft/linalg/detail/norm.cuh
- cpp/tests/sparse/convert_csr.cu
- cpp/include/raft/core/host_container_policy.hpp
- cpp/include/raft/matrix/col_wise_sort.cuh
- cpp/include/raft/random/make_blobs.cuh
- cpp/tests/matrix/gather.cu
- cpp/tests/linalg/rsvd.cu
- cpp/include/raft/stats/mean.cuh
- cpp/include/raft/stats/entropy.cuh
- cpp/include/raft/core/bitset.hpp
- cpp/include/raft/stats/dispersion.cuh
- cpp/include/raft/core/device_container_policy.hpp
- cpp/tests/stats/stddev.cu
- cpp/tests/stats/mean.cu
- cpp/tests/core/bitset.cu
- cpp/include/raft/stats/detail/stddev.cuh
- cpp/tests/core/mdspan_utils.cu
- cpp/include/raft/spectral/detail/matrix_wrappers.hpp
- cpp/include/raft/core/csr_matrix.hpp
| auto bk = static_cast<uint32_t>(X.extent(1)); | ||
| base_op_.apply(handle, X, Y); | ||
| rmm::device_uvector<ValueType> corr(bk, stream); | ||
| rmm::device_uvector<ValueType> ones(m_, stream); | ||
| std::vector<ValueType> h(m_, 1); | ||
| raft::update_device(ones.data(), h.data(), m_, stream); | ||
| ValueType a1 = 1, a0 = 0, am1 = -1; | ||
| RAFT_CUBLAS_TRY(raft::linalg::detail::cublasgemv(cublas, | ||
| CUBLAS_OP_T, | ||
| n_, | ||
| bk, | ||
| &a1, | ||
| X.data_handle(), | ||
| n_, | ||
| col_means_, | ||
| 1, | ||
| &a0, | ||
| corr.data(), | ||
| 1, | ||
| stream)); | ||
| RAFT_CUBLAS_TRY(raft::linalg::detail::cublasgemm(cublas, | ||
| CUBLAS_OP_N, | ||
| CUBLAS_OP_N, | ||
| m_, | ||
| bk, | ||
| 1, | ||
| &am1, | ||
| ones.data(), | ||
| m_, | ||
| corr.data(), | ||
| 1, | ||
| &a1, | ||
| Y.data_handle(), | ||
| m_, | ||
| stream)); | ||
| auto corr = raft::make_device_vector<ValueType, uint32_t>(handle, bk); | ||
| auto ones = raft::make_device_vector<ValueType, uint32_t>(handle, m_); | ||
| raft::linalg::map(handle, ones.view(), raft::const_op{ValueType{1}}); | ||
|
|
||
| ValueType neg_one = -1, one = 1; | ||
| // Same col-major buffer as X; row_major tag selects gemv transpose (mean^T @ X). | ||
| auto X_t = raft::make_device_matrix_view<const ValueType, uint32_t, raft::row_major>( | ||
| X.data_handle(), X.extent(0), X.extent(1)); | ||
| raft::linalg::gemv(handle, | ||
| X_t, | ||
| raft::make_device_vector_view<const ValueType, uint32_t>(col_means_, n_), | ||
| corr.view()); | ||
| raft::linalg::gemm(handle, | ||
| raft::reshape(ones.view(), raft::make_extents<uint32_t>(m_, 1)), | ||
| raft::reshape(corr.view(), raft::make_extents<uint32_t>(1, bk)), | ||
| Y, | ||
| std::make_optional(raft::make_host_scalar_view(&neg_one)), | ||
| std::make_optional(raft::make_host_scalar_view(&one))); | ||
| } | ||
|
|
||
| // Z = (A - 1*mean^T)^T @ X = A^T@X - mean * (1^T @ X) | ||
| void apply_transpose(raft::resources const& handle, | ||
| raft::device_matrix_view<const ValueType, uint32_t, raft::col_major> X, | ||
| raft::device_matrix_view<ValueType, uint32_t, raft::col_major> Z) const | ||
| { | ||
| auto stream = raft::resource::get_cuda_stream(handle); | ||
| auto cublas = raft::resource::get_cublas_handle(handle); | ||
| int bk = X.extent(1); | ||
| auto bk = static_cast<uint32_t>(X.extent(1)); | ||
| base_op_.apply_transpose(handle, X, Z); | ||
| rmm::device_uvector<ValueType> sums(bk, stream); | ||
| rmm::device_uvector<ValueType> ones(m_, stream); | ||
| std::vector<ValueType> h(m_, 1); | ||
| raft::update_device(ones.data(), h.data(), m_, stream); | ||
| ValueType a1 = 1, a0 = 0, am1 = -1; | ||
| RAFT_CUBLAS_TRY(raft::linalg::detail::cublasgemv(cublas, | ||
| CUBLAS_OP_T, | ||
| m_, | ||
| bk, | ||
| &a1, | ||
| X.data_handle(), | ||
| m_, | ||
| ones.data(), | ||
| 1, | ||
| &a0, | ||
| sums.data(), | ||
| 1, | ||
| stream)); | ||
| RAFT_CUBLAS_TRY(raft::linalg::detail::cublasgemm(cublas, | ||
| CUBLAS_OP_N, | ||
| CUBLAS_OP_N, | ||
| n_, | ||
| bk, | ||
| 1, | ||
| &am1, | ||
| col_means_, | ||
| n_, | ||
| sums.data(), | ||
| 1, | ||
| &a1, | ||
| Z.data_handle(), | ||
| n_, | ||
| stream)); | ||
| auto sums = raft::make_device_vector<ValueType, uint32_t>(handle, bk); | ||
| auto ones = raft::make_device_vector<ValueType, uint32_t>(handle, m_); | ||
| raft::linalg::map(handle, ones.view(), raft::const_op{ValueType{1}}); | ||
|
|
||
| ValueType neg_one = -1, one = 1; | ||
| // Same col-major buffer as X; row_major tag selects gemv transpose (ones^T @ X). | ||
| auto X_t = raft::make_device_matrix_view<const ValueType, uint32_t, raft::row_major>( | ||
| X.data_handle(), X.extent(0), X.extent(1)); | ||
| raft::linalg::gemv(handle, X_t, raft::make_const_mdspan(ones.view()), sums.view()); | ||
| raft::linalg::gemm(handle, | ||
| raft::reshape(raft::make_device_vector_view(col_means_, n_), | ||
| raft::make_extents<uint32_t>(n_, 1)), | ||
| raft::reshape(sums.view(), raft::make_extents<uint32_t>(1, bk)), | ||
| Z, | ||
| std::make_optional(raft::make_host_scalar_view(&neg_one)), | ||
| std::make_optional(raft::make_host_scalar_view(&one))); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
Guard the mean-centering CUDA work in dry-run mode.
During execute_with_dry_run_check, corr, sums, and ones use dry-run allocations. Lines 531, 537, 541, 558, 564, and 565 then launch work that reads or writes those probe-backed buffers. This can cause invalid device-memory access.
After base_op_.apply or base_op_.apply_transpose and the local allocations, return when resource::get_dry_run_flag(handle) is true. Keep the base_op_ call and allocations before the check so their allocation requirements remain visible.
Proposed guard placement
base_op_.apply(handle, X, Y);
auto corr = raft::make_device_vector<ValueType, uint32_t>(handle, bk);
auto ones = raft::make_device_vector<ValueType, uint32_t>(handle, m_);
+ if (resource::get_dry_run_flag(handle)) { return; }
raft::linalg::map(handle, ones.view(), raft::const_op{ValueType{1}});Apply the equivalent change in apply_transpose.
As per path instructions, allocations must remain active and meaningful CUDA work must be guarded in dry-run mode.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cpp/tests/sparse/solver/randomized_svds.cu` around lines 527 - 571, Add a
dry-run guard in both apply and apply_transpose after the base operation and
local allocations, using resource::get_dry_run_flag(handle) to return before
map, gemv, and gemm operations. Keep the base_op_ call and allocations before
the guard so allocation requirements remain visible, while preventing CUDA work
from accessing dry-run buffers.
Source: Path instructions
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
cpp/include/raft/core/dry_run_resources.hpp (1)
62-70: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
init()still has no rollback if it throws.The constructor calls
init()directly.init()replaces the global host resource at Line 180 and the global device resource at Line 207 before it completes. If any later step throws, the object is not fully constructed, so~dry_run_resources()never runs. The global host and device resources then point at adaptors that are destroyed during stack unwinding.Wrap
init()in a try/catch that restoresold_host_,old_device_, and the dry-run flag, then rethrows.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/core/dry_run_resources.hpp` around lines 62 - 70, Update the dry_run_resources constructor around init() to provide rollback when initialization throws: catch the exception, restore old_host_ and old_device_, reset the dry-run flag to its prior state, then rethrow. Preserve the existing successful initialization and destructor behavior.Source: Path instructions
🧹 Nitpick comments (3)
cpp/include/raft/sparse/linalg/transpose.cuh (1)
68-70: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winConsider allocating the temporary buffer from the workspace resource.
convert_csc_workspaceis a short-lived scratch buffer. It currently uses the default device memory resource, so the dry-run tracker attributes it todevice_globalinstead ofdevice_workspace. Allocating it fromresource::get_workspace_resource(handle)gives correct categorization and honors the configured workspace limit.rmm::device_uvector<char> convert_csc_workspace( convert_csc_workspace_size, stream, resource::get_workspace_resource(handle));The dry-run ordering itself is correct: the buffer-size query and the allocation run before the guard, and only the numeric conversion is skipped.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/include/raft/sparse/linalg/transpose.cuh` around lines 68 - 70, Update the convert_csc_workspace allocation to use resource::get_workspace_resource(handle) as its memory resource, while preserving the existing allocation-before-dry-run-guard ordering and skipping only the numeric conversion.Source: Path instructions
cpp/tests/util/dry_run_guards.cu (2)
153-174: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
DeallocReducesCurrentdoes not assert the behavior in its name.The test allocates
buf1, frees it, then allocatesbuf2, but the only assertion isEXPECT_GE(stats.device_global, kSize2). That assertion also passes if deallocation is never accounted for. Add an upper bound so the test fails when the counter does not decrease on deallocation.🧪 Proposed assertion
EXPECT_GE(stats.device_global, kSize2); - // But could be less than kSize1 + kSize2 (since buf1 is freed before buf2) - // This depends on timing/implementation, so we just check the peak is reasonable + // buf1 is freed before buf2 is allocated, so the peak must not include both. + EXPECT_LT(stats.device_global, kSize1 + kSize2);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/tests/util/dry_run_guards.cu` around lines 153 - 174, Update the DeallocReducesCurrent test to assert an upper bound on stats.device_global after buf1 is freed before buf2 is allocated, ensuring the recorded peak does not include both allocation sizes. Keep the existing lower-bound check for kSize2 and add a bound that fails when deallocation is not accounted for.
42-73: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider covering these paths with
raft::execute_with_dry_run_check.
AddDoesNotExecuteandRngDoesNotExecutetoggleset_dry_run_flagon a liveresourceshandle. That checks the guard but not the allocation contract, and it leaves the flag set onresif the call under test throws. The test guidelines require principal public paths to be covered withexecute_with_dry_run_checkand the matching allocation behavior.As per coding guidelines: "When adding or materially changing raft::resources algorithms or primitives, cover principal public paths with execute_with_dry_run_check and the appropriate allocation behavior."
Also applies to: 75-100
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cpp/tests/util/dry_run_guards.cu` around lines 42 - 73, Update the dry-run tests around AddDoesNotExecute and RngDoesNotExecute to use raft::execute_with_dry_run_check instead of manually toggling set_dry_run_flag on a live resources handle. Configure the helper to verify the corresponding allocation behavior while preserving assertions that the operation does not modify output or execute RNG work, and ensure cleanup remains exception-safe.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cpp/include/raft/core/host_container_policy.hpp`:
- Around line 118-127: Update host_container::reallocate so bytesize_ is reset
to zero immediately when the existing data_ buffer is deallocated and data_ is
cleared, before constructing host_container{count, mr_}; preserve the existing
allocation and swap behavior.
---
Duplicate comments:
In `@cpp/include/raft/core/dry_run_resources.hpp`:
- Around line 62-70: Update the dry_run_resources constructor around init() to
provide rollback when initialization throws: catch the exception, restore
old_host_ and old_device_, reset the dry-run flag to its prior state, then
rethrow. Preserve the existing successful initialization and destructor
behavior.
---
Nitpick comments:
In `@cpp/include/raft/sparse/linalg/transpose.cuh`:
- Around line 68-70: Update the convert_csc_workspace allocation to use
resource::get_workspace_resource(handle) as its memory resource, while
preserving the existing allocation-before-dry-run-guard ordering and skipping
only the numeric conversion.
In `@cpp/tests/util/dry_run_guards.cu`:
- Around line 153-174: Update the DeallocReducesCurrent test to assert an upper
bound on stats.device_global after buf1 is freed before buf2 is allocated,
ensuring the recorded peak does not include both allocation sizes. Keep the
existing lower-bound check for kSize2 and add a bound that fails when
deallocation is not accounted for.
- Around line 42-73: Update the dry-run tests around AddDoesNotExecute and
RngDoesNotExecute to use raft::execute_with_dry_run_check instead of manually
toggling set_dry_run_flag on a live resources handle. Configure the helper to
verify the corresponding allocation behavior while preserving assertions that
the operation does not modify output or execute RNG work, and ensure cleanup
remains exception-safe.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 43afc17c-4abd-45c0-a29f-51b135a6aab1
📒 Files selected for processing (231)
.coderabbit.yamlcpp/REVIEW_GUIDELINES.mdcpp/include/raft/core/bitset.cuhcpp/include/raft/core/bitset.hppcpp/include/raft/core/coo_matrix.hppcpp/include/raft/core/copy.cuhcpp/include/raft/core/copy.hppcpp/include/raft/core/csr_matrix.hppcpp/include/raft/core/detail/copy.hppcpp/include/raft/core/device_container_policy.hppcpp/include/raft/core/device_mdarray.hppcpp/include/raft/core/dry_run_resources.hppcpp/include/raft/core/host_container_policy.hppcpp/include/raft/core/host_mdarray.hppcpp/include/raft/core/managed_mdarray.hppcpp/include/raft/core/pinned_mdarray.hppcpp/include/raft/core/resource/cuda_stream.hppcpp/include/raft/core/resource/dry_run_flag.hppcpp/include/raft/core/resource/resource_types.hppcpp/include/raft/core/sparse_types.hppcpp/include/raft/label/classlabels.cuhcpp/include/raft/label/detail/classlabels.cuhcpp/include/raft/linalg/add.cuhcpp/include/raft/linalg/coalesced_reduction.cuhcpp/include/raft/linalg/detail/axpy.cuhcpp/include/raft/linalg/detail/cholesky_r1_update.cuhcpp/include/raft/linalg/detail/coalesced_reduction-inl.cuhcpp/include/raft/linalg/detail/cublaslt_wrappers.hppcpp/include/raft/linalg/detail/eig.cuhcpp/include/raft/linalg/detail/gemv.hppcpp/include/raft/linalg/detail/lstsq.cuhcpp/include/raft/linalg/detail/map.cuhcpp/include/raft/linalg/detail/matrix_vector_op.cuhcpp/include/raft/linalg/detail/norm.cuhcpp/include/raft/linalg/detail/pca.cuhcpp/include/raft/linalg/detail/qr.cuhcpp/include/raft/linalg/detail/reduce.cuhcpp/include/raft/linalg/detail/rsvd.cuhcpp/include/raft/linalg/detail/svd.cuhcpp/include/raft/linalg/detail/transpose.cuhcpp/include/raft/linalg/divide.cuhcpp/include/raft/linalg/dot.cuhcpp/include/raft/linalg/map_reduce.cuhcpp/include/raft/linalg/matrix_vector_op.cuhcpp/include/raft/linalg/mean_squared_error.cuhcpp/include/raft/linalg/multiply.cuhcpp/include/raft/linalg/norm.cuhcpp/include/raft/linalg/normalize.cuhcpp/include/raft/linalg/power.cuhcpp/include/raft/linalg/reduce.cuhcpp/include/raft/linalg/reduce_cols_by_key.cuhcpp/include/raft/linalg/reduce_rows_by_key.cuhcpp/include/raft/linalg/sqrt.cuhcpp/include/raft/linalg/strided_reduction.cuhcpp/include/raft/linalg/subtract.cuhcpp/include/raft/linalg/unary_op.cuhcpp/include/raft/matrix/argmax.cuhcpp/include/raft/matrix/argmin.cuhcpp/include/raft/matrix/col_wise_sort.cuhcpp/include/raft/matrix/copy.cuhcpp/include/raft/matrix/detail/columnWiseSort.cuhcpp/include/raft/matrix/detail/gather.cuhcpp/include/raft/matrix/detail/gather_inplace.cuhcpp/include/raft/matrix/detail/math.cuhcpp/include/raft/matrix/detail/matrix.cuhcpp/include/raft/matrix/detail/scatter_inplace.cuhcpp/include/raft/matrix/detail/select_k-inl.cuhcpp/include/raft/matrix/detail/select_radix.cuhcpp/include/raft/matrix/detail/select_warpsort.cuhcpp/include/raft/matrix/detail/shift.cuhcpp/include/raft/matrix/diagonal.cuhcpp/include/raft/matrix/gather.cuhcpp/include/raft/matrix/init.cuhcpp/include/raft/matrix/linewise_op.cuhcpp/include/raft/matrix/norm.cuhcpp/include/raft/matrix/power.cuhcpp/include/raft/matrix/print.cuhcpp/include/raft/matrix/reciprocal.cuhcpp/include/raft/matrix/reverse.cuhcpp/include/raft/matrix/sign_flip.cuhcpp/include/raft/matrix/slice.cuhcpp/include/raft/matrix/sqrt.cuhcpp/include/raft/matrix/threshold.cuhcpp/include/raft/matrix/triangular.cuhcpp/include/raft/mr/dry_run_resource.hppcpp/include/raft/random/detail/make_blobs.cuhcpp/include/raft/random/detail/make_regression.cuhcpp/include/raft/random/detail/multi_variable_gaussian.cuhcpp/include/raft/random/detail/rmat_rectangular_generator.cuhcpp/include/raft/random/detail/rng_impl.cuhcpp/include/raft/random/detail/rng_impl_deprecated.cuhcpp/include/raft/random/make_blobs.cuhcpp/include/raft/random/permute.cuhcpp/include/raft/random/rng.cuhcpp/include/raft/random/sample_without_replacement.cuhcpp/include/raft/solver/detail/lap_functions.cuhcpp/include/raft/sparse/convert/detail/adj_to_csr.cuhcpp/include/raft/sparse/convert/detail/bitmap_to_csr.cuhcpp/include/raft/sparse/convert/detail/bitset_to_csr.cuhcpp/include/raft/sparse/convert/detail/csr.cuhcpp/include/raft/sparse/linalg/detail/laplacian.cuhcpp/include/raft/sparse/linalg/detail/sddmm.hppcpp/include/raft/sparse/linalg/detail/spmm.hppcpp/include/raft/sparse/linalg/detail/symmetrize.cuhcpp/include/raft/sparse/linalg/detail/utils.cuhcpp/include/raft/sparse/linalg/spmm.hppcpp/include/raft/sparse/linalg/transpose.cuhcpp/include/raft/sparse/matrix/detail/preprocessing.cuhcpp/include/raft/sparse/matrix/preprocessing.cuhcpp/include/raft/sparse/op/detail/filter.cuhcpp/include/raft/sparse/op/detail/reduce.cuhcpp/include/raft/sparse/op/detail/sort.hcpp/include/raft/sparse/op/sort.cuhcpp/include/raft/sparse/solver/detail/cholesky_qr.cuhcpp/include/raft/sparse/solver/detail/lanczos.cuhcpp/include/raft/sparse/solver/detail/randomized_svds.cuhcpp/include/raft/sparse/solver/detail/svds_sign_correction.cuhcpp/include/raft/spectral/detail/matrix_wrappers.hppcpp/include/raft/spectral/detail/modularity_maximization.hppcpp/include/raft/spectral/detail/partition.hppcpp/include/raft/spectral/detail/spectral_util.cuhcpp/include/raft/stats/accuracy.cuhcpp/include/raft/stats/adjusted_rand_index.cuhcpp/include/raft/stats/completeness_score.cuhcpp/include/raft/stats/contingency_matrix.cuhcpp/include/raft/stats/detail/adjusted_rand_index.cuhcpp/include/raft/stats/detail/batched/silhouette_score.cuhcpp/include/raft/stats/detail/contingencyMatrix.cuhcpp/include/raft/stats/detail/cov.cuhcpp/include/raft/stats/detail/dispersion.cuhcpp/include/raft/stats/detail/entropy.cuhcpp/include/raft/stats/detail/homogeneity_score.cuhcpp/include/raft/stats/detail/kl_divergence.cuhcpp/include/raft/stats/detail/mean.cuhcpp/include/raft/stats/detail/mean_center.cuhcpp/include/raft/stats/detail/meanvar.cuhcpp/include/raft/stats/detail/mutual_info_score.cuhcpp/include/raft/stats/detail/neighborhood_recall.cuhcpp/include/raft/stats/detail/rand_index.cuhcpp/include/raft/stats/detail/scores.cuhcpp/include/raft/stats/detail/silhouette_score.cuhcpp/include/raft/stats/detail/stddev.cuhcpp/include/raft/stats/detail/sum.cuhcpp/include/raft/stats/detail/trustworthiness_score.cuhcpp/include/raft/stats/detail/v_measure.cuhcpp/include/raft/stats/detail/weighted_mean.cuhcpp/include/raft/stats/dispersion.cuhcpp/include/raft/stats/entropy.cuhcpp/include/raft/stats/histogram.cuhcpp/include/raft/stats/homogeneity_score.cuhcpp/include/raft/stats/information_criterion.cuhcpp/include/raft/stats/kl_divergence.cuhcpp/include/raft/stats/mean.cuhcpp/include/raft/stats/mean_center.cuhcpp/include/raft/stats/meanvar.cuhcpp/include/raft/stats/minmax.cuhcpp/include/raft/stats/mutual_info_score.cuhcpp/include/raft/stats/neighborhood_recall.cuhcpp/include/raft/stats/r2_score.cuhcpp/include/raft/stats/rand_index.cuhcpp/include/raft/stats/regression_metrics.cuhcpp/include/raft/stats/stddev.cuhcpp/include/raft/stats/sum.cuhcpp/include/raft/stats/v_measure.cuhcpp/include/raft/stats/weighted_mean.cuhcpp/tests/CMakeLists.txtcpp/tests/core/bitmap.cucpp/tests/core/bitset.cucpp/tests/core/mdarray.cucpp/tests/core/mdbuffer.cucpp/tests/core/mdspan_copy.cucpp/tests/core/mdspan_utils.cucpp/tests/core/sparse_matrix.cucpp/tests/core/temporary_device_buffer.cucpp/tests/linalg/add.cucpp/tests/linalg/axpy.cucpp/tests/linalg/binary_op.cucpp/tests/linalg/coalesced_reduction.cucpp/tests/linalg/divide.cucpp/tests/linalg/dot.cucpp/tests/linalg/eig.cucpp/tests/linalg/gemm_basic.cppcpp/tests/linalg/gemm_layout.cucpp/tests/linalg/map.cucpp/tests/linalg/matrix_vector_op.cucpp/tests/linalg/mean_squared_error.cucpp/tests/linalg/multiply.cucpp/tests/linalg/norm.cucpp/tests/linalg/normalize.cucpp/tests/linalg/pca.cucpp/tests/linalg/power.cucpp/tests/linalg/reduce.cucpp/tests/linalg/rsvd.cucpp/tests/linalg/strided_reduction.cucpp/tests/linalg/subtract.cucpp/tests/linalg/svd.cucpp/tests/linalg/ternary_op.cucpp/tests/linalg/transpose.cucpp/tests/linalg/unary_op.cucpp/tests/matrix/gather.cucpp/tests/matrix/sample_rows.cucpp/tests/sparse/convert_csr.cucpp/tests/sparse/csr_transpose.cucpp/tests/sparse/diagonal.cucpp/tests/sparse/filter.cucpp/tests/sparse/masked_matmul.cucpp/tests/sparse/norm.cucpp/tests/sparse/preprocess.cucpp/tests/sparse/reduce.cucpp/tests/sparse/sddmm.cucpp/tests/sparse/select_k_csr.cucpp/tests/sparse/solver/lanczos.cucpp/tests/sparse/solver/randomized_svds.cucpp/tests/sparse/spmm.cucpp/tests/sparse/symmetrize.cucpp/tests/stats/cov.cucpp/tests/stats/homogeneity_score.cucpp/tests/stats/mean.cucpp/tests/stats/meanvar.cucpp/tests/stats/minmax.cucpp/tests/stats/stddev.cucpp/tests/stats/sum.cucpp/tests/stats/weighted_mean.cucpp/tests/test_utils.cuhcpp/tests/util/dry_run_guards.cucpp/tests/util/dry_run_resources.cppcpp/tests/util/memory_type_dispatcher.cucpp/tests/util/popc.cudocs/source/cpp_api/core_resources.rstdocs/source/developer_guide.mddocs/source/dry_run_protocol.md
💤 Files with no reviewable changes (1)
- cpp/include/raft/stats/detail/sum.cuh
🚧 Files skipped from review as they are similar to previous changes (223)
- cpp/include/raft/sparse/linalg/detail/utils.cuh
- cpp/include/raft/matrix/detail/select_k-inl.cuh
- cpp/include/raft/matrix/detail/gather_inplace.cuh
- cpp/include/raft/core/copy.hpp
- cpp/include/raft/matrix/init.cuh
- cpp/include/raft/matrix/detail/matrix.cuh
- cpp/include/raft/linalg/reduce_rows_by_key.cuh
- cpp/tests/linalg/coalesced_reduction.cu
- cpp/include/raft/linalg/sqrt.cuh
- cpp/include/raft/matrix/detail/shift.cuh
- cpp/include/raft/linalg/reduce_cols_by_key.cuh
- cpp/include/raft/linalg/matrix_vector_op.cuh
- cpp/include/raft/linalg/strided_reduction.cuh
- cpp/include/raft/linalg/power.cuh
- cpp/tests/linalg/binary_op.cu
- cpp/include/raft/linalg/divide.cuh
- cpp/include/raft/linalg/mean_squared_error.cuh
- cpp/include/raft/matrix/sign_flip.cuh
- cpp/include/raft/linalg/map_reduce.cuh
- cpp/include/raft/linalg/detail/axpy.cuh
- cpp/include/raft/core/sparse_types.hpp
- cpp/include/raft/stats/detail/cov.cuh
- cpp/include/raft/matrix/argmax.cuh
- cpp/include/raft/core/copy.cuh
- docs/source/cpp_api/core_resources.rst
- cpp/include/raft/matrix/slice.cuh
- cpp/include/raft/matrix/diagonal.cuh
- cpp/include/raft/matrix/detail/math.cuh
- cpp/tests/sparse/reduce.cu
- cpp/include/raft/core/bitset.cuh
- cpp/include/raft/matrix/detail/scatter_inplace.cuh
- cpp/include/raft/random/sample_without_replacement.cuh
- cpp/include/raft/linalg/detail/map.cuh
- cpp/tests/linalg/power.cu
- cpp/tests/linalg/eig.cu
- cpp/include/raft/sparse/linalg/detail/sddmm.hpp
- cpp/include/raft/linalg/unary_op.cuh
- cpp/include/raft/matrix/detail/select_warpsort.cuh
- .coderabbit.yaml
- cpp/include/raft/matrix/triangular.cuh
- cpp/tests/core/mdbuffer.cu
- cpp/include/raft/random/make_blobs.cuh
- cpp/include/raft/matrix/col_wise_sort.cuh
- cpp/include/raft/sparse/convert/detail/csr.cuh
- cpp/include/raft/linalg/detail/reduce.cuh
- cpp/include/raft/stats/detail/kl_divergence.cuh
- cpp/include/raft/linalg/multiply.cuh
- cpp/include/raft/stats/rand_index.cuh
- cpp/include/raft/matrix/power.cuh
- cpp/include/raft/core/host_mdarray.hpp
- cpp/include/raft/spectral/detail/partition.hpp
- cpp/tests/stats/stddev.cu
- cpp/tests/sparse/preprocess.cu
- cpp/include/raft/matrix/threshold.cuh
- cpp/include/raft/matrix/linewise_op.cuh
- cpp/tests/core/temporary_device_buffer.cu
- cpp/include/raft/core/managed_mdarray.hpp
- cpp/include/raft/stats/information_criterion.cuh
- cpp/include/raft/matrix/reciprocal.cuh
- cpp/include/raft/linalg/dot.cuh
- cpp/tests/linalg/subtract.cu
- cpp/include/raft/core/pinned_mdarray.hpp
- cpp/tests/linalg/ternary_op.cu
- cpp/include/raft/stats/mean_center.cuh
- cpp/include/raft/matrix/argmin.cuh
- cpp/include/raft/linalg/detail/cholesky_r1_update.cuh
- cpp/tests/sparse/solver/lanczos.cu
- cpp/include/raft/core/detail/copy.hpp
- cpp/include/raft/linalg/detail/svd.cuh
- cpp/tests/core/bitmap.cu
- cpp/tests/sparse/norm.cu
- cpp/include/raft/core/resource/cuda_stream.hpp
- cpp/tests/linalg/transpose.cu
- cpp/tests/linalg/normalize.cu
- cpp/include/raft/random/detail/make_blobs.cuh
- cpp/include/raft/core/coo_matrix.hpp
- cpp/include/raft/linalg/norm.cuh
- cpp/include/raft/linalg/subtract.cuh
- cpp/include/raft/random/detail/multi_variable_gaussian.cuh
- cpp/include/raft/stats/detail/neighborhood_recall.cuh
- cpp/include/raft/sparse/convert/detail/adj_to_csr.cuh
- cpp/include/raft/stats/detail/dispersion.cuh
- cpp/include/raft/sparse/op/sort.cuh
- cpp/include/raft/random/detail/rng_impl_deprecated.cuh
- cpp/tests/util/memory_type_dispatcher.cu
- cpp/tests/core/mdarray.cu
- cpp/tests/linalg/matrix_vector_op.cu
- cpp/tests/linalg/axpy.cu
- cpp/include/raft/linalg/detail/cublaslt_wrappers.hpp
- cpp/tests/stats/meanvar.cu
- cpp/include/raft/stats/accuracy.cuh
- cpp/include/raft/linalg/detail/matrix_vector_op.cuh
- cpp/include/raft/stats/v_measure.cuh
- cpp/include/raft/matrix/gather.cuh
- cpp/include/raft/stats/completeness_score.cuh
- cpp/tests/sparse/select_k_csr.cu
- cpp/include/raft/core/resource/resource_types.hpp
- cpp/tests/sparse/symmetrize.cu
- cpp/tests/linalg/multiply.cu
- cpp/include/raft/stats/detail/rand_index.cuh
- cpp/include/raft/stats/entropy.cuh
- cpp/include/raft/spectral/detail/spectral_util.cuh
- cpp/include/raft/linalg/reduce.cuh
- cpp/include/raft/stats/adjusted_rand_index.cuh
- cpp/tests/core/mdspan_copy.cu
- cpp/tests/linalg/dot.cu
- cpp/include/raft/linalg/detail/coalesced_reduction-inl.cuh
- cpp/include/raft/stats/detail/contingencyMatrix.cuh
- cpp/include/raft/matrix/reverse.cuh
- cpp/include/raft/stats/kl_divergence.cuh
- cpp/tests/sparse/sddmm.cu
- cpp/include/raft/stats/homogeneity_score.cuh
- cpp/include/raft/stats/regression_metrics.cuh
- cpp/include/raft/sparse/op/detail/reduce.cuh
- cpp/include/raft/linalg/detail/transpose.cuh
- cpp/include/raft/linalg/detail/pca.cuh
- cpp/tests/stats/cov.cu
- cpp/include/raft/random/permute.cuh
- cpp/include/raft/linalg/detail/gemv.hpp
- cpp/include/raft/stats/contingency_matrix.cuh
- cpp/include/raft/linalg/detail/rsvd.cuh
- cpp/include/raft/stats/detail/mean_center.cuh
- cpp/include/raft/stats/mutual_info_score.cuh
- cpp/include/raft/matrix/print.cuh
- cpp/include/raft/linalg/coalesced_reduction.cuh
- cpp/include/raft/sparse/convert/detail/bitmap_to_csr.cuh
- cpp/include/raft/core/device_mdarray.hpp
- cpp/include/raft/stats/histogram.cuh
- cpp/tests/sparse/masked_matmul.cu
- cpp/include/raft/stats/weighted_mean.cuh
- cpp/tests/sparse/diagonal.cu
- cpp/tests/stats/mean.cu
- cpp/include/raft/random/detail/make_regression.cuh
- cpp/include/raft/sparse/convert/detail/bitset_to_csr.cuh
- cpp/tests/core/mdspan_utils.cu
- cpp/include/raft/stats/mean.cuh
- cpp/include/raft/sparse/matrix/preprocessing.cuh
- cpp/include/raft/label/classlabels.cuh
- cpp/include/raft/stats/r2_score.cuh
- cpp/include/raft/sparse/linalg/detail/spmm.hpp
- cpp/tests/sparse/filter.cu
- cpp/tests/util/popc.cu
- cpp/tests/linalg/add.cu
- cpp/include/raft/sparse/solver/detail/cholesky_qr.cuh
- cpp/tests/linalg/gemm_basic.cpp
- cpp/include/raft/stats/meanvar.cuh
- cpp/include/raft/sparse/linalg/detail/symmetrize.cuh
- cpp/include/raft/matrix/detail/select_radix.cuh
- cpp/include/raft/stats/detail/mutual_info_score.cuh
- cpp/include/raft/matrix/copy.cuh
- cpp/include/raft/core/device_container_policy.hpp
- cpp/include/raft/stats/minmax.cuh
- cpp/tests/linalg/rsvd.cu
- cpp/include/raft/linalg/add.cuh
- docs/source/developer_guide.md
- cpp/tests/stats/minmax.cu
- cpp/include/raft/matrix/detail/gather.cuh
- cpp/tests/stats/sum.cu
- cpp/tests/linalg/unary_op.cu
- cpp/tests/linalg/map.cu
- cpp/tests/linalg/strided_reduction.cu
- cpp/include/raft/random/detail/rmat_rectangular_generator.cuh
- cpp/include/raft/stats/sum.cuh
- cpp/tests/linalg/norm.cu
- cpp/tests/core/bitset.cu
- docs/source/dry_run_protocol.md
- cpp/include/raft/stats/detail/batched/silhouette_score.cuh
- cpp/include/raft/sparse/matrix/detail/preprocessing.cuh
- cpp/include/raft/stats/detail/entropy.cuh
- cpp/include/raft/stats/neighborhood_recall.cuh
- cpp/include/raft/linalg/detail/lstsq.cuh
- cpp/tests/linalg/pca.cu
- cpp/include/raft/stats/detail/homogeneity_score.cuh
- cpp/include/raft/core/bitset.hpp
- cpp/tests/matrix/sample_rows.cu
- cpp/tests/linalg/reduce.cu
- cpp/include/raft/matrix/detail/columnWiseSort.cuh
- cpp/tests/linalg/mean_squared_error.cu
- cpp/include/raft/sparse/op/detail/filter.cuh
- cpp/include/raft/stats/detail/trustworthiness_score.cuh
- cpp/include/raft/sparse/solver/detail/randomized_svds.cuh
- cpp/tests/sparse/csr_transpose.cu
- cpp/include/raft/label/detail/classlabels.cuh
- cpp/include/raft/core/csr_matrix.hpp
- cpp/tests/CMakeLists.txt
- cpp/tests/linalg/svd.cu
- cpp/tests/core/sparse_matrix.cu
- cpp/tests/linalg/divide.cu
- cpp/include/raft/matrix/sqrt.cuh
- cpp/include/raft/matrix/norm.cuh
- cpp/include/raft/stats/detail/mean.cuh
- cpp/include/raft/stats/dispersion.cuh
- cpp/include/raft/stats/stddev.cuh
- cpp/include/raft/linalg/detail/norm.cuh
- cpp/include/raft/stats/detail/adjusted_rand_index.cuh
- cpp/include/raft/stats/detail/silhouette_score.cuh
- cpp/tests/stats/weighted_mean.cu
- cpp/include/raft/mr/dry_run_resource.hpp
- cpp/include/raft/linalg/detail/qr.cuh
- cpp/include/raft/sparse/solver/detail/lanczos.cuh
- cpp/tests/matrix/gather.cu
- cpp/tests/linalg/gemm_layout.cu
- cpp/include/raft/sparse/linalg/spmm.hpp
- cpp/include/raft/linalg/detail/eig.cuh
- cpp/include/raft/sparse/op/detail/sort.h
- cpp/include/raft/core/resource/dry_run_flag.hpp
- cpp/include/raft/solver/detail/lap_functions.cuh
- cpp/include/raft/random/detail/rng_impl.cuh
- cpp/include/raft/random/rng.cuh
- cpp/include/raft/stats/detail/scores.cuh
- cpp/include/raft/sparse/solver/detail/svds_sign_correction.cuh
- cpp/include/raft/stats/detail/weighted_mean.cuh
- cpp/tests/test_utils.cuh
- cpp/include/raft/spectral/detail/matrix_wrappers.hpp
- cpp/include/raft/stats/detail/meanvar.cuh
- cpp/tests/sparse/spmm.cu
- cpp/include/raft/stats/detail/stddev.cuh
- cpp/include/raft/linalg/normalize.cuh
- cpp/include/raft/sparse/linalg/detail/laplacian.cuh
- cpp/tests/sparse/convert_csr.cu
- cpp/include/raft/stats/detail/v_measure.cuh
- cpp/include/raft/spectral/detail/modularity_maximization.hpp
- cpp/tests/stats/homogeneity_score.cu
| void reallocate(size_type count) | ||
| { | ||
| if (bytesize_ == sizeof(value_type) * count) { return; } | ||
| if (data_ != nullptr) { | ||
| mr_.deallocate_sync(data_, bytesize_); | ||
| data_ = nullptr; | ||
| } | ||
| auto tmp = host_container{count, mr_}; | ||
| std::swap(tmp, *this); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Reset bytesize_ when you release the old buffer.
Line 122 deallocates the buffer and Line 123 clears data_, but bytesize_ keeps the old value. If the allocation inside host_container{count, mr_} throws, *this is left with bytesize_ > 0 and data_ == nullptr. The destructor is safe because it checks both fields, but resize() then computes cur_count from the stale bytesize_ and calls std::copy from a null pointer.
🛠️ Proposed fix
if (data_ != nullptr) {
mr_.deallocate_sync(data_, bytesize_);
data_ = nullptr;
}
+ bytesize_ = 0;
auto tmp = host_container{count, mr_};
std::swap(tmp, *this);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void reallocate(size_type count) | |
| { | |
| if (bytesize_ == sizeof(value_type) * count) { return; } | |
| if (data_ != nullptr) { | |
| mr_.deallocate_sync(data_, bytesize_); | |
| data_ = nullptr; | |
| } | |
| auto tmp = host_container{count, mr_}; | |
| std::swap(tmp, *this); | |
| } | |
| void reallocate(size_type count) | |
| { | |
| if (bytesize_ == sizeof(value_type) * count) { return; } | |
| if (data_ != nullptr) { | |
| mr_.deallocate_sync(data_, bytesize_); | |
| data_ = nullptr; | |
| } | |
| bytesize_ = 0; | |
| auto tmp = host_container{count, mr_}; | |
| std::swap(tmp, *this); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cpp/include/raft/core/host_container_policy.hpp` around lines 118 - 127,
Update host_container::reallocate so bytesize_ is reset to zero immediately when
the existing data_ buffer is deallocated and data_ is cleared, before
constructing host_container{count, mr_}; preserve the existing allocation and
swap behavior.
The dry run protocol defines a mechanism to simulate the execution of algorithms to get a precise estimate of the memory requirements for a real execution with the same parameters.
This PR:
raft::util::dry_run_execute,raft::dry_run_resources, andresource::get_dry_run_flagto let callers estimate peak memory usage of any RAFT algorithm without executing GPU work.Note for reviewers
The PR contains a lot of small tedious changes to cover all of raft library and the tests components.
Please start reading at
docs/sourceupdates to learn more about the topic and the principles guiding these changes.