Skip to content

Commit

Permalink
[onert] Remove tensor layout check on permute function (#13766)
Browse files Browse the repository at this point in the history
This commit moves tensor layout check from permute function to permute layer constructor to prepare removing layout interface on tensor.

ONE-DCO-1.0-Signed-off-by: Hyeongseok Oh <[email protected]>
  • Loading branch information
hseok-oh authored Aug 27, 2024
1 parent f852aab commit 42a6f83
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 46 deletions.
37 changes: 20 additions & 17 deletions runtime/onert/core/src/backend/builtin/kernel/PermuteLayer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ PermuteLayer::PermuteLayer(const std::vector<ITensor *> &src_tensors,
_dst_tensors = dst_tensors;
_src_tensors_offsets.resize(src_tensors.size());
_dst_tensors_offsets.resize(dst_tensors.size());
_permute_types.resize(src_tensors.size());

// TODO Get from constructor parameter
for (uint32_t i = 0; i < src_tensors.size(); i++)
{
if (src_tensors[i]->layout() == dst_tensors[i]->layout())
_permute_types[i] = ir::PermuteType::COPY;
else if (src_tensors[i]->layout() == ir::Layout::NHWC)
_permute_types[i] = ir::PermuteType::NHWC_TO_NCHW;
else
_permute_types[i] = ir::PermuteType::NCHW_TO_NHWC;
}
}

void PermuteLayer::optimize()
Expand All @@ -48,6 +60,7 @@ void PermuteLayer::optimize()
auto dst_it = _dst_tensors.begin();
auto src_offsets_it = _src_tensors_offsets.begin();
auto dst_offsets_it = _dst_tensors_offsets.begin();
auto type_it = _permute_types.begin();
while (src_it != _src_tensors.end())
{
if ((*src_it == *dst_it) || (*src_it == nullptr || *dst_it == nullptr))
Expand All @@ -56,6 +69,7 @@ void PermuteLayer::optimize()
dst_it = _dst_tensors.erase(dst_it);
src_offsets_it = _src_tensors_offsets.erase(src_offsets_it);
dst_offsets_it = _dst_tensors_offsets.erase(dst_offsets_it);
type_it = _permute_types.erase(type_it);
}
else
{
Expand All @@ -65,22 +79,7 @@ void PermuteLayer::optimize()
dst_offsets_it->resize(0);
if (underlying_type(src->data_type()) != underlying_type(dst->data_type()))
continue;
const auto permute_type = [&]() -> ir::PermuteType {
if (src->getShape().rank() == 4 && src->layout() == ir::Layout::NHWC &&
dst->layout() == ir::Layout::NCHW)
{
return ir::PermuteType::NHWC_TO_NCHW;
}
else if (src->getShape().rank() == 4 && src->layout() == ir::Layout::NCHW &&
dst->layout() == ir::Layout::NHWC)
{
return ir::PermuteType::NCHW_TO_NHWC;
}
else
{
return ir::PermuteType::COPY;
}
}();
const auto permute_type = *type_it;

// TODO Support different types
auto fn = [&](backend::ITensor &src_tensor) {
Expand Down Expand Up @@ -139,6 +138,7 @@ void PermuteLayer::optimize()
dst_it++;
src_offsets_it++;
dst_offsets_it++;
type_it++;
}
}
}
Expand Down Expand Up @@ -243,12 +243,14 @@ void PermuteLayer::run()
auto dst_it = _dst_tensors.begin();
auto src_offsets_it = _src_tensors_offsets.begin();
auto dst_offsets_it = _dst_tensors_offsets.begin();
auto type_it = _permute_types.begin();
while (src_it != _src_tensors.end())
{
auto src = *src_it;
auto dst = *dst_it;
auto &src_offsets = *src_offsets_it;
auto &dst_offsets = *dst_offsets_it;
auto permute_type = *type_it;

if (src->total_size() == 0)
{
Expand All @@ -267,7 +269,7 @@ void PermuteLayer::run()
src->is_dynamic() || dst->is_dynamic() ||
underlying_type(src->data_type()) != underlying_type(dst->data_type()))
{
permute(src, dst, src->getShape().rank(), src_offsets, dst_offsets);
permute(src, dst, src->getShape().rank(), src_offsets, dst_offsets, permute_type);
}
// If dst is subtensor, we have to use clEnqueueMapBuffer instead of clEnqueueWirteBuffer
else if (dst->needMemoryMap() && !dst->is_subtensor())
Expand Down Expand Up @@ -307,6 +309,7 @@ void PermuteLayer::run()
dst_it++;
src_offsets_it++;
dst_offsets_it++;
type_it++;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ void PermuteLayer::backward()
const auto rank = src_back_prop->getShape().rank();
auto output_offsets = _dst_tensors_offsets.at(i);
auto input_offsets = _src_tensors_offsets.at(i);
auto permute_type = _permute_types.at(i);

exec::IPermuteFunction::permute(src_back_prop, dst_back_prop, rank, output_offsets,
input_offsets);
input_offsets, permute_type);
}
}
}
Expand Down
20 changes: 11 additions & 9 deletions runtime/onert/core/src/exec/IPermuteFunction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,19 @@ void IPermuteFunction::IPermuteFunction::run()
auto dst_tensor = _dst_tensors.at(i);
auto &src_offsets = _src_tensors_offsets.at(i);
auto &dst_offsets = _dst_tensors_offsets.at(i);
auto permute_type = _permute_types.at(i);
if (src_tensor != dst_tensor)
{
const auto rank = src_tensor->getShape().rank();
permute(src_tensor, dst_tensor, rank, src_offsets, dst_offsets);
permute(src_tensor, dst_tensor, rank, src_offsets, dst_offsets, permute_type);
}
}
}

