Introduce IndexIterator (for feature) (#428)
author박종현/동작제어Lab(SR)/Senior Engineer/삼성전자 <jh1302.park@samsung.com>
Thu, 5 Apr 2018 02:13:17 +0000 (11:13 +0900)
committer서상민/동작제어Lab(SR)/Senior Engineer/삼성전자 <sangmin7.seo@samsung.com>
Thu, 5 Apr 2018 02:13:17 +0000 (11:13 +0900)
This commit introduces IndexIterator class and relevent helpers in
nnfw::util::feature namespace to make it easy to iterate over feature
elements.

This commit includes updates on NNAPI Conv1 Unittest to demonstrate how
to use these helpers.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
include/util/feature/IndexIterator.h [new file with mode: 0644]
tools/nnapi_unittests/tests/conv_1.cpp

diff --git a/include/util/feature/IndexIterator.h b/include/util/feature/IndexIterator.h
new file mode 100644 (file)
index 0000000..07093c0
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __NNFW_UTIL_FEATURE_INDEX_ITERATOR_H__
+#define __NNFW_UTIL_FEATURE_INDEX_ITERATOR_H__
+
+#include "util/feature/Shape.h"
+
+namespace nnfw
+{
+namespace util
+{
+namespace feature
+{
+
+class IndexIterator
+{
+public:
+  IndexIterator(const Shape &shape) : _shape{shape}
+  {
+    // DO NOTHING
+  }
+
+public:
+  template <typename Callable> IndexIterator &iter(Callable cb)
+  {
+    for (uint32_t ch = 0; ch < _shape.C; ++ch)
+    {
+      for (uint32_t row = 0; row < _shape.H; ++row)
+      {
+        for (uint32_t col = 0; col < _shape.W; ++col)
+        {
+          cb(ch, row, col);
+        }
+      }
+    }
+
+    return (*this);
+  }
+
+private:
+  const Shape _shape;
+};
+
+IndexIterator iterate(const Shape &shape) { return IndexIterator{shape}; }
+
+template <typename Callable> IndexIterator &operator<<(IndexIterator &&it, Callable cb)
+{
+  return it.iter(cb);
+}
+
+} // namespace feature
+} // namespace util
+} // namespace nnfw
+
+#endif // __NNFW_UTIL_FEATURE_INDEX_ITERATOR_H__
index 378fe01..dcd5cf8 100644 (file)
@@ -5,6 +5,7 @@
 #include "env.h"
 
 #include "util/vector/Object.h"
+#include "util/feature/IndexIterator.h"
 #include "util/feature/RandomObject.h"
 #include "util/feature/Reader.h"
 #include "util/kernel/RandomObject.h"
@@ -338,27 +339,23 @@ int main(int argc, char **argv)
     const TfLiteFeatureView<float> interp_output{pure, TfLiteOutputIndex{0}};
     const TfLiteFeatureView<float> nnapi_output{delegated, TfLiteOutputIndex{0}};
 
-    for (uint32_t row = 0; row < OFM_H; ++row)
+    const nnfw::util::feature::Shape ofm_shape{OFM_C, OFM_H, OFM_W};
+
+    nnfw::util::feature::iterate(ofm_shape) << [&] (uint32_t ch, uint32_t row, uint32_t col)
     {
-      for (uint32_t col = 0; col < OFM_W; ++col)
-      {
-        for (uint32_t ch = 0; ch < kernel.shape().N; ++ch)
-        {
-          const auto value_from_interp = interp_output.at(ch, row, col);
-          const auto value_from_NNAPI = nnapi_output.at(ch, row, col);
+      const auto value_from_interp = interp_output.at(ch, row, col);
+      const auto value_from_NNAPI = nnapi_output.at(ch, row, col);
 
-          if (!nnfw::util::fp32::epsilon_equal(value_from_interp, value_from_NNAPI))
-          {
-            const auto rdiff = nnfw::util::fp32::relative_diff(value_from_interp, value_from_NNAPI);
+      if (!nnfw::util::fp32::epsilon_equal(value_from_interp, value_from_NNAPI))
+      {
+        const auto rdiff = nnfw::util::fp32::relative_diff(value_from_interp, value_from_NNAPI);
 
-            std::cerr << "Diff at (ch: " << ch << ", row: " << row << ", col: " << col << ")" << std::endl;
-            std::cerr << "  Value from interpreter: " << value_from_interp << std::endl;
-            std::cerr << "  Value from NNAPI: " << value_from_NNAPI << std::endl;
-            std::cerr << "  Relative difference: " << rdiff << std::endl;
-          }
-        }
+        std::cerr << "Diff at (ch: " << ch << ", row: " << row << ", col: " << col << ")" << std::endl;
+        std::cerr << "  Value from interpreter: " << value_from_interp << std::endl;
+        std::cerr << "  Value from NNAPI: " << value_from_NNAPI << std::endl;
+        std::cerr << "  Relative difference: " << rdiff << std::endl;
       }
-    }
+    };
   }
 
   return 0;