@@ -42,6 +42,13 @@ __device__ void find_local_mapping(cooperative_groups::thread_block const& block
4242 auto const ref_cardinality =
4343 cuda::atomic_ref<size_type, cuda::thread_scope_block>{*cardinality};
4444 auto const shared_set_index = ref_cardinality.fetch_add (1 , cuda::std::memory_order_relaxed);
45+
46+ // The value of `shared_set_index` is before increment, thus if we have
47+ // `shared_set_index == GROUPBY_CARDINALITY_THRESHOLD` the value of cardinality
48+ // will be at least `GROUPBY_CARDINALITY_THRESHOLD + 1`.
49+ // This will trigger fallback to global memory.
50+ if (shared_set_index >= GROUPBY_CARDINALITY_THRESHOLD ) { return cuda::std::pair{0 , true }; }
51+
4552 shared_set_indices[shared_set_index] = idx;
4653 local_mapping_indices[idx] = shared_set_index;
4754 }
@@ -71,7 +78,7 @@ __device__ void find_global_mapping(cooperative_groups::thread_block const& bloc
7178 auto const input_idx = shared_set_indices[idx];
7279 auto const key_idx = *global_set.insert_and_find (input_idx).first ;
7380
74- global_mapping_indices[block.group_index ().x * GROUPBY_SHM_MAX_ELEMENTS + idx] = key_idx;
81+ global_mapping_indices[block.group_index ().x * GROUPBY_CARDINALITY_THRESHOLD + idx] = key_idx;
7582 }
7683}
7784
@@ -88,9 +95,10 @@ CUDF_KERNEL void mapping_indices_kernel(size_type num_input_rows,
8895 bitmask_type const * row_bitmask,
8996 size_type* local_mapping_indices,
9097 size_type* global_mapping_indices,
91- size_type* block_cardinality)
98+ size_type* block_cardinality,
99+ cuda::std::atomic_flag* needs_global_memory_fallback)
92100{
93- __shared__ size_type shared_set_indices[GROUPBY_SHM_MAX_ELEMENTS ];
101+ __shared__ size_type shared_set_indices[GROUPBY_CARDINALITY_THRESHOLD ];
94102
95103 // Shared set initialization
96104 __shared__ size_type slots[valid_extent.value ()];
@@ -126,12 +134,17 @@ CUDF_KERNEL void mapping_indices_kernel(size_type num_input_rows,
126134 shared_set_indices);
127135
128136 block.sync ();
129- if (cardinality >= GROUPBY_CARDINALITY_THRESHOLD ) { break ; }
137+ if (cardinality > GROUPBY_CARDINALITY_THRESHOLD ) {
138+ if (block.thread_rank () == 0 ) {
139+ needs_global_memory_fallback->test_and_set (cuda::std::memory_order_relaxed);
140+ }
141+ break ;
142+ }
130143 }
131144
132145 // Insert unique keys from shared to global hash set if block-cardinality
133146 // doesn't exceed the threshold upper-limit
134- if (cardinality < GROUPBY_CARDINALITY_THRESHOLD ) {
147+ if (cardinality <= GROUPBY_CARDINALITY_THRESHOLD ) {
135148 find_global_mapping (block, cardinality, global_set, shared_set_indices, global_mapping_indices);
136149 }
137150
@@ -155,13 +168,16 @@ void compute_mapping_indices(size_type grid_size,
155168 size_type* local_mapping_indices,
156169 size_type* global_mapping_indices,
157170 size_type* block_cardinality,
171+ cuda::std::atomic_flag* needs_global_memory_fallback,
158172 rmm::cuda_stream_view stream)
159173{
160- mapping_indices_kernel<<<grid_size, GROUPBY_BLOCK_SIZE , 0 , stream>>> (num_rows,
161- global_set,
162- row_bitmask,
163- local_mapping_indices,
164- global_mapping_indices,
165- block_cardinality);
174+ mapping_indices_kernel<<<grid_size, GROUPBY_BLOCK_SIZE , 0 , stream>>> (
175+ num_rows,
176+ global_set,
177+ row_bitmask,
178+ local_mapping_indices,
179+ global_mapping_indices,
180+ block_cardinality,
181+ needs_global_memory_fallback);
166182}
167183} // namespace cudf::groupby::detail::hash
0 commit comments