Skip to content

Split random forest histogram building and split scoring kernels - #8370

Merged
rapids-bot[bot] merged 11 commits into
NVIDIA:mainfrom
RAMitchell:codex/enh-rf-split-kernels-preserve-shmem
Jul 14, 2026
Merged

Split random forest histogram building and split scoring kernels#8370
rapids-bot[bot] merged 11 commits into
NVIDIA:mainfrom
RAMitchell:codex/enh-rf-split-kernels-preserve-shmem

Conversation

@RAMitchell

Copy link
Copy Markdown
Contributor

Description

Splits random forest split computation into two kernel launches:

  • buildHistogramsKernel: builds per-node/per-feature histograms
  • findBestSplitsKernel: converts histograms to CDFs and scores split candidates

This is preparation for distributed histogram construction. In the distributed path, each rank will build partial histograms locally, then an all-reduce must take place before split scoring can run. Splitting histogram construction and split scoring gives that all-reduce a natural synchronization point between the two kernels.

The histogram kernel preserves the existing shared-memory fast path for histogram accumulation and quantile lookup. The split-scoring kernel no longer uses dynamic shared memory for quantiles, since it only indexes quantile thresholds by bin rather than searching them per row.

Notes

  • Histogram layout remains dense by node and sampled feature.
  • Shared-memory atomics are preserved for histogram construction.
  • Split scoring still uses static shared memory for CUB scan state and per-warp split reduction scratch.
  • Dynamic shared memory is now only needed by the histogram kernel.

Testing

  • Built SG_RF_TEST
  • Ran RFEquivalentSplitRangeTest.*:RfTest.EquivalentSplitRangePersistsThroughBuilder

@copy-pr-bot

copy-pr-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@RAMitchell RAMitchell added improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Jul 13, 2026
@RAMitchell
RAMitchell requested a review from Copilot July 13, 2026 11:09
@RAMitchell
RAMitchell marked this pull request as ready for review July 13, 2026 11:10
@RAMitchell
RAMitchell requested a review from a team as a code owner July 13, 2026 11:10
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d17cb377-34b1-4f23-809a-cf7a29f0bbab

📥 Commits

Reviewing files that changed from the base of the PR and between 61ede93 and b165a70.

📒 Files selected for processing (17)
  • cpp/src/decisiontree/batched-levelalgo/builder.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-float.cu
  • python/cuml/cuml/_thirdparty/sklearn/preprocessing/_data.py
  • python/cuml/cuml/decomposition/pca.pyx
  • python/cuml/cuml/decomposition/tsvd.pyx
  • python/cuml/cuml/manifold/t_sne.pyx
  • python/cuml/cuml/neighbors/kneighbors_regressor.pyx
  • python/cuml/tests/test_sklearn_compatibility.py
🚧 Files skipped from review as they are similar to previous changes (11)
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/builder.cuh

📝 Walkthrough

Summary by CodeRabbit

  • Performance
    • Improved GPU decision-tree split computation by splitting it into a dedicated histogram-building stage followed by best-split selection.
    • Added adaptive shared-memory sizing for split analysis, automatically choosing shared- or global-histogram paths based on available shared memory.
    • Reduced extra device bookkeeping during batched tree growth by streamlining synchronization and workload scheduling.

Walkthrough

The batched decision-tree builder removes done_count and large-node workload tracking, introduces shared-memory configuration, and replaces the monolithic split kernel with separate histogram-building and best-split kernels across objective instantiations.

Changes

Batched split pipeline

