[custom op] Update custom kernel registry to use C api version (#6288)
authorVladimir Plazun/AI Tools Lab /SRR/Engineer/삼성전자 <v.plazun@samsung.com>
Wed, 4 Sep 2019 06:16:46 +0000 (09:16 +0300)
committer이춘석/On-Device Lab(SR)/Staff Engineer/삼성전자 <chunseok.lee@samsung.com>
Wed, 4 Sep 2019 06:16:46 +0000 (15:16 +0900)
* [custom op] Update custom kernel registry to use C api version

Split custom kernel and kernel registry into separate files
Now custom kernel uses api types
Link neurun core library with API headers

* update with latest changes to #6219

* Update kernel registry with changes to api. Link neurun core with nnfw-header

* add missed license

Signed-off-by: Vladimir Plazun <v.plazun@samsung.com>
runtimes/neurun/core/CMakeLists.txt
runtimes/neurun/core/include/backend/CustomKernel.h [new file with mode: 0644]
runtimes/neurun/core/include/backend/CustomKernelRegistry.h
runtimes/neurun/core/src/backend/CustomKernel.cc [new file with mode: 0644]
runtimes/neurun/core/src/backend/CustomKernelRegistry.cc

index f4906ee..56f1134 100644 (file)
@@ -10,3 +10,5 @@ target_link_libraries(neurun_core PRIVATE nnfw_lib_cker)
 target_link_libraries(neurun_core PRIVATE nnfw_common)
 target_link_libraries(neurun_core PRIVATE nnfw_coverage)
 target_link_libraries(neurun_core PRIVATE dl)
+
+target_link_libraries(neurun_core PUBLIC nnfw-header) # To be removed later
diff --git a/runtimes/neurun/core/include/backend/CustomKernel.h b/runtimes/neurun/core/include/backend/CustomKernel.h
new file mode 100644 (file)
index 0000000..4be7847
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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 __NEURUN_BACKEND_CUSTOM_KERNEL_H__
+#define __NEURUN_BACKEND_CUSTOM_KERNEL_H__
+
+#include "nnfw_dev.h"
+
+#include "exec/IFunction.h"
+
+#include "misc/tensor/Shape.h"
+#include "model/DataType.h"
+
+#include <vector>
+
+namespace neurun
+{
+namespace backend
+{
+namespace custom
+{
+
+using Shape = nnfw::misc::tensor::Shape;
+
+struct TypeInfo
+{
+  Shape shape;
+  model::DataType dtype;
+};
+
+class Kernel : public ::neurun::exec::IFunction
+{
+public:
+  explicit Kernel(nnfw_custom_eval evalFunction);
+
+  nnfw_custom_kernel_params _params;
+  void *_userdata;
+
+  nnfw_custom_eval _evalFunction;
+  // nnfw_custom_type_infer _type_infer_function; //Unused for now
+
+  struct CustomKernelConfigParams
+  {
+    std::vector<void *> input_allocations;
+    std::vector<TypeInfo> input_types;
+
+    std::vector<void *> output_allocations;
+    std::vector<TypeInfo> output_types;
+
+    void *userdata;
+  };
+
+  /**
+   * Fills _params field used later by user specified eval function
+   * @param inParams custom kernel parameters
+   */
+  virtual void configure(CustomKernelConfigParams &&inParams);
+
+  void run() override;
+  void runSync() override { run(); }
+};
+
+} // namespace custom
+} // namespace backend
+} // namespace neurun
+
+#endif // __NEURUN_BACKEND_CUSTOM_KERNEL_H__
index eaac9d1..3eb218e 100644 (file)
 #ifndef __NEURUN_BACKEND_CUSTOM_KERNEL_REGISTRY_H__
 #define __NEURUN_BACKEND_CUSTOM_KERNEL_REGISTRY_H__
 
-#include "exec/IFunction.h"
-#include "misc/tensor/Shape.h"
-
-#include "model/OperandIndexSequence.h"
-#include "model/DataType.h"
+#include "CustomKernel.h"
 
 #include <unordered_map>
 #include <functional>
@@ -36,44 +32,15 @@ namespace backend
 
 namespace custom
 {
-using Shape = nnfw::misc::tensor::Shape;
-
-struct TypeInfo
-{
-  Shape shape;
-  model::DataType dtype;
-};
 
 class KernelRegistry
 {
 public:
-  class Kernel : public ::neurun::exec::IFunction
-  {
-  public:
-    struct Params
-    {
-      std::vector<custom::TypeInfo> input_types;
-      std::vector<custom::TypeInfo> output_types;
-
-      std::vector<uint8_t *> output_allocations;
-      std::vector<uint8_t *> input_allocations;
-
-      void *custom_data;
-    };
-
-    virtual void configure(Params &&options) = 0;
-  };
-
-  using FactoryFunction = std::function<std::unique_ptr<Kernel>(void)>;
-
-  void registerKernelFactory(size_t opId, FactoryFunction &&f);
-
-  std::unique_ptr<Kernel> buildKernelForOp(size_t opId);
+  void registerKernel(const std::string &id, nnfw_custom_eval evalFunction);
+  std::unique_ptr<Kernel> buildKernelForOp(const std::string &id);
 
 private:
-  const FactoryFunction &getKernelFactory(size_t opId);
-
-  std::unordered_map<size_t, FactoryFunction> _storage;
+  std::unordered_map<std::string, nnfw_custom_eval> _storage;
 };
 
 } // namespace custom
diff --git a/runtimes/neurun/core/src/backend/CustomKernel.cc b/runtimes/neurun/core/src/backend/CustomKernel.cc
new file mode 100644 (file)
index 0000000..76de8d4
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+#include "backend/CustomKernel.h"
+
+namespace neurun
+{
+namespace backend
+{
+namespace custom
+{
+
+// TODO move this elsewhere
+class APIConverter
+{
+public:
+  static nnfw_operand convertOperand(void *alloc, const TypeInfo &type)
+  {
+    nnfw_operand api_operand;
+    api_operand.allocation = alloc;
+    api_operand.type = convertType(type);
+    return api_operand;
+  }
+
+  static nnfw_tensorinfo convertType(const TypeInfo &type)
+  {
+    nnfw_tensorinfo api_type;
+    api_type.rank = type.shape.rank();
+    assert(type.shape.rank() <= 6);
+    std::copy(type.shape.dims().begin(), type.shape.dims().end(), std::begin(api_type.dims));
+
+    switch (type.dtype)
+    {
+      case model::DataType::FLOAT32:
+        api_type.dtype = NNFW_TYPE_TENSOR_FLOAT32;
+        break;
+      case model::DataType::INT32:
+        api_type.dtype = NNFW_TYPE_TENSOR_INT32;
+        break;
+      case model::DataType::QUANT8_ASYMM:
+        api_type.dtype = NNFW_TYPE_TENSOR_QUANT8_ASYMM;
+        break;
+      case model::DataType::BOOL8:
+        api_type.dtype = NNFW_TYPE_TENSOR_BOOL;
+        break;
+      default:
+        throw std::runtime_error("Unsupported tensor datatype");
+    }
+    return api_type;
+  }
+};
+
+Kernel::Kernel(const nnfw_custom_eval evalFunction) : _evalFunction(evalFunction) {}
+
+void Kernel::configure(Kernel::CustomKernelConfigParams &&inParams)
+{
+  _userdata = inParams.userdata;
+
+  _params.ninputs = inParams.input_allocations.size();
+  _params.inputs = new nnfw_operand[_params.ninputs];
+  for (size_t i = 0; i < _params.ninputs; ++i)
+  {
+    _params.inputs[i] =
+        APIConverter::convertOperand(inParams.input_allocations[i], inParams.input_types[i]);
+  }
+
+  _params.noutputs = inParams.output_allocations.size();
+  _params.outputs = new nnfw_operand[_params.noutputs];
+  for (size_t i = 0; i < _params.noutputs; ++i)
+  {
+    _params.outputs[i] =
+        APIConverter::convertOperand(inParams.output_allocations[i], inParams.output_types[i]);
+  }
+}
+
+void Kernel::run() { _evalFunction(&_params, _userdata); }
+
+} // namespace custom
+} // namespace backend
+} // namespace neurun
index 665ba69..4acab70 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "backend/CustomKernelRegistry.h"
 
+#include "cpp14/memory.h"
+
 namespace neurun
 {
 namespace backend
@@ -23,27 +25,20 @@ namespace backend
 namespace custom
 {
 
-void KernelRegistry::registerKernelFactory(size_t opId, KernelRegistry::FactoryFunction &&f)
-{
-  _storage.emplace(opId, std::move(f));
-}
-
-std::unique_ptr<KernelRegistry::Kernel> KernelRegistry::buildKernelForOp(size_t opId)
+void KernelRegistry::registerKernel(const std::string &id, nnfw_custom_eval evalFunction)
 {
-  return getKernelFactory(opId)();
+  _storage.emplace(id, evalFunction);
 }
 
-const KernelRegistry::FactoryFunction &KernelRegistry::getKernelFactory(size_t opId)
+std::unique_ptr<Kernel> KernelRegistry::buildKernelForOp(const std::string &id)
 {
-  auto it = _storage.find(opId);
-  if (it != _storage.end())
-  {
-    return it->second;
-  }
-  else
+  auto it = _storage.find(id);
+  if (it == _storage.end())
   {
     throw std::runtime_error("Unable to find associated kernel for op");
   }
+
+  return nnfw::cpp14::make_unique<custom::Kernel>(it->second);
 }
 
 } // namespace custom