45 cooperative_groups::grid_group grid = cooperative_groups::this_grid();
49 Before{}(gridDim.x, blockIdx.x, checker, std::forward<Args>(args)...);
51 while (!checker(gridDim.x, blockIdx.x, std::forward<Args>(args)...))
53 auto helper = [&](
auto func)
55 func(gridDim.x, blockIdx.x, checker, std::forward<Args>(args)...);
59 (helper(Funcs{}), ...);
61 After{}(gridDim.x, blockIdx.x, checker, std::forward<Args>(args)...);
155 __shared__
bool is_participating;
157 const bool is_reference_thread = (threadIdx.x == 0 && threadIdx.y == 0 && threadIdx.z == 0);
159 if (is_reference_thread)
166 const unsigned int this_block_index = store->block_indices[blockIdx.x];
169 if (is_participating)
171 const bool is_reference_block = (this_block_index == 0);
173 const unsigned int this_thread_index = threadIdx.z * blockDim.y * blockDim.x +
174 threadIdx.y * blockDim.x +
177 const unsigned int num_threads_per_block = blockDim.x * blockDim.y * blockDim.z;
182 Before{}(total_blocks, this_block_index, checker, std::forward<Args>(args)...);
184 while (!checker(total_blocks, this_block_index, std::forward<Args>(args)...))
186 auto helper = [&](
auto func)
189 func(total_blocks, this_block_index, checker, std::forward<Args>(args)...);
195 if (is_reference_block)
197 for (
unsigned int block_to_check = this_thread_index + 1; block_to_check < total_blocks; block_to_check += num_threads_per_block)
199 unsigned int last_check = 0;
201 volatile unsigned int * to_check =
static_cast<volatile unsigned int*
>(&store->wait_flags[block_to_check]);
205 last_check = *to_check;
207 while (last_check == 0);
213 for (
unsigned int block_to_check = this_thread_index + 1; block_to_check < total_blocks; block_to_check += num_threads_per_block)
217 atomicAnd(&(store->wait_flags[block_to_check]), 0U);
226 if (is_reference_thread)
228 atomicOr(&(store->wait_flags[this_block_index]), 1U);
230 unsigned int last_check = 1;
232 volatile unsigned int * to_check =
static_cast<volatile unsigned int*
>(&store->wait_flags[this_block_index]);
238 last_check = *to_check;
240 while (last_check != 0);
249 (helper(Funcs{}), ...);
252 After{}(total_blocks, this_block_index, checker, std::forward<Args>(args)...);
255#if CALORECGPU_ITERATE_UNTIL_CONDITION_DEBUG
256 if (is_reference_thread)
258 printf(
"%d | %d | %u %u \n", blockIdx.x,
static_cast<int>(is_participating), total_blocks, this_block_index);