Layer / File(s) Summary
Workspace and workload bookkeeping
cpp/src/decisiontree/batched-levelalgo/builder.cuh
Removes done_count allocation and initialization, simplifies workload metadata, and updates partition block-count handling.
Split kernel contracts
cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh, cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
Removes large_nodeid, adds SharedMemoryConfig, changes pdf_to_cdf to in-place conversion, and replaces the split-launch declaration.
Builder split orchestration
cpp/src/decisiontree/batched-levelalgo/builder.cuh
Computes shared-memory configuration and launches histogram and split work with separate grids.
Two-stage split kernels
cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
Adds histogram construction and best-split evaluation kernels coordinated by launchComputeSplitKernels.
Objective-specific launcher wiring
cpp/src/decisiontree/batched-levelalgo/kernels/*classification*.cu, cpp/src/decisiontree/batched-levelalgo/kernels/*regression*.cu
Updates classification, regression, and weighted template instantiations to the revised launcher signature.
Attribution header updates
cpp/src/decisiontree/..., python/cuml/cuml/..., python/cuml/tests/test_sklearn_compatibility.py
Updates SPDX copyright attribution text in modified files.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: dantegd, lowener

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: splitting histogram building from split scoring in the random forest pipeline.
Description check ✅ Passed The description is clearly aligned with the PR, describing the same two-kernel split and its distributed synchronization purpose.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/src/decisiontree/batched-levelalgo/builder.cuh`:
- Around line 550-551: Guard the dim3 launch dimensions in the histogram_grid
and split_grid initialization by converting each size_t/int dimension through
ML::narrow_cast<ML::cuda_launch_t> before constructing dim3. Preserve the
existing grid dimensions while ensuring oversized values fail on the host
instead of truncating to unsigned int.
🪄 Autofix (Beta)

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: 61575d02-2dbc-4264-a9fd-a31c1fdb2922

📥 Commits

Reviewing files that changed from the base of the PR and between f19ca67 and 13695e8.

📒 Files selected for processing (11)
  • cpp/src/decisiontree/batched-levelalgo/builder.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-float.cu

Comment thread cpp/src/decisiontree/batched-levelalgo/builder.cuh Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the batched-level random forest split computation into two separate CUDA kernel launches: one for histogram construction and another for CDF conversion + split scoring. This separation creates a clean synchronization point needed for upcoming distributed histogram all-reduce integration while keeping the existing shared-memory histogram fast path.

Changes:

  • Split the previous monolithic split kernel into buildHistogramsKernel and findBestSplitsKernel, and update the host launcher API accordingly.
  • Remove the inter-block completion handshake (done_count) and rework workload bookkeeping to support the two-kernel flow.
  • Update all explicit template instantiations and shared-memory configuration plumbing to match the new launcher signature.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh Implements the new two-kernel split flow and updates histogram/CDF handling.
cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh Updates public kernel launcher declarations and introduces SharedMemoryConfig.
cpp/src/decisiontree/batched-levelalgo/builder.cuh Removes done_count, adjusts workspace sizing, workload mapping, and launches the split kernels with separate grids.
cpp/src/decisiontree/batched-levelalgo/kernels/regression-float.cu Updates explicit instantiation to launchComputeSplitKernels and new parameters.
cpp/src/decisiontree/batched-levelalgo/kernels/regression-double.cu Updates explicit instantiation to launchComputeSplitKernels and new parameters.
cpp/src/decisiontree/batched-levelalgo/kernels/classification-float.cu Updates explicit instantiation to launchComputeSplitKernels and new parameters.
cpp/src/decisiontree/batched-levelalgo/kernels/classification-double.cu Updates explicit instantiation to launchComputeSplitKernels and new parameters.
cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-float.cu Updates explicit instantiation to launchComputeSplitKernels and new parameters.
cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-double.cu Updates explicit instantiation to launchComputeSplitKernels and new parameters.
cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-float.cu Updates explicit instantiation to launchComputeSplitKernels and new parameters.
cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-double.cu Updates explicit instantiation to launchComputeSplitKernels and new parameters.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@RAMitchell

Copy link
Copy Markdown
Contributor Author
Benchmark Main PR Speedup
RFClassifier<float>/blobs/12 539.6 ms 497.2 ms 1.09x
RFClassifier<float>/blobs/13 532.1 ms 479.7 ms 1.11x
RFClassifier<float>/blobs/14 777.8 ms 758.0 ms 1.03x
RFClassifier<float>/blobs/15 868.5 ms 755.9 ms 1.15x

@chyunsu3 chyunsu3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Nice job cleaning up the code.

Comment on lines -343 to -348
__threadfence(); // for commit guarantee before the last block scores the split
if (!use_global_memory_histogram) {
__syncthreads();

bool last = MLCommon::signalDone(
done_count + nid * gridDim.y + blockIdx.y, num_blocks, offset_blockid == 0, shared_done);
if (!last) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signaling a completion is no longer needed because we now have two kernels, with a natural point for synchronization in between. Is my understanding correct?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the kernel boundary is now the sync.

@RAMitchell
RAMitchell requested a review from a team as a code owner July 14, 2026 09:42
@RAMitchell
RAMitchell requested a review from dantegd July 14, 2026 09:42
@github-actions github-actions Bot added the Cython / Python Cython or Python issue label Jul 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@python/cuml/cuml/decomposition/pca.pyx`:
- Around line 482-483: Remove the ensure_min_features=2 guard from the input
validation in python/cuml/cuml/decomposition/pca.pyx lines 482-483,
python/cuml/cuml/decomposition/tsvd.pyx lines 316-317, and
python/cuml/cuml/manifold/t_sne.pyx lines 598-599 so valid one-feature inputs
are accepted; if retaining the restriction instead, document it and add coverage
for the enforced behavior at all three sites.
🪄 Autofix (Beta)

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: d17cb377-34b1-4f23-809a-cf7a29f0bbab

📥 Commits

Reviewing files that changed from the base of the PR and between 61ede93 and b165a70.

📒 Files selected for processing (17)
  • cpp/src/decisiontree/batched-levelalgo/builder.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-float.cu
  • python/cuml/cuml/_thirdparty/sklearn/preprocessing/_data.py
  • python/cuml/cuml/decomposition/pca.pyx
  • python/cuml/cuml/decomposition/tsvd.pyx
  • python/cuml/cuml/manifold/t_sne.pyx
  • python/cuml/cuml/neighbors/kneighbors_regressor.pyx
  • python/cuml/tests/test_sklearn_compatibility.py
🚧 Files skipped from review as they are similar to previous changes (11)
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/builder.cuh

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

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 `@python/cuml/cuml/decomposition/pca.pyx`:
- Around line 482-483: Remove the ensure_min_features=2 guard from the input
validation in python/cuml/cuml/decomposition/pca.pyx lines 482-483,
python/cuml/cuml/decomposition/tsvd.pyx lines 316-317, and
python/cuml/cuml/manifold/t_sne.pyx lines 598-599 so valid one-feature inputs
are accepted; if retaining the restriction instead, document it and add coverage
for the enforced behavior at all three sites.
🪄 Autofix (Beta)

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: d17cb377-34b1-4f23-809a-cf7a29f0bbab

📥 Commits

Reviewing files that changed from the base of the PR and between 61ede93 and b165a70.

📒 Files selected for processing (17)
  • cpp/src/decisiontree/batched-levelalgo/builder.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-float.cu
  • python/cuml/cuml/_thirdparty/sklearn/preprocessing/_data.py
  • python/cuml/cuml/decomposition/pca.pyx
  • python/cuml/cuml/decomposition/tsvd.pyx
  • python/cuml/cuml/manifold/t_sne.pyx
  • python/cuml/cuml/neighbors/kneighbors_regressor.pyx
  • python/cuml/tests/test_sklearn_compatibility.py
🚧 Files skipped from review as they are similar to previous changes (11)
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/classification-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-classification-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-float.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/weighted-regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/kernels/builder_kernels_impl.cuh
  • cpp/src/decisiontree/batched-levelalgo/kernels/regression-double.cu
  • cpp/src/decisiontree/batched-levelalgo/builder.cuh
🛑 Comments failed to post (1)
python/cuml/cuml/decomposition/pca.pyx (1)

482-483: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant source ranges and search for related validation/tests/docs.
for f in \
  python/cuml/cuml/decomposition/pca.pyx \
  python/cuml/cuml/decomposition/tsvd.pyx \
  python/cuml/cuml/manifold/t_sne.pyx
do
  echo "===== $f ====="
  wc -l "$f"
done

echo "===== PCA excerpt ====="
sed -n '450,510p' python/cuml/cuml/decomposition/pca.pyx

echo "===== TSVD excerpt ====="
sed -n '280,340p' python/cuml/cuml/decomposition/tsvd.pyx

echo "===== t-SNE excerpt ====="
sed -n '560,630p' python/cuml/cuml/manifold/t_sne.pyx

echo "===== Search for ensure_min_features / one-feature handling ====="
rg -n "ensure_min_features\s*=\s*2|ensure_min_features|min_features|n_features == 1|one feature|1-feature|single feature" python/cuml/cuml -g '!**/build/**' -g '!**/dist/**'

echo "===== Search for docs/tests mentioning feature minimums ====="
rg -n "PCA|TruncatedSVD|TSVD|t-SNE|t_sne|ensure_min_features|one feature|single feature|n_features" python -g '!**/build/**' -g '!**/dist/**'

Repository: rapidsai/cuml

Length of output: 50370


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show only the exact validation blocks and nearby comments.
nl -ba python/cuml/cuml/decomposition/pca.pyx | sed -n '470,490p'
echo
nl -ba python/cuml/cuml/decomposition/tsvd.pyx | sed -n '305,325p'
echo
nl -ba python/cuml/cuml/manifold/t_sne.pyx | sed -n '588,608p'
echo
# Look for any estimator docs that state the minimum number of features.
rg -n "minimum.*feature|at least 2 features|ensure_min_features|n_features" python/cuml/cuml/decomposition python/cuml/cuml/manifold -g '!**/build/**' -g '!**/dist/**'

Repository: rapidsai/cuml

Length of output: 191


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "===== Relevant validation docs ====="
sed -n '100,165p' python/cuml/cuml/internals/validation.py

echo "===== PCA/TSVD/t-SNE docstrings around fit ====="
sed -n '450,500p' python/cuml/cuml/decomposition/pca.pyx
echo
sed -n '300,330p' python/cuml/cuml/decomposition/tsvd.pyx
echo
sed -n '585,610p' python/cuml/cuml/manifold/t_sne.pyx

echo "===== Tests mentioning single-feature inputs or feature minima ====="
rg -n "single feature|one feature|n_features=1|n_features == 1|minimum of 2|ensure_min_features=2" python/cuml/cuml_accel_tests python/cuml/tests python/cuml/cuml -g '!**/build/**' -g '!**/dist/**' | head -n 200

Repository: rapidsai/cuml

Length of output: 17565


Remove or document the 2-feature minimum

ensure_min_features=2 blocks valid 1-feature inputs in python/cuml/cuml/decomposition/pca.pyx#L482-L483, python/cuml/cuml/decomposition/tsvd.pyx#L316-L317, and python/cuml/cuml/manifold/t_sne.pyx#L598-L599. If that restriction is intentional, add docs and tests; otherwise drop the guard.

📍 Affects 3 files
  • python/cuml/cuml/decomposition/pca.pyx#L482-L483 (this comment)
  • python/cuml/cuml/decomposition/tsvd.pyx#L316-L317
  • python/cuml/cuml/manifold/t_sne.pyx#L598-L599
🤖 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 `@python/cuml/cuml/decomposition/pca.pyx` around lines 482 - 483, Remove the
ensure_min_features=2 guard from the input validation in
python/cuml/cuml/decomposition/pca.pyx lines 482-483,
python/cuml/cuml/decomposition/tsvd.pyx lines 316-317, and
python/cuml/cuml/manifold/t_sne.pyx lines 598-599 so valid one-feature inputs
are accepted; if retaining the restriction instead, document it and add coverage
for the enforced behavior at all three sites.

@RAMitchell

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit edc95c5 into NVIDIA:main Jul 14, 2026
102 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CUDA/C++ Cython / Python Cython or Python issue improvement Improvement / enhancement to an existing function non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants