Skip to content

Commit f528bfe

Browse files
committed
Don't prune highways and make the skipping threshold soft
1 parent 4e517d0 commit f528bfe

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

cpp/src/neighbors/detail/cagra/graph_core.cuh

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,15 @@ __global__ void kern_fused_prune(KnnGraphView knn_graph, // [graph_chunk_
380380
}
381381
}
382382

383+
// Cheap stateless integer hash (PCG-style mixing) used for deterministic, warp-uniform thinning of
384+
// reverse-graph edges during the merge step.
385+
__device__ __forceinline__ uint32_t mix_hash(uint32_t x)
386+
{
387+
x = x * 747796405u + 2891336453u;
388+
uint32_t word = ((x >> ((x >> 28u) + 4u)) ^ x) * 277803737u;
389+
return (word >> 22u) ^ word;
390+
}
391+
383392
// Helper functions for merging the graph
384393
template <typename T>
385394
__device__ unsigned int warp_pos_in_array(T val, const T* array, uint64_t num)
@@ -534,7 +543,15 @@ __global__ void kern_merge_graph(
534543
if (rev_graph_value < graph_size) {
535544
if constexpr (VariableDegree) {
536545
const uint32_t in_degree = rev_graph_count(rev_graph_value);
537-
if (std::min(in_degree, my_in_degree) + ed0 < output_graph_degree) { continue; }
546+
if (my_in_degree < output_graph_degree * 3 || in_degree < output_graph_degree * 1) {
547+
// Don't prune highways (edges between high in-degree nodes)
548+
// P(skipping the edge) = a / b
549+
const uint32_t a = output_graph_degree + ed0;
550+
const uint32_t b = output_graph_degree * 2;
551+
const uint32_t r = mix_hash(static_cast<uint32_t>(nid) * 0x9e3779b9u ^
552+
static_cast<uint32_t>(rev_graph_value));
553+
if ((r % b) < a) { continue; }
554+
}
538555
}
539556
uint64_t pos =
540557
warp_pos_in_array<IdxT>(rev_graph_value, smem_sorted_output_graph, output_graph_degree);

0 commit comments

Comments
 (0)