Skip to content

Fixed window temporal sampling - #5625

Open
ChuckHastings wants to merge 7 commits into
rapidsai:mainfrom
ChuckHastings:fixed_window_temporal_sampling
Open

Fixed window temporal sampling#5625
ChuckHastings wants to merge 7 commits into
rapidsai:mainfrom
ChuckHastings:fixed_window_temporal_sampling

Conversation

@ChuckHastings

Copy link
Copy Markdown
Collaborator

Add fixed window temporal sampling implementation, closes #5593

Also lays the groundwork for implementing last-n sampling, updating the API framework temporal sampling to make the last-n choice orthogonal to the temporal parameters.

@copy-pr-bot

copy-pr-bot Bot commented Aug 12, 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.

@ChuckHastings ChuckHastings self-assigned this Aug 12, 2026
@ChuckHastings ChuckHastings added improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Aug 12, 2026
@ChuckHastings
ChuckHastings marked this pull request as ready for review August 12, 2026 17:42
@ChuckHastings
ChuckHastings requested review from a team as code owners August 12, 2026 17:42

@seunghwak seunghwak 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.

Quick reviews/questions about the API changes.

More reviews on the implementation part are in progress.

time) */
LAST /** Support last n behavior */
FIXED_WINDOW, /** Apply the original per-seed time window at every hop */
LAST = FIXED_WINDOW /** Deprecated alias for FIXED_WINDOW */

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.

What is this? Last-N is not a temporal sampling method, it is a neighbor selection method (as specified in neighbor_selection_t), right? Should we better delete this to avoid confusion?

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.

Or last-N or first-N are based on time stamps, not priorities (biases)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Last-N for the current use case is based on timestamps, but we already use timestamps to create biases, so we can easily implement with your new primitive. I think having it based on biases is a more flexible design anyway.

The LAST enum value was already defined, leaving this in place as deprecated to allow this to be a non-breaking API change. If a user previously called with LAST it would be valid, although it would have fast-failed as not implemented.

I'll change this so that it is not the same as FIXED_WINDOW (that's probably not correct) and instead returns a not implemented but deprecated error message. We'll actually delete the value in the next release.

enum class neighbor_selection_t {
RANDOM = 0, /** Random selection. Uniform if no bias view is supplied, biased otherwise. */
FIRST, /** Deterministically select the earliest edges. Not yet implemented. */
LAST /** Deterministically select the latest edges. Not yet implemented. */

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.

Similar here, last-N or first-N are based on time stamps?

In this case, does it make sense to set neighbor_selection_t to LAST and temporal_sampling_comparison_t to STRICTLY_INCREASING?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, that might be a cleaner design. I'll look at that.

Comment on lines +970 to +972
neighbor_selection_t neighbor_selection,
std::optional<temporal_sampling_comparison_t> temporal_sampling_comparison,
sampling_flags_t sampling_flags,

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.

Now we have neighbor_selection_t, temporal_sampling_comparison_t, and sampling_flags_t. But aren't the first two sampling flags (or sampling options)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, I think combining them would make sense, let me look at that.

* is required and @p fan_out contains one value per (hop, edge type). Otherwise, @p fan_out
* contains one value per hop.
*
* RANDOM selection samples uniformly when @p edge_bias_view is absent and samples according to

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.

RANDOM=>neighbor_selection_t::RANDOM?

or something like

neighbor_selection_t dictates a neighbor selection method. RANDOM selection samples ... ?

And documentation for template and input parameters and return values are missing here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Will look at this

@seunghwak seunghwak 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.

Additional reviews.

Comment thread cpp/src/c_api/neighbor_sampling.cpp Outdated
return cugraph::c_api::run_algorithm(graph, functor, result, error);
auto const* options_cpp =
reinterpret_cast<cugraph::c_api::cugraph_sampling_options_t const*>(options);
return cugraph_neighbor_sample(

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.

Any reason the biased wrappers call run_neighbor_sample() (https://github.com/rapidsai/cugraph/pull/5625/changes#diff-d268da7d4ce7574a739c9818704be440c1d2d633f087c39f8a73736b2f057859R746) directly while the uniform wrappers go through cugraph_neighbor_sample()? Better be more consistent about call chains?

It is a bit challenging to understand the call stack hierarchy.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This all should go through cugraph_neighbor_sample, I'll fix that. I tried a few things and ended up with this model, missed getting rid of some of the run_neighbor_sample() calls.

The intention is to remove the old interfaces and have everything call cugraph_neighbor_sample, but I wanted to marek them as deprecated and leave the old methods in place for a release before we delete them.

* SPDX-License-Identifier: Apache-2.0
*/

// Built into libcugraph_common.so: sampling common TUs (gather_one_hop / sample_outgoing_edges)

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.

This seems to describe a build/linkage requirement rather than the implementation itself. Would it be better to keep this explanation in CMakeLists.txt next to where these sources are added to CUGRAPH_COMMON_*?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'll move that.

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

Labels

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.

Temporal sampling: support a fixed per-seed cutoff across hops

2 participants