void IPermuteFunction::permute(backend::ITensor *src_tensor, backend::ITensor *dst_tensor,
size_t rank, std::vector<size_t> &src_offsets,
std::vector<size_t> &dst_offsets)
std::vector<size_t> &dst_offsets,
const ir::PermuteType &permute_type)
{
if (src_tensor->total_size() == 0)
{
Expand All @@ -261,28 +263,28 @@ void IPermuteFunction::permute(backend::ITensor *src_tensor, backend::ITensor *d
switch (src_tensor->data_type())
{
case ir::DataType::FLOAT32:
permute<float>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets);
permute<float>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets, permute_type);
break;
case ir::DataType::INT32:
permute<int32_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets);
permute<int32_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets, permute_type);
break;
case ir::DataType::UINT32:
permute<uint32_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets);
permute<uint32_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets, permute_type);
break;
case ir::DataType::BOOL8:
case ir::DataType::QUANT_UINT8_ASYMM:
case ir::DataType::UINT8:
permute<uint8_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets);
permute<uint8_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets, permute_type);
break;
case ir::DataType::QUANT_INT8_ASYMM:
case ir::DataType::QUANT_INT8_SYMM:
permute<int8_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets);
permute<int8_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets, permute_type);
break;
case ir::DataType::INT64:
permute<int64_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets);
permute<int64_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets, permute_type);
break;
case ir::DataType::QUANT_INT16_SYMM:
permute<int16_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets);
permute<int16_t>(src_tensor, dst_tensor, rank, src_offsets, dst_offsets, permute_type);
break;
default:
throw std::runtime_error("IPermuteFunction: Not supported data type");
Expand Down
42 changes: 23 additions & 19 deletions runtime/onert/core/src/exec/IPermuteFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ class IPermuteFunction : public IFunction

protected:
void permute(backend::ITensor *src_tensor, backend::ITensor *dst_tensor, size_t rank,
std::vector<size_t> &src_offsets, std::vector<size_t> &dst_offsets);
std::vector<size_t> &src_offsets, std::vector<size_t> &dst_offsets,
const ir::PermuteType &permute_type);

