{
return model::Shape{shape.dim(0), shape.dim(1), shape.dim(2), shape.dim(3)};
}
- else if (frontend_layout == kernel::FilterLayout::OHWI &&
- backend_layout == kernel::FilterLayout::HWOI)
- {
- return model::Shape{shape.dim(1), shape.dim(2), shape.dim(0), shape.dim(3)};
- }
- else if (frontend_layout == kernel::FilterLayout::OHWI &&
- backend_layout == kernel::FilterLayout::OIHW)
- {
- return model::Shape{shape.dim(0), shape.dim(3), shape.dim(1), shape.dim(2)};
- }
- else if (frontend_layout == kernel::FilterLayout::OIHW &&
- backend_layout == kernel::FilterLayout::HWOI)
- {
- return model::Shape{shape.dim(2), shape.dim(3), shape.dim(0), shape.dim(1)};
- }
- else if (frontend_layout == kernel::FilterLayout::OIHW &&
- backend_layout == kernel::FilterLayout::OHWI)
- {
- return model::Shape{shape.dim(0), shape.dim(2), shape.dim(3), shape.dim(1)};
- }
- else
+
+ const auto permutation = getFilterPermutation(frontend_layout, backend_layout);
+ if (permutation.size() == 0)
{
throw std::runtime_error("Not supported FilterLayout");
}
+ return model::Shape{shape.dim(permutation[0]), shape.dim(permutation[1]),
+ shape.dim(permutation[2]), shape.dim(permutation[3])};
}
model::Shape asTensorShape(const model::Shape &shape, model::Layout frontend_layout,
#include <cmath>
#include <algorithm>
#include <cassert>
+#include <map>
#include "util/Utils.h"
return descr1.dimensions[index1];
}
-Coordinates convertCoordinates(const Coordinates &from_coordinates, FilterLayout from_layout,
- FilterLayout to_layout)
+std::vector<int32_t> getFilterPermutation(FilterLayout from_layout, FilterLayout to_layout)
{
- assert(from_coordinates.size() == 4);
- Coordinates to{from_coordinates};
- if (from_layout == to_layout)
- {
- return Coordinates{from_coordinates};
- }
- else if (from_layout == FilterLayout::OHWI && to_layout == FilterLayout::HWOI)
- {
- return Coordinates{from_coordinates[1], from_coordinates[2], from_coordinates[0],
- from_coordinates[3]};
- }
- else if (from_layout == FilterLayout::OHWI && to_layout == FilterLayout::OIHW)
- {
- return Coordinates{from_coordinates[0], from_coordinates[3], from_coordinates[1],
- from_coordinates[2]};
- }
- else if (from_layout == FilterLayout::OIHW && to_layout == FilterLayout::HWOI)
+ static std::map<std::pair<FilterLayout, FilterLayout>, std::vector<int32_t>> filter_permutation =
+ {{std::make_pair(FilterLayout::OHWI, FilterLayout::HWOI), {1, 2, 0, 3}},
+ {std::make_pair(FilterLayout::OHWI, FilterLayout::HWIO), {1, 2, 3, 0}},
+ {std::make_pair(FilterLayout::OHWI, FilterLayout::OIHW), {0, 3, 1, 2}},
+ {std::make_pair(FilterLayout::OHWI, FilterLayout::IOHW), {3, 0, 1, 2}},
+ {std::make_pair(FilterLayout::OIHW, FilterLayout::HWOI), {2, 3, 0, 1}},
+ {std::make_pair(FilterLayout::OIHW, FilterLayout::HWIO), {2, 3, 1, 0}},
+ {std::make_pair(FilterLayout::OIHW, FilterLayout::OHWI), {0, 2, 3, 1}},
+ {std::make_pair(FilterLayout::OIHW, FilterLayout::IOHW), {1, 0, 2, 3}}};
+
+ const auto pair = std::make_pair(from_layout, to_layout);
+ const auto it = filter_permutation.find(pair);
+ if (it == filter_permutation.end())
{
- return Coordinates{from_coordinates[2], from_coordinates[3], from_coordinates[0],
- from_coordinates[1]};
+ return std::vector<int32_t>{};
}
- else if (from_layout == FilterLayout::OIHW && to_layout == FilterLayout::OHWI)
+ return it->second;
+}
+
+Coordinates convertCoordinates(const Coordinates &coordinates, FilterLayout from_layout,
+ FilterLayout to_layout)
+{
+ assert(coordinates.size() == 4);
+ if (from_layout == to_layout)
{
- return Coordinates{from_coordinates[0], from_coordinates[2], from_coordinates[3],
- from_coordinates[1]};
+ return coordinates;
}
- else
+
+ const auto permutation = getFilterPermutation(from_layout, to_layout);
+ if (permutation.size() == 0)
{
- throw std::runtime_error{"Not supported FilterLayout"};
+ throw std::runtime_error("Not supported FilterLayout");
}
+ return Coordinates{coordinates[permutation[0]], coordinates[permutation[1]],
+ coordinates[permutation[2]], coordinates[permutation[3]]};
}
TensorDescriptor getTensorDescriptor(const ::neurun::model::Operand &o,
{
OHWI = 0, // TfLite Kernel Layout when using NHWC image layout
HWOI, // SRCN Transpose Conv Kernel Layout when using NHWC image layout
- OIHW, // SRCN Transpose Conv Kernel Layout when using NCHW image layout
+ OIHW, // SRCN Conv Kernel Layout when using NCHW image layout
+ HWIO, // SRCN Conv Kernel Layout when using NHWC image layout
+ IOHW, // SRCN Transpose Conv Kernel Layout when using NCHW image layout
};
uint32_t MatchingDim(const TensorDescriptor &shape1, int index1, const TensorDescriptor &shape2,
int index2);
+std::vector<int32_t> getFilterPermutation(FilterLayout from_layout, FilterLayout to_layout);
+
Coordinates convertCoordinates(const Coordinates &from_coordinates, FilterLayout from_layout,
FilterLayout to_layout);