#include "gpu/intel/block_structure.hpp"
namespace dnnl {
namespace impl {
namespace gpu {
namespace intel {
block_layout_t block_layout_t::normalized(bool remove_size_1_blocks) const {
if (num_blocks == 0) return block_layout_t();
block_layout_t res;
std::vector<block_t> block_vec(num_blocks);
memcpy(&block_vec[0], &blocks[0], num_blocks * sizeof(block_t));
std::vector<block_t> new_blocks
= normalize_blocks(block_vec, remove_size_1_blocks);
for (const block_t &block : new_blocks) {
res.append(block);
}
return res;
}
std::vector<block_t> normalize_blocks(
const std::vector<block_t> &blocks, bool remove_size_1_blocks) {
if (blocks.empty()) return {};
std::vector<block_t> res;
for (const block_t &block : blocks) {
if (remove_size_1_blocks && block.block == 1) continue;
if (!res.empty() && res.back().can_merge(block)) {
res.back().block *= block.block;
} else {
res.emplace_back(block);
}
}
return res;
}
block_layout_t::block_layout_t(
const memory_desc_wrapper &mdw, bool inner_only, bool do_normalize) {
if (mdw.format_kind() == format_kind::undef) return;
const dim_idx_t ndims = into<uint32_t>(mdw.ndims());
auto &blocking = mdw.blocking_desc();
auto *padded_dims = mdw.padded_dims();
dim_t stride = 1;
std::vector<dim_t> full_blocks(ndims, 1);
for (int i = blocking.inner_nblks - 1; i >= 0; i--) {
dim_idx_t dim_idx = into<uint32_t>(blocking.inner_idxs[i]);
dim_t block = blocking.inner_blks[i];
append(block_t(dim_idx, block, stride));
stride *= block;
full_blocks[dim_idx] *= block;
}
if (!inner_only) {
for (dim_idx_t i = 0; i < ndims; i++) {
dim_t block = padded_dims[i] / full_blocks[i];
append(block_t(i, block, blocking.strides[i]));
}
std::sort(begin() + blocking.inner_nblks, end(),
[](const block_t &a, const block_t &b) {
return a.stride < b.stride
|| (a.stride == b.stride && a.block < b.block);
});
}
if (do_normalize) *this = normalized();
}
block_layout_t get_inner_layout(const memory_desc_wrapper &md) {
block_layout_t inner_layout(md, true);
block_layout_t ret;
for (int d = 0; d < MAX_NDIMS; d++) {
ret.append(block_t(d, 1, 0));
}
for (const auto &block : inner_layout) {
ret[block.dim_idx] = block;
}
return ret;
}
} } } }