[kbenchmark] Add operation class for loading operation info (#5359)
author윤지영/On-Device Lab(SR)/Staff Engineer/삼성전자 <jy910.yun@samsung.com>
Tue, 25 Jun 2019 02:01:05 +0000 (11:01 +0900)
committer이춘석/On-Device Lab(SR)/Staff Engineer/삼성전자 <chunseok.lee@samsung.com>
Tue, 25 Jun 2019 02:01:05 +0000 (11:01 +0900)
This patch loads operation informations from config file.
And it executes kernel benchmark test using the operation info.
The result is stored by default in text file.

Signed-off-by: Jiyoung Yun <jy910.yun@samsung.com>
tools/kbenchmark/Driver.cc
tools/kbenchmark/Operation.h [new file with mode: 0644]
tools/kbenchmark/OperationLoader.h [new file with mode: 0644]
tools/kbenchmark/Operations.lst [new file with mode: 0644]
tools/kbenchmark/README.md
tools/kbenchmark/Utils.h [new file with mode: 0644]
tools/kbenchmark/operations/Convolution.h [new file with mode: 0644]

index 8f34ce2..8d9e6b7 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "Args.h"
 #include "ConfigFile.h"
+#include "OperationLoader.h"
 
 #include <nonius/nonius.h++>
 
@@ -105,11 +106,22 @@ int main(int argc, char *argv[])
   // Create ConfigFile object from config file
   ConfigFile cf(args.config());
 
-  for (auto &c : cf)
+  // Get OperationLoader instance
+  OperationLoader &opl = OperationLoader::getInstance();
+
+  if (!opl.is_valid(cf.name()))
+  {
+    std::cerr << cf.name() << " is not valid operation" << std::endl;
+  }
+  else
   {
-    // TODO Update nonius benchmark parameters
+    for (auto &c : cf)
+    {
+      nonius::parameters op_params = opl[cf.name()]->params(c.second);
+      cfg.params.map = cfg.params.map.merged(op_params);
 
-    nonius::go(cfg, benchmarks);
+      nonius::go(cfg, benchmarks);
+    }
   }
 
   // Release kernel library
diff --git a/tools/kbenchmark/Operation.h b/tools/kbenchmark/Operation.h
new file mode 100644 (file)
index 0000000..386f08a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __KBENCHMARK_OPERATION_H__
+#define __KBENCHMARK_OPERATION_H__
+
+#include <nonius/param.h++>
+
+#include "ConfigFile.h"
+
+namespace kbenchmark
+{
+
+class Operation
+{
+public:
+  Operation() = default;
+
+  virtual nonius::parameters params(OperationInfo &info) = 0;
+};
+
+} // namespace kbenchmark
+
+#endif // __KBENCHMARK_OPERATION_H__
diff --git a/tools/kbenchmark/OperationLoader.h b/tools/kbenchmark/OperationLoader.h
new file mode 100644 (file)
index 0000000..701033d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __KBENCHMARK_OPERATION_LOADER_H__
+#define __KBENCHMARK_OPERATION_LOADER_H__
+
+#include <string>
+#include <unordered_map>
+
+#include "Operation.h"
+#include "operations/Convolution.h"
+
+namespace kbenchmark
+{
+
+class OperationLoader
+{
+public:
+  static OperationLoader &getInstance(void)
+  {
+    static OperationLoader instance;
+    return instance;
+  }
+
+  Operation *operator[](const std::string &name) { return _map[name]; }
+  bool is_valid(const std::string &name) { return _map.count(name); }
+
+private:
+  OperationLoader(void)
+  {
+#define OP(ConfigName, OperationName) _map[ConfigName] = new operation::OperationName();
+#include "Operations.lst"
+#undef OP
+  }
+
+  ~OperationLoader() = default;
+  OperationLoader(const OperationLoader &) = delete;
+  OperationLoader &operator=(const OperationLoader &) = delete;
+
+private:
+  std::unordered_map<std::string, Operation *> _map;
+};
+
+} // namespace kbenchmark
+
+#endif // __KBENCHMARK_OPERATION_LOADER_H__
diff --git a/tools/kbenchmark/Operations.lst b/tools/kbenchmark/Operations.lst
new file mode 100644 (file)
index 0000000..1ebdab1
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OP
+#error  Define OP before including this file
+#endif
+
+// Config Name        Operation Name
+OP("CONV_2D",         Convolution)
index 2eb1088..45e4970 100644 (file)
@@ -76,3 +76,6 @@ and the following optional parameters:
 * `verbose`: \
   Show verbose messages.
 
+### Operations
+The `OperationLoader` loads each operation information from configuration file. This loader takes the last string of the configuration file name as a key of `OperationLoader` map. So the configuration file should not be changed. For example, if the configuration file name is a `inceptionv3_slim_Main_model_CONV_2D.test.config`, the `OperationLoader` takes `CONV_2D` as a key of map. The `CONV_2D` key is connected to `Convolution` class in `operations/Convolution.h`. This related information is described in `Operations.lst` file. Each operation class will return the `nonius::parameters` from `OperationInfo` in `ConfigFile` class.
+
diff --git a/tools/kbenchmark/Utils.h b/tools/kbenchmark/Utils.h
new file mode 100644 (file)
index 0000000..cda6c32
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __KBENCHMARK_UTILS_H__
+#define __KBENCHMARK_UTILS_H__
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <cassert>
+
+namespace kbenchmark
+{
+
+void check_valid_key(const std::string &key, OperationInfo &info)
+{
+  OperationInfo::const_iterator it;
+  it = info.find(key);
+  assert(it != info.end());
+}
+
+std::vector<int> dims(const std::string &src)
+{
+  std::vector<int> dim;
+
+  std::stringstream ss(src);
+  int i;
+  while (ss >> i)
+  {
+    dim.push_back(i);
+    if (ss.peek() == ',')
+      ss.ignore();
+  }
+  return dim;
+}
+
+std::vector<int> get_key_dims(const std::string &key, OperationInfo &info)
+{
+  check_valid_key(key, info);
+  return dims(info[key]);
+}
+
+int get_key_int(const std::string &key, OperationInfo &info)
+{
+  check_valid_key(key, info);
+  return std::stoi(info[key]);
+}
+
+std::string get_key_string(const std::string &key, OperationInfo &info)
+{
+  check_valid_key(key, info);
+  return info[key];
+}
+
+} // namespace kbenchmark
+
+#endif // __KBENCHMARK_UTILS_H__
diff --git a/tools/kbenchmark/operations/Convolution.h b/tools/kbenchmark/operations/Convolution.h
new file mode 100644 (file)
index 0000000..2f3b60b
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __KBENCHMARK_OPERATIONS_CONVOLUTION_H__
+#define __KBENCHMARK_OPERATIONS_CONVOLUTION_H__
+
+#include "Operation.h"
+#include "Utils.h"
+
+namespace kbenchmark
+{
+namespace operation
+{
+
+class Convolution final : public Operation
+{
+public:
+  Convolution() = default;
+
+  nonius::parameters params(OperationInfo &info) override
+  {
+    nonius::parameters params;
+
+    params.insert({"BATCH", nonius::param{1}});
+
+    auto _input = get_key_dims({"input"}, info);
+    params.insert({"IFM_C", nonius::param{_input[3]}});
+    params.insert({"IFM_H", nonius::param{_input[1]}});
+    params.insert({"IFM_W", nonius::param{_input[2]}});
+
+    auto _output0 = get_key_dims({"output0"}, info);
+    params.insert({"OFM_C", nonius::param{_output0[3]}});
+    params.insert({"OFM_H", nonius::param{_output0[1]}});
+    params.insert({"OFM_W", nonius::param{_output0[2]}});
+
+    auto _weights = get_key_dims({"weights"}, info);
+    params.insert({"KER_H", nonius::param{_weights[1]}});
+    params.insert({"KER_W", nonius::param{_weights[2]}});
+
+    auto _stride_h = get_key_int({"stride_h"}, info);
+    auto _stride_w = get_key_int({"stride_w"}, info);
+    params.insert({"STRIDE_H", nonius::param{_stride_h}});
+    params.insert({"STRIDE_W", nonius::param{_stride_w}});
+
+    auto _pad = get_key_string({"padding"}, info);
+    params.insert({"PADDING", nonius::param{_pad}});
+
+    auto _act = get_key_string({"fused_act"}, info);
+    params.insert({"FUSED_ACT", nonius::param{_act}});
+
+    return params;
+  }
+};
+
+} // namespace operation
+} // namespace kbenchmark
+
+#endif // __KBENCHMARK_OPERATIONS_CONVOLUTION_H__