private:
// TODO make src const by proving const access()
template <class T>
void permute(backend::ITensor *src, backend::ITensor *dst, size_t rank,
std::vector<size_t> &src_offsets, std::vector<size_t> &dst_offsets)
std::vector<size_t> &src_offsets, std::vector<size_t> &dst_offsets,
const ir::PermuteType &permute_type)
{
assert(src->total_size() != 0 && dst->total_size() != 0);
// If dst is subtensor, we have to use clEnqueueMapBuffer instead of clEnqueueWirteBuffer
Expand All @@ -101,7 +103,8 @@ class IPermuteFunction : public IFunction
_buffers_map[dst].reserve(dst->total_size());
auto dst_buffer = _buffers_map[dst].data();
src->access([&](backend::ITensor &) {
permute<T>(src, dst, rank, dst_buffer, dst->total_size(), src_offsets, dst_offsets);
permute<T>(src, dst, rank, dst_buffer, dst->total_size(), src_offsets, dst_offsets,
permute_type);
});
dst->enqueueWriteBuffer(dst_buffer, false);
}
Expand All @@ -116,7 +119,8 @@ class IPermuteFunction : public IFunction
{
auto fn = [&](backend::ITensor &) {
dst->access([&](backend::ITensor &) {
permute<T>(src, dst, rank, dst->buffer(), dst->total_size(), src_offsets, dst_offsets);
permute<T>(src, dst, rank, dst->buffer(), dst->total_size(), src_offsets, dst_offsets,
permute_type);
});
};
src->access(fn);
Expand All @@ -125,25 +129,12 @@ class IPermuteFunction : public IFunction

template <class T>
void permute(backend::ITensor *src, backend::ITensor *dst, size_t rank, uint8_t *dst_buffer,
size_t dst_size, std::vector<size_t> &src_offsets, std::vector<size_t> &dst_offsets)
size_t dst_size, std::vector<size_t> &src_offsets, std::vector<size_t> &dst_offsets,
const ir::PermuteType &permute_type)
{
assert(dst_buffer != nullptr);
assert(dst_size == dst->total_size());

const auto permute_type = [&]() -> ir::PermuteType {
if (src->layout() == ir::Layout::NHWC && dst->layout() == ir::Layout::NCHW)
{
return ir::PermuteType::NHWC_TO_NCHW;
}
else if (src->layout() == ir::Layout::NCHW && dst->layout() == ir::Layout::NHWC)
{
return ir::PermuteType::NCHW_TO_NHWC;
}
else
{
return ir::PermuteType::COPY;
}
}();
if (rank == 4 && permute_type != ir::PermuteType::COPY)
{
switch (permute_type)
Expand Down Expand Up @@ -252,6 +243,7 @@ class IPermuteFunction : public IFunction
std::vector<backend::ITensor *> _dst_tensors;
std::vector<std::vector<size_t>> _src_tensors_offsets;
std::vector<std::vector<size_t>> _dst_tensors_offsets;
std::vector<ir::PermuteType> _permute_types;
std::unordered_map<const backend::ITensor *, std::vector<uint8_t>> _buffers_map;
};

Expand All @@ -265,6 +257,18 @@ class PermuteLayer : public onert::exec::IPermuteFunction
assert(inputs.size() == outputs.size());
_src_tensors = inputs;
_dst_tensors = outputs;
_permute_types.resize(inputs.size());

// TODO Get from constructor parameter
for (uint32_t i = 0; i < inputs.size(); i++)
{
if (inputs[i]->layout() == outputs[i]->layout())
_permute_types[i] = ir::PermuteType::COPY;
else if (inputs[i]->layout() == ir::Layout::NHWC)
_permute_types[i] = ir::PermuteType::NHWC_TO_NCHW;
else
_permute_types[i] = ir::PermuteType::NCHW_TO_NHWC;
}
}
virtual ~PermuteLayer() {}
void optimize() override {}
Expand Down
11 changes: 11 additions & 0 deletions runtime/onert/core/src/exec/IPermuteFunction.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ class MockUpLayer : public IPermuteFunction
assert(inputs.size() == outputs.size());
_src_tensors = inputs;
_dst_tensors = outputs;
_permute_types.resize(inputs.size());

for (uint32_t i = 0; i < inputs.size(); i++)
{
if (inputs[i]->layout() == outputs[i]->layout())
_permute_types[i] = ir::PermuteType::COPY;
else if (inputs[i]->layout() == ir::Layout::NHWC)
_permute_types[i] = ir::PermuteType::NHWC_TO_NCHW;
else
_permute_types[i] = ir::PermuteType::NCHW_TO_NHWC;
}
}
virtual ~MockUpLayer() {}
void optimize() override {}
Expand Down

0 comments on commit 42a6f83

Please sign in to comment.