can we fallback to a sub-group level implementation?
| 199 | #if FLOOR_COMPUTE_INFO_HAS_SUB_GROUPS != 0 |
| 200 | // can we fallback to a sub-group level implementation? |
| 201 | else if constexpr (group::supports_v<group::ALGORITHM::SUB_GROUP_REDUCE, group::OP::ADD, reduced_type>) { |
| 202 | constexpr const uint32_t linear_work_group_size = compute_linear_work_group_size<work_group_size>(); |
| 203 | |
| 204 | // first pass: inclusive scan in each sub-group |
| 205 | const auto sub_block_red_val = group::sub_group_reduce<group::OP::ADD>(work_item_value); |
| 206 | // first sub-group item writes its result into local memory for the second pass |
| 207 | if (sub_group_local_id == 0u) { |
| 208 | lmem[sub_group_id_1d] = sub_block_red_val; |
| 209 | } |
| 210 | local_barrier(); |
| 211 | |
| 212 | // second pass: reduction of the partial sums in each sub-group to compute the total sum, executed in the first sub-group |
| 213 | reduced_type total_sum {}; |
| 214 | if (sub_group_id_1d == 0u) { |
| 215 | // NOTE: we need to consider that the executing work-group size may be smaller than "sub_group_size * sub_group_size" |
| 216 | const auto sg_in_val = (sub_group_local_id < (linear_work_group_size / sub_group_size) ? lmem[sub_group_local_id] : reduced_type(0)); |
| 217 | total_sum = group::sub_group_reduce<group::OP::ADD>(sg_in_val); |
| 218 | } |
| 219 | local_barrier(); |
| 220 | return total_sum; |
| 221 | } |
| 222 | #endif |
| 223 | return reduce<work_group_size>(work_item_value, lmem, plus<reduced_type> {}); |
| 224 | } |
nothing calls this directly
no test coverage detected