DDC 0.14.0
Loading...
Searching...
No Matches
for_each_block.cpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#include <cassert>
6#include <cstddef>
7#include <span>
8#include <stdexcept>
9
12
13namespace {
14
15bool is_power_of_2(std::size_t const n) noexcept
16{
17 return n > 0 && !(n & (n - 1));
18}
19
20} // namespace
21
22namespace ddc::detail {
23
24void distribute_blocks(
25 std::size_t nb_blocks,
26 std::span<DiscreteVectorElement const> const sizes,
27 std::span<DiscreteVectorElement> const nb_blocks_per_dim)
28{
29 assert(sizes.size() == nb_blocks_per_dim.size());
30
31 if (!is_power_of_2(nb_blocks)) {
32 throw std::runtime_error("DDC distribute_blocks expects a power of 2.");
33 }
34
35 for (DiscreteVectorElement& blocks : nb_blocks_per_dim) {
36 blocks = 1;
37 }
38
39 std::size_t dim = 0;
40 while (nb_blocks != 1) {
41 if (dim >= sizes.size()) {
42 throw std::runtime_error("DDC expects a smaller number of blocks.");
43 }
44
45 if (sizes[dim] >= nb_blocks_per_dim[dim] * 2) {
46 nb_blocks_per_dim[dim] *= 2;
47 nb_blocks /= 2;
48 } else {
49 ++dim;
50 }
51 }
52}
53
54ComputeBlockFn::ComputeBlockFn(
55 DiscreteVectorElement const extent,
56 DiscreteVectorElement const nb_blocks) noexcept
57 : m_quot(extent / nb_blocks)
58 , m_rem(extent % nb_blocks)
59{
60}
61
62DiscreteVectorElement ComputeBlockFn::operator()(DiscreteVectorElement const i) const noexcept
63{
64 if (i < m_rem) {
65 return m_quot + 1;
66 }
67 return m_quot;
68}
69
70} // namespace ddc::detail
The top-level namespace of DDC.