Introduce HWIO and IOHW (#8785)
author장지섭/On-Device Lab(SR)/Engineer/삼성전자 <jiseob.jang@samsung.com>
Wed, 6 Nov 2019 05:51:07 +0000 (14:51 +0900)
committer이한종/On-Device Lab(SR)/Engineer/삼성전자 <hanjoung.lee@samsung.com>
Wed, 6 Nov 2019 05:51:07 +0000 (14:51 +0900)
* Introduce a kernel layout as HWIO into srcn backend

This commit instroduces a kernel layout as HWIO into srcn backend.

Signed-off-by: jiseob.jang <jiseob.jang@samsung.com>
* Introduce a kernel layout as IOHW into srcn backend

This commit introduces a kernel layout as HWIO into srcn backend.

Signed-off-by: jiseob.jang <jiseob.jang@samsung.com>
* Introduce getFilterPermutation into ncnn

This commit introduces getFilterPermutation into ncnn.

Signed-off-by: jiseob.jang <jiseob.jang@samsung.com>
runtime/neurun/backend/srcn/Convert.cc
runtime/neurun/backend/srcn/kernel/OperationUtils.cc
runtime/neurun/backend/srcn/kernel/OperationUtils.h

index 76beb38..8f3f82a 100644 (file)
@@ -37,30 +37,14 @@ model::Shape asKernelShape(const model::Shape &shape, kernel::FilterLayout front
   {
     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,
index b3ed8bd..56ac525 100644 (file)
@@ -19,6 +19,7 @@
 #include <cmath>
 #include <algorithm>
 #include <cassert>
+#include <map>
 
 #include "util/Utils.h"
 
@@ -40,39 +41,43 @@ uint32_t MatchingDim(const TensorDescriptor &descr1, int index1, const TensorDes
   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,
index ce676cd..c10be46 100644 (file)
@@ -57,12 +57,16 @@ enum FilterLayout
 {
   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);