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)...);
88 const unsigned int ticket = atomicAdd(&store->mutex_ticket, 1U);
90 unsigned int last_check = 0;
92 bool was_once_valid =
false;
98 last_check = atomicOr(&store->mutex_check, 0U);
99 was_once_valid = !(last_check & 0x80000000U);
102 while (last_check < ticket && !(last_check & 0x80000000U));
104 return was_once_valid &&
count < 10000;
123 if (atomicOr(&store->poll_closed, 0U) == 0)
125 old_count = atomicAdd(&store->count, 1);
126 store->block_indices[blockIdx.x] = old_count;
138 if (atomicOr(&store->poll_closed, 0U))
141 atomicOr(&store->poll_closed, 1U);
157 __shared__
bool is_participating;
159 const bool is_reference_thread = (threadIdx.x == 0 && threadIdx.y == 0 && threadIdx.z == 0);
161 if (is_reference_thread)
168 const unsigned int this_block_index = store->block_indices[blockIdx.x];
171 if (is_participating)
173 const bool is_reference_block = (this_block_index == 0);
175 const unsigned int this_thread_index = threadIdx.z * blockDim.y * blockDim.x +
176 threadIdx.y * blockDim.x +
179 const unsigned int num_threads_per_block = blockDim.x * blockDim.y * blockDim.z;
184 Before{}(total_blocks, this_block_index, checker, std::forward<Args>(args)...);
186 while (!checker(total_blocks, this_block_index, std::forward<Args>(args)...))
188 auto helper = [&](
auto func)
191 func(total_blocks, this_block_index, checker, std::forward<Args>(args)...);
199 if (is_reference_block)
202 for (
unsigned int block_to_check = this_thread_index + 1; block_to_check < total_blocks; block_to_check += num_threads_per_block)
204 while (store->wait_flags[block_to_check] == 0);
210 for (
unsigned int block_to_check = this_thread_index + 1; block_to_check < total_blocks; block_to_check += num_threads_per_block)
212 atomicAnd(&(store->wait_flags[block_to_check]), 0U);
219 if (is_reference_thread)
221 atomicOr(&(store->wait_flags[this_block_index]), 1U);
223 while (store->wait_flags[this_block_index] != 0);
232 (helper(Funcs{}), ...);
235 After{}(total_blocks, this_block_index, checker, std::forward<Args>(args)...);
238#if CALORECGPU_ITERATE_UNTIL_CONDITION_DEBUG
239 if (is_reference_thread)
241 printf(
"%d | %d | %u %u \n", blockIdx.x,
static_cast<int>(is_participating), total_blocks, this_block_index);