summaryrefslogtreecommitdiff
path: root/runtime/neurun/api
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/neurun/api')
-rw-r--r--runtime/neurun/api/CMakeLists.txt21
-rw-r--r--runtime/neurun/api/include/nnfw.h378
-rw-r--r--runtime/neurun/api/include/nnfw_debug.h24
-rw-r--r--runtime/neurun/api/include/nnfw_dev.h65
-rw-r--r--runtime/neurun/api/src/CustomKernel.cc98
-rw-r--r--runtime/neurun/api/src/CustomKernel.h59
-rw-r--r--runtime/neurun/api/src/CustomKernelRegistry.cc64
-rw-r--r--runtime/neurun/api/src/CustomKernelRegistry.h64
-rw-r--r--runtime/neurun/api/src/OpMap.lst89
-rw-r--r--runtime/neurun/api/src/nnfw_api.cc267
-rw-r--r--runtime/neurun/api/src/nnfw_api_internal.cc435
-rw-r--r--runtime/neurun/api/src/nnfw_api_internal.h84
-rw-r--r--runtime/neurun/api/src/nnfw_debug.cc24
-rw-r--r--runtime/neurun/api/src/nnfw_debug_internal.cc25
-rw-r--r--runtime/neurun/api/src/nnfw_debug_internal.h29
15 files changed, 1726 insertions, 0 deletions
diff --git a/runtime/neurun/api/CMakeLists.txt b/runtime/neurun/api/CMakeLists.txt
new file mode 100644
index 000000000..c3f7702ad
--- /dev/null
+++ b/runtime/neurun/api/CMakeLists.txt
@@ -0,0 +1,21 @@
+file(GLOB_RECURSE API_SRC "*.cc")
+
+set(NEURUN_DEV nnfw-dev)
+add_library(${NEURUN_DEV} SHARED ${API_SRC})
+
+# Public headers to publish
+# nnfw_debug.h is header for runtime developer, so it will not be installed
+# But runtime developer can use nnfw_debug.h by linking nnfw-dev
+set(NNFW_API_HEADERS include/nnfw.h include/nnfw_dev.h)
+
+target_link_libraries(${NEURUN_DEV} PUBLIC nnfw-nnapi-header)
+target_link_libraries(${NEURUN_DEV} PRIVATE neurun_core)
+target_link_libraries(${NEURUN_DEV} PRIVATE jsoncpp tflite_loader circle_loader ${LIB_PTHREAD})
+target_link_libraries(${NEURUN_DEV} PRIVATE nnfw_common)
+target_link_libraries(${NEURUN_DEV} PRIVATE nnfw_coverage)
+target_include_directories(${NEURUN_DEV} PUBLIC include)
+set_target_properties(${NEURUN_DEV} PROPERTIES PUBLIC_HEADER "${NNFW_API_HEADERS}")
+
+install(TARGETS ${NEURUN_DEV}
+ LIBRARY DESTINATION lib
+ PUBLIC_HEADER DESTINATION include/nnfw)
diff --git a/runtime/neurun/api/include/nnfw.h b/runtime/neurun/api/include/nnfw.h
new file mode 100644
index 000000000..c903fbcad
--- /dev/null
+++ b/runtime/neurun/api/include/nnfw.h
@@ -0,0 +1,378 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file nnfw.h
+ * @brief This file describes runtime API
+ */
+#ifndef __NNFW_H__
+#define __NNFW_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Session to query with runtime
+ *
+ * <p>nnfw_session is started and passed by calling {@link nnfw_create_session}.
+ * Each session has its own inference environment, such as model to inference, backend usage, etc.
+ *
+ * <p>Load model by calling {@link nnfw_load_model_from_file}
+ *
+ * <p>After loading, prepare inference by calling {@link nnfw_prepare}.
+ * Application can set runtime environment before prepare by calling
+ * {@link nnfw_set_available_backends} and {@link nnfw_set_op_backend}, and it is optional.
+ *
+ * <p>Application can inference by calling {@link nnfw_run}.
+ * Before inference, application has responsibility to set input tensor to set input data by calling
+ * {@link nnfw_set_output}, and output tensor to get output by calling {@link nnfw_set_input}
+ *
+ * <p>To support input and output setting, application can get
+ * input and output tensor information by calling<ul>
+ * <li>{@link nnfw_input_size}</li>
+ * <li>{@link nnfw_output_size}</li>
+ * <li>{@link nnfw_input_tensorinfo}</li>
+ * <li>{@link nnfw_output_tensorinfo}</li>
+ * </ul>
+ *
+ * <p>Application can inference many times using one session,
+ * but next inference can do after prior inference end
+ *
+ * <p>Application cannot use muitiple model using one session
+ */
+typedef struct nnfw_session nnfw_session;
+
+/**
+ * @brief Tensor types
+ *
+ * The type of tensor represented in {@link nnfw_tensorinfo}
+ */
+typedef enum {
+ /** A tensor of 32 bit floating point */
+ NNFW_TYPE_TENSOR_FLOAT32 = 0,
+ /** A tensor of 32 bit signed integer */
+ NNFW_TYPE_TENSOR_INT32 = 1,
+ /**
+ * A tensor of 8 bit integers that represent real numbers.
+ *
+ * real_value = (integer_value - zeroPoint) * scale.
+ */
+ NNFW_TYPE_TENSOR_QUANT8_ASYMM = 2,
+ /** A tensor of boolean */
+ NNFW_TYPE_TENSOR_BOOL = 3,
+ /** A tensor of 8 bit unsigned integer */
+ NNFW_TYPE_TENSOR_UINT8 = 4,
+} NNFW_TYPE;
+
+/**
+ * @brief Result Values
+ */
+typedef enum {
+ /** Successful */
+ NNFW_STATUS_NO_ERROR = 0,
+ /** Failed */
+ NNFW_STATUS_ERROR = 1,
+} NNFW_STATUS;
+
+/**
+ * @brief Data format of a tensor
+ */
+typedef enum {
+ /** Don't care layout */
+ NNFW_LAYOUT_NONE = 0,
+ /**
+ * Channel last layout
+ * If rank is 4, layout is NHWC
+ */
+ NNFW_LAYOUT_CHANNELS_LAST = 1,
+ /**
+ * Channel first layout
+ * If rank is 4, layout is NCHW
+ */
+ NNFW_LAYOUT_CHANNELS_FIRST = 2,
+} NNFW_LAYOUT;
+
+/**
+ * @brief tensor info describes the type and shape of tensors
+ *
+ * <p>This structure is used to describe input and output tensors.
+ * Application can get input and output tensor type and shape described in model by using
+ * {@link nnfw_input_tensorinfo} and {@link nnfw_output_tensorinfo}
+ *
+ * <p>Maximum rank is 6. And tensor's dimension value is filled in 'dims' field from index 0.
+ * For example, if tensor's rank is 4,
+ * application can get dimension value from dims[0], dims[1], dims[2], and dims[3]
+ */
+typedef struct nnfw_tensorinfo
+{
+ /** The data type */
+ NNFW_TYPE dtype;
+ /** The number of dimensions (rank) */
+ int32_t rank;
+ /**
+ * The dimension of tensor.
+ * Maximum rank is 6.
+ */
+ int32_t dims[6];
+} nnfw_tensorinfo;
+
+/**
+ * @brief Create a new session instance.
+ *
+ * <p>This only creates a session.
+ * Model is loaded after {@link nnfw_load_model_from_file} is invoked.
+ * And inference is performed after {@link nnfw_run} is invoked.
+ *
+ * <p>{@link nnfw_close_session} should be called once
+ * if session is no longer need
+ *
+ * @param[out] session The session to be created
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_create_session(nnfw_session **session);
+
+/**
+ * @brief Close a session instance
+ *
+ * After called, access to closed session by application will be invalid
+ *
+ * @param[in] session The session to be closed
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_close_session(nnfw_session *session);
+
+/**
+ * @brief Load model from nnpackage file or directory
+ *
+ * @param[in] session nnfw_session loading the given nnpackage file/dir
+ * @param[in] package_file_path Path to the nnpackage file or unzipped directory to be loaded
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_load_model_from_file(nnfw_session *session, const char *package_file_path);
+
+/**
+ * @brief Apply i-th input's tensor info to resize input tensor
+ *
+ * This function should be called before {@link nnfw_prepare} is invoked, and
+ * should be called after {@link nnfw_load_model_from_file} is invoked
+ * See {@link nnfw_prepare} for information applying updated tensor info
+ * If this function is called many times for same index, tensor info is overwritten
+ *
+ * @param[in] session Session to the input tensor info is to be set
+ * @param[in] index Index of input to be applied (0-indexed)
+ * @param[in] tensor_info Tensor info to be applied
+ * @return @c NNFW_STATUS_NO_ERROR if successful, otherwise return @c NNFW_STATUS_ERROR
+ */
+NNFW_STATUS nnfw_apply_tensorinfo(nnfw_session *session, uint32_t index,
+ nnfw_tensorinfo tensor_info);
+
+/**
+ * @brief Prepare session to be ready for inference
+ *
+ * This phase may finalize model compilation, scheduling, and additional settings.
+ * If {@link nnfw_apply_tensor} is called to apply input tensor info different with model
+ * before this function, tries to resize all tensors.
+ *
+ * @param[in] session the session to be prepared
+ * @return @c NNFW_STATUS_NO_ERROR if successful, otherwise return @c NNFW_STATUS_ERROR
+ */
+NNFW_STATUS nnfw_prepare(nnfw_session *session);
+
+/**
+ * @brief Run inference
+ *
+ * <p>This function should be called after model is loaded by {@link nnfw_load_model_from_file},
+ * session is prepared for inference by {@link nnfw_prepare}, set input and output buffers
+ * by {@link nnfw_set_input} and {@link nnfw_set_output}.</p>
+ *
+ * <p>This function return after inference is finished.</p>
+ *
+ * @param[in] session The session to run inference
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_run(nnfw_session *session);
+
+/**
+ * @brief Set input buffer
+ *
+ * This function should be called after {@link nnfw_prepare}, and before first inference
+ * on session by {@link nnfw_run}. Application can reuse buffer for many inferences.
+ *
+ * @param[in] session Session to the input is to be set
+ * @param[in] index Index of input to be set (0-indexed)
+ * @param[in] type Type of the input
+ * @param[in] buffer Raw buffer for input
+ * @param[in] length Size of bytes of input buffer
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_input(nnfw_session *session, uint32_t index, NNFW_TYPE type,
+ const void *buffer, size_t length);
+
+/**
+ * @brief Set output buffer
+ *
+ * This function should be called after {@link nnfw_prepare}, and before first inference
+ * on session by {@link nnfw_run}. Application can reuse buffer for many inferences.
+ *
+ * @param[in] session Session from inference output is to be extracted
+ * @param[in] index Index of output to be set (0-indexed)
+ * @param[in] type Type of the output
+ * @param[out] buffer Raw buffer for output
+ * @param[in] length Size of bytes of output buffer
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_output(nnfw_session *session, uint32_t index, NNFW_TYPE type, void *buffer,
+ size_t length);
+
+/**
+ * @brief Get the number of inputs
+ *
+ * Application can call this function to get number of inputs defined in loaded model.
+ * This function should be called after {@link nnfw_load_model_from_file} is invoked to load model
+ *
+ * @param[in] session Session from input information is to be extracted
+ * @param[out] number Variable which the number of inputs is put into
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_input_size(nnfw_session *session, uint32_t *number);
+
+/**
+ * @brief Get the number of outputs
+ *
+ * Application can call this function to get number of outputs defined in loaded model.
+ * This function should be called after {@link nnfw_load_model_from_file} is invoked to load model
+ *
+ * @param[in] session Session from output information is to be extracted
+ * @param[out] number Variable which the number of outputs is put into
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_output_size(nnfw_session *session, uint32_t *number);
+
+/**
+ * @brief Set the layout of an input
+ *
+ * The input that does not call this has NNFW_LAYOUT_NHWC layout
+ *
+ * @param[in] session session from inference input is to be extracted
+ * @param[in] index index of input to be set (0-indexed)
+ * @param[in] layout layout to set to target input
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_input_layout(nnfw_session *session, uint32_t index, NNFW_LAYOUT layout);
+
+/**
+ * @brief Set the layout of an output
+ *
+ * The output that does not call this has NNFW_LAYOUT_NHWC layout
+ *
+ * @param[in] session session from inference output is to be extracted
+ * @param[in] index index of output to be set (0-indexed)
+ * @param[in] layout layout to set to target output
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_output_layout(nnfw_session *session, uint32_t index, NNFW_LAYOUT layout);
+
+/**
+ * @brief Get i-th input tensor info
+ *
+ * <p>Before {@link nnfw_prepare} is invoked, this function return tensor info in model,
+ * so updated tensor info by {@link nnfw_apply_tensorinfo} is not returned.</p>
+ *
+ * <p>After {@link nnfw_prepare} is invoked, this function return updated tensor info
+ * if tensor info is updated by {@link nnfw_apply_tensorinfo}.</p>
+ *
+ * @param[in] session Session from input information is to be extracted
+ * @param[in] index Index of input
+ * @param[out] tensor_info Tensor info (shape, type, etc)
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_input_tensorinfo(nnfw_session *session, uint32_t index,
+ nnfw_tensorinfo *tensor_info);
+
+/**
+ * @brief Get i-th output tensor info
+ *
+ * <p>Before {@link nnfw_prepare} is invoked, this function return tensor info in model,
+ * so updated tensor info by {@link nnfw_apply_tensorinfo} is not returned.</p>
+ *
+ * <p>After {@link nnfw_prepare} is invoked, this function return updated tensor info
+ * if tensor info is updated by {@link nnfw_apply_tensorinfo}.</p>
+ *
+ * @param[in] session Session from output information is to be extracted
+ * @param[in] index Index of output
+ * @param[out] tensor_info Tensor info (shape, type, etc)
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_output_tensorinfo(nnfw_session *session, uint32_t index,
+ nnfw_tensorinfo *tensor_info);
+
+/**
+ * @brief Set available backends
+ *
+ * This function should be called before {@link nnfw_prepare} is invoked.
+ *
+ * <p>Supported backends differs on each platforms.
+ * For example, `x86_64` supports "cpu" only.
+ * Can set multiple backends by semicolon (ex: "acl_cl;cpu").
+ * Among the multiple backends, the 1st element is used as default backend.</p>
+ *
+ * @note Possible backend strings are: "cpu", "acl_cl", "acl_neon", "srcn"
+ *
+ * @param[in] session session to which avilable backends are set
+ * @param[in] backends available backends on which nnfw uses
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_available_backends(nnfw_session *session, const char *backends);
+
+/**
+ * @brief Set the operation's backend
+ *
+ * This function should be called before {@link nnfw_prepare} is invoked.
+ *
+ * <p>Supported backends differs on each platforms.
+ * For example, `x86_64` supports "cpu" only.
+ * The backend for op has higher priority than default backend specified by
+ * nnfw_set_default_backend.</p>
+ *
+ * @note Possible backend strings are: "cpu", "acl_cl", "acl_neon"
+ *
+ * @param[in] session session to be modified
+ * @param[in] op operation to be set
+ * @param[in] backend bakcend on which operation run
+ *
+ * @return @c NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_op_backend(nnfw_session *session, const char *op, const char *backend);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/runtime/neurun/api/include/nnfw_debug.h b/runtime/neurun/api/include/nnfw_debug.h
new file mode 100644
index 000000000..eefca0d29
--- /dev/null
+++ b/runtime/neurun/api/include/nnfw_debug.h
@@ -0,0 +1,24 @@
+/*
+ * 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 __NNFW_DEBUG_H__
+#define __NNFW_DEBUG_H__
+
+#include "nnfw.h"
+
+NNFW_STATUS nnfw_create_debug_session(nnfw_session **session);
+
+#endif // __NNFW_DEBUG_H__
diff --git a/runtime/neurun/api/include/nnfw_dev.h b/runtime/neurun/api/include/nnfw_dev.h
new file mode 100644
index 000000000..ecf0597cf
--- /dev/null
+++ b/runtime/neurun/api/include/nnfw_dev.h
@@ -0,0 +1,65 @@
+/*
+ * 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 __NNFW_DEV_H__
+#define __NNFW_DEV_H__
+
+#include "nnfw.h"
+
+// Used for custom kernel development
+
+/*
+ * operand type, used only for custom operations
+ */
+typedef struct
+{
+ nnfw_tensorinfo type;
+ void *allocation;
+} nnfw_operand;
+
+/*
+ * Used as input to custom operation eval function
+ */
+typedef struct
+{
+ size_t ninputs;
+ nnfw_operand *inputs;
+
+ size_t noutputs;
+ nnfw_operand *outputs;
+} nnfw_custom_kernel_params;
+
+/*
+ * Custom kernel evaluation function
+ *
+ * param[in] params custom operation parameters
+ * param[in] userdata pointer to user-specified buffer( kernel instance specific )
+ */
+typedef void (*nnfw_custom_eval)(nnfw_custom_kernel_params *params, char *userdata,
+ size_t userdata_size);
+
+/*
+ * custom operation registration info
+ */
+typedef struct
+{
+ nnfw_custom_eval eval_function;
+} custom_kernel_registration_info;
+
+NNFW_STATUS nnfw_register_custom_op_info(nnfw_session *session, const char *id,
+ custom_kernel_registration_info *info);
+
+#endif // __NNFW_DEV_H__
diff --git a/runtime/neurun/api/src/CustomKernel.cc b/runtime/neurun/api/src/CustomKernel.cc
new file mode 100644
index 000000000..60ddeedc2
--- /dev/null
+++ b/runtime/neurun/api/src/CustomKernel.cc
@@ -0,0 +1,98 @@
+/*
+ * 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 "CustomKernel.h"
+
+namespace neurun
+{
+namespace frontend
+{
+namespace custom
+{
+
+using namespace backend::custom;
+
+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 ir::DataType::FLOAT32:
+ api_type.dtype = NNFW_TYPE_TENSOR_FLOAT32;
+ break;
+ case ir::DataType::INT32:
+ api_type.dtype = NNFW_TYPE_TENSOR_INT32;
+ break;
+ case ir::DataType::QUANT8_ASYMM:
+ api_type.dtype = NNFW_TYPE_TENSOR_QUANT8_ASYMM;
+ break;
+ case ir::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)
+ : _params(), _userdata(nullptr), _userdata_size(0), _evalFunction(evalFunction)
+{
+}
+
+void Kernel::configure(CustomKernelConfigParams &&inParams)
+{
+ _userdata = inParams.userdata;
+ _userdata_size = inParams.userdata_size;
+
+ _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, _userdata_size); }
+
+} // namespace custom
+} // namespace backend
+} // namespace neurun
diff --git a/runtime/neurun/api/src/CustomKernel.h b/runtime/neurun/api/src/CustomKernel.h
new file mode 100644
index 000000000..8cafc2061
--- /dev/null
+++ b/runtime/neurun/api/src/CustomKernel.h
@@ -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 __NEURUN_BACKEND_CUSTOM_KERNEL_H__
+#define __NEURUN_BACKEND_CUSTOM_KERNEL_H__
+
+#include "nnfw_dev.h"
+
+#include "backend/CustomKernelBuilder.h"
+
+#include <vector>
+
+namespace neurun
+{
+namespace frontend
+{
+namespace custom
+{
+
+class Kernel : public ::neurun::exec::IFunction
+{
+public:
+ explicit Kernel(nnfw_custom_eval evalFunction);
+
+ nnfw_custom_kernel_params _params;
+ char *_userdata;
+ size_t _userdata_size;
+
+ nnfw_custom_eval _evalFunction;
+ // nnfw_custom_type_infer _type_infer_function; //Unused for now
+
+ /**
+ * Fills _params field used later by user specified eval function
+ * @param inParams custom kernel parameters
+ */
+ virtual void configure(backend::custom::CustomKernelConfigParams &&inParams);
+
+ void run() override;
+ void runSync() override { run(); }
+};
+
+} // namespace custom
+} // namespace frontend
+} // namespace neurun
+
+#endif // __NEURUN_BACKEND_CUSTOM_KERNEL_H__
diff --git a/runtime/neurun/api/src/CustomKernelRegistry.cc b/runtime/neurun/api/src/CustomKernelRegistry.cc
new file mode 100644
index 000000000..b223682b8
--- /dev/null
+++ b/runtime/neurun/api/src/CustomKernelRegistry.cc
@@ -0,0 +1,64 @@
+/*
+ * 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 "CustomKernelRegistry.h"
+
+#include "cpp14/memory.h"
+
+namespace neurun
+{
+namespace frontend
+{
+namespace custom
+{
+
+void KernelRegistry::registerKernel(const std::string &id, nnfw_custom_eval evalFunction)
+{
+ _storage.emplace(id, evalFunction);
+}
+
+std::shared_ptr<backend::custom::IKernelBuilder> KernelRegistry::getBuilder()
+{
+ return nnfw::cpp14::make_unique<KernelBuilder>(this);
+}
+
+std::unique_ptr<Kernel> KernelRegistry::buildKernelForOp(const std::string &id)
+{
+ 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<Kernel>(it->second);
+}
+
+// Kernel builder
+std::unique_ptr<exec::IFunction>
+KernelBuilder::buildKernel(const std::string &id,
+ backend::custom::CustomKernelConfigParams &&params) const
+{
+ auto kernel = _registry->buildKernelForOp(id);
+ kernel->configure(std::move(params));
+
+ return kernel;
+}
+
+KernelBuilder::KernelBuilder(KernelRegistry *registry) : _registry(registry) {}
+
+} // namespace custom
+} // namespace frontend
+} // namespace neurun
diff --git a/runtime/neurun/api/src/CustomKernelRegistry.h b/runtime/neurun/api/src/CustomKernelRegistry.h
new file mode 100644
index 000000000..207a82a0a
--- /dev/null
+++ b/runtime/neurun/api/src/CustomKernelRegistry.h
@@ -0,0 +1,64 @@
+/*
+ * 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_REGISTRY_H__
+#define __NEURUN_BACKEND_CUSTOM_KERNEL_REGISTRY_H__
+
+#include "CustomKernel.h"
+
+#include <unordered_map>
+#include <functional>
+#include <memory>
+
+#include <iostream>
+
+namespace neurun
+{
+namespace frontend
+{
+namespace custom
+{
+
+class KernelRegistry
+{
+public:
+ void registerKernel(const std::string &id, nnfw_custom_eval evalFunction);
+
+ std::shared_ptr<backend::custom::IKernelBuilder> getBuilder();
+ std::unique_ptr<Kernel> buildKernelForOp(const std::string &id);
+
+private:
+ std::unordered_map<std::string, nnfw_custom_eval> _storage;
+};
+
+class KernelBuilder : public backend::custom::IKernelBuilder
+{
+public:
+ KernelBuilder(KernelRegistry *registry);
+
+ std::unique_ptr<exec::IFunction>
+ buildKernel(const std::string &id,
+ backend::custom::CustomKernelConfigParams &&params) const override;
+
+private:
+ KernelRegistry *_registry;
+};
+
+} // namespace custom
+} // namespace frontend
+} // namespace neurun
+
+#endif // __NEURUN_BACKEND_CUSTOM_KERNEL_REGISTRY_H__
diff --git a/runtime/neurun/api/src/OpMap.lst b/runtime/neurun/api/src/OpMap.lst
new file mode 100644
index 000000000..5e93275b8
--- /dev/null
+++ b/runtime/neurun/api/src/OpMap.lst
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2020 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 MAP_MACRO
+#error Define MAP_MACRO before including this file
+#endif
+
+// circle operation | neurun internal operation
+MAP_MACRO(ADD , Add)
+MAP_MACRO(SUB , Sub)
+MAP_MACRO(BATCH_TO_SPACE_ND , BatchToSpaceND)
+MAP_MACRO(CAST , Cast)
+MAP_MACRO(CONV_2D , Conv2D)
+MAP_MACRO(DEPTHWISE_CONV_2D , DepthwiseConv2D)
+MAP_MACRO(AVERAGE_POOL_2D , AvgPool2D)
+MAP_MACRO(MAX_POOL_2D , MaxPool2D)
+MAP_MACRO(CONCATENATION , Concat)
+MAP_MACRO(FULLY_CONNECTED , FullyConnected)
+MAP_MACRO(SUM , ReduceSum)
+MAP_MACRO(RESHAPE , Reshape)
+MAP_MACRO(MUL , Mul)
+MAP_MACRO(SOFTMAX , Softmax)
+MAP_MACRO(SQUEEZE , Squeeze)
+MAP_MACRO(SLICE , Slice)
+MAP_MACRO(STRIDED_SLICE , StridedSlice)
+MAP_MACRO(TANH , Tanh)
+MAP_MACRO(LOGISTIC , Logistic)
+MAP_MACRO(DIV , Div)
+MAP_MACRO(TRANSPOSE , Transpose)
+MAP_MACRO(EXP , Exp)
+MAP_MACRO(REDUCE_MAX , ReduceMax)
+// UNMATCHED
+//MAP_MACRO(Comparison)
+MAP_MACRO(LOGICAL_AND , LogicalAnd)
+MAP_MACRO(LOGICAL_OR , LogicalOr)
+MAP_MACRO(LOGICAL_NOT , LogicalNot)
+MAP_MACRO(LSTM , LSTM)
+MAP_MACRO(RSQRT , RSQRT)
+MAP_MACRO(RELU , ReLU)
+MAP_MACRO(RESIZE_BILINEAR , ResizeBilinear)
+MAP_MACRO(RELU_N1_TO_1 , ReLU1)
+MAP_MACRO(RELU6 , ReLU6)
+MAP_MACRO(RNN , RNN)
+MAP_MACRO(FLOOR , Floor)
+MAP_MACRO(SPACE_TO_BATCH_ND , SpaceToBatchND)
+MAP_MACRO(SPACE_TO_DEPTH , SpaceToDepth)
+MAP_MACRO(L2_POOL_2D , L2Pool2D)
+MAP_MACRO(EMBEDDING_LOOKUP , EmbeddingLookup)
+MAP_MACRO(L2_NORMALIZATION , L2Normalization)
+MAP_MACRO(HASHTABLE_LOOKUP , HashtableLookup)
+MAP_MACRO(INSTANCE_NORM , InstanceNorm)
+MAP_MACRO(PRELU , PReLU)
+MAP_MACRO(TRANSPOSE_CONV , TransposeConv)
+MAP_MACRO(SQRT , SQRT)
+MAP_MACRO(SQUARED_DIFFERENCE , SquaredDifference)
+MAP_MACRO(TOPK_V2 , TopKV2)
+MAP_MACRO(GATHER , Gather)
+MAP_MACRO(NEG , Neg)
+MAP_MACRO(ABS , Abs)
+MAP_MACRO(ARG_MAX , ArgMax)
+MAP_MACRO(DEQUANTIZE , Dequantize)
+MAP_MACRO(MEAN , Mean)
+MAP_MACRO(LOCAL_RESPONSE_NORMALIZATION , LocalResponseNormalization)
+// UNDEFINED IN CIRCLE
+//MAP_MACRO(DepthToSpace)
+MAP_MACRO(PACK , Pack)
+MAP_MACRO(REDUCE_MIN , ReduceMin)
+MAP_MACRO(SPLIT , Split)
+MAP_MACRO(UNPACK , Unpack)
+MAP_MACRO(PAD , Pad)
+MAP_MACRO(CUSTOM , Custom)
+// UNDEFINED IN CIRCLE
+//MAP_MACRO(Permute)
+MAP_MACRO(MINIMUM , Min)
+MAP_MACRO(MAXIMUM , Max)
+MAP_MACRO(ONE_HOT , OneHot)
diff --git a/runtime/neurun/api/src/nnfw_api.cc b/runtime/neurun/api/src/nnfw_api.cc
new file mode 100644
index 000000000..bdac4c89b
--- /dev/null
+++ b/runtime/neurun/api/src/nnfw_api.cc
@@ -0,0 +1,267 @@
+/*
+ * 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 "nnfw_api_internal.h"
+
+/*
+ * Create a new session instance
+ *
+ * @param session the session to be created
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_create_session(nnfw_session **session)
+{
+ *session = new nnfw_session();
+
+ return NNFW_STATUS_NO_ERROR;
+}
+
+/*
+ * Close a session instance
+ *
+ * @param session the session to be closed
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_close_session(nnfw_session *session)
+{
+ delete session;
+ return NNFW_STATUS_NO_ERROR;
+}
+
+#define NNFW_RETURN_ERROR_IF_NULL(p) \
+ do \
+ { \
+ if ((p) == NULL) \
+ return NNFW_STATUS_ERROR; \
+ } while (0)
+
+/*
+ * Load model from nnpackage file or directory
+ *
+ * @param session nnfw_session loading the given nnpackage file/dir
+ * @param package_file_path path to the nnpackage file or unzipped directory to be loaded
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_load_model_from_file(nnfw_session *session, const char *pacakge_file_path)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->load_model_from_file(pacakge_file_path);
+}
+
+/*
+ * Prepare session to be ready for inference
+ * This phase may finalize model compilation, scheduling, and additional settings.
+ *
+ * @param session the session to be prepared
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_prepare(nnfw_session *session)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->prepare();
+}
+
+/*
+ * Run inference
+ *
+ * @param session the session to run inference
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_run(nnfw_session *session)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->run();
+}
+
+/*
+ * Set input
+ *
+ * @param session session to the input is to be set
+ * @param index index of input to be set (0-indexed)
+ * @param type type of the input
+ * @param buffer raw buffer for input
+ * @param length size of bytes of output
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+
+NNFW_STATUS nnfw_set_input(nnfw_session *session, uint32_t index, NNFW_TYPE type,
+ const void *buffer, size_t length)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->set_input(index, type, buffer, length);
+}
+
+/*
+ * Set output
+ *
+ * @param session session from inference output is to be extracted
+ * @param index index of output to be set (0-indexed)
+ * @param type type of the output
+ * @param buffer raw buffer for output
+ * @param length size of bytes of output
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+
+NNFW_STATUS nnfw_set_output(nnfw_session *session, uint32_t index, NNFW_TYPE type, void *buffer,
+ size_t length)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->set_output(index, type, buffer, length);
+}
+
+/*
+ * Get the number of inputs
+ *
+ * @param[in] session session from input information is to be extracted
+ * @param[out] number variable which the number of inputs is put into
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+
+NNFW_STATUS nnfw_input_size(nnfw_session *session, uint32_t *number)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->input_size(number);
+}
+
+/*
+ * Get the number of outputs
+ *
+ * @param[in] session session from output information is to be extracted
+ * @param[out] number variable which the number of outputs is put into
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_output_size(nnfw_session *session, uint32_t *number)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->output_size(number);
+}
+
+/*
+ * Set the layout of an input
+ * @note The input that does not call this has NNFW_LAYOUT_CHANNELS_LAST layout
+ *
+ * @param[in] session session from inference input is to be extracted
+ * @param[in] index index of input to be set (0-indexed)
+ * @param[in] layout layout to set to target input
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_input_layout(nnfw_session *session, uint32_t index, NNFW_LAYOUT layout)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->set_input_layout(index, layout);
+}
+
+/*
+ * Set the layout of an output
+ * @note The output that does not call this has NNFW_LAYOUT_CHANNELS_LAST layout
+ *
+ * @param[in] session session from inference output is to be extracted
+ * @param[in] index index of output to be set (0-indexed)
+ * @param[in] layout layout to set to target output
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_output_layout(nnfw_session *session, uint32_t index, NNFW_LAYOUT layout)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->set_output_layout(index, layout);
+}
+
+/*
+ * Get i-th input tensor info
+ *
+ * @param[in] session session from input information is to be extracted
+ * @param[in] index index of input
+ * @param[out] tensor_info nnfw_tensor_info
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_input_tensorinfo(nnfw_session *session, uint32_t index,
+ nnfw_tensorinfo *tensor_info)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->input_tensorinfo(index, tensor_info);
+}
+
+/*
+ * Get i-th output tensor info
+ *
+ * @param[in] session session from output information is to be extracted
+ * @param[in] index index of output
+ * @param[out] tensor_info nnfw_tensor_info
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_output_tensorinfo(nnfw_session *session, uint32_t index,
+ nnfw_tensorinfo *tensor_info)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->output_tensorinfo(index, tensor_info);
+}
+
+/*
+ * Register custom operation
+ * @param session session to register this operation
+ * @param id operation id
+ * @param info registration info ( eval function, etc. )
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_register_custom_op_info(nnfw_session *session, const char *id,
+ custom_kernel_registration_info *info)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->register_custom_operation(id, info->eval_function);
+}
+
+NNFW_STATUS nnfw_apply_tensorinfo(nnfw_session *session, uint32_t index,
+ nnfw_tensorinfo tensor_info)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->apply_tensorinfo(index, tensor_info);
+}
+
+/*
+ * Set available backends
+ *
+ * @param[in] session session to which a avilable backends are set
+ * @param[in] backends available backends on which nnfw uses
+ */
+NNFW_STATUS nnfw_set_available_backends(nnfw_session *session, const char *backends)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->set_available_backends(backends);
+}
+
+/*
+ * Set the operation's backend
+ *
+ * @param[in] session session to be modified
+ * @param[in] op operation to be set
+ * @param[in] backend bakcend on which operation run
+ *
+ * @return NNFW_STATUS_NO_ERROR if successful
+ */
+NNFW_STATUS nnfw_set_op_backend(nnfw_session *session, const char *op, const char *backend)
+{
+ NNFW_RETURN_ERROR_IF_NULL(session);
+ return session->set_op_backend(op, backend);
+}
diff --git a/runtime/neurun/api/src/nnfw_api_internal.cc b/runtime/neurun/api/src/nnfw_api_internal.cc
new file mode 100644
index 000000000..037cd3bca
--- /dev/null
+++ b/runtime/neurun/api/src/nnfw_api_internal.cc
@@ -0,0 +1,435 @@
+/*
+ * 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 "nnfw_api_internal.h"
+#include "CustomKernelRegistry.h"
+#include "compiler/Compiler.h"
+#include "exec/Execution.h"
+#include "circle_loader.h"
+#include "tflite_loader.h"
+#include "json/json.h"
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <dirent.h>
+#include <util/ConfigSource.h>
+
+/*
+ * API does not accept string argument longer than max length below
+ */
+#define MAX_BACKEND_NAME_LENGTH 32
+#define MAX_OP_NAME_LENGTH 64
+
+// Is null-terminating in length ?
+static bool null_terminating(const char *str, uint32_t length)
+{
+ for (uint32_t i = 0; i < length; i++)
+ {
+ if (*(str + i) == '\0')
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+static neurun::ir::Layout convertLayout(NNFW_LAYOUT layout)
+{
+ if (layout == NNFW_LAYOUT_CHANNELS_LAST)
+ {
+ return neurun::ir::Layout::NHWC;
+ }
+ else if (layout == NNFW_LAYOUT_CHANNELS_FIRST)
+ {
+ return neurun::ir::Layout::NCHW;
+ }
+ return neurun::ir::Layout::UNKNOWN;
+}
+
+nnfw_session::nnfw_session()
+ : _graph{nullptr}, _execution{nullptr},
+ _kernel_registry{std::make_shared<neurun::frontend::custom::KernelRegistry>()},
+ _source{nnfw::cpp14::make_unique<neurun::util::GeneralConfigSource>()}
+{
+ // DO NOTHING
+}
+
+NNFW_STATUS nnfw_session::load_model_from_file(const char *package_dir)
+{
+ // TODO : add support for zipped package file load
+ DIR *dir;
+ if (!(dir = opendir(package_dir)))
+ {
+ std::cerr << "invalid nnpackge directory: " << package_dir << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ closedir(dir);
+
+ try
+ {
+ std::string manifest_file_name(package_dir);
+ manifest_file_name += "/metadata/MANIFEST";
+ std::ifstream mfs(manifest_file_name);
+
+ // extract the filename of the first(index 0) model
+ // e.g. In MANIFEST file, { "models" : [ "firstmodel.tflite", "2nd.tflite" ] }
+ Json::Value root;
+ mfs >> root;
+ Json::Value models = root["models"];
+ Json::Value model_types = root["model-types"];
+
+ auto model_file_path = package_dir + std::string("/") + models[0].asString(); // first model
+ auto model_type = model_types[0].asString(); // first model's type
+ if (model_type == "tflite")
+ {
+ _graph = neurun::tflite_loader::loadModel(model_file_path.c_str());
+ }
+ else if (model_type == "circle")
+ {
+ _graph = neurun::circle_loader::loadModel(model_file_path.c_str());
+ }
+ else
+ {
+ std::cerr << "Unsupported model type in MANIFEST" << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ _graph->bindKernelBuilder(_kernel_registry->getBuilder());
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during model loading : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::prepare()
+{
+ // TODO : add additional setting routine(executor type, backend)
+ // Note that we assume acl_cl backend
+
+ try
+ {
+ // config_source setting
+ using neurun::util::config_source;
+ config_source(std::move(_source));
+
+ auto compiler = nnfw::cpp14::make_unique<neurun::compiler::Compiler>(_graph);
+ compiler->compile();
+ std::shared_ptr<neurun::exec::IExecutor> executor;
+ compiler->release(executor);
+ _execution = std::make_shared<neurun::exec::Execution>(executor);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during model prepare : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::run()
+{
+ try
+ {
+ _execution->execute();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::run : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::set_input(uint32_t index, NNFW_TYPE /*type*/, const void *buffer,
+ size_t length)
+{
+ try
+ {
+ _execution->setInput(neurun::ir::IOIndex(index), buffer, length);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::set_input : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::set_output(uint32_t index, NNFW_TYPE /*type*/, void *buffer,
+ size_t length)
+{
+ try
+ {
+ _execution->setOutput(neurun::ir::IOIndex(index), buffer, length);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::set_output : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::input_size(uint32_t *number)
+{
+ try
+ {
+ if (number == nullptr)
+ {
+ std::cerr << "Error during nnfw_session::input_size, number is null pointer." << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ *number = _graph->getInputs().size();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::input_size : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::output_size(uint32_t *number)
+{
+ try
+ {
+ if (number == nullptr)
+ {
+ std::cerr << "Error during nnfw_session::output_size, number is null pointer." << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ *number = _graph->getOutputs().size();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::output_size" << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::set_input_layout(uint32_t index, NNFW_LAYOUT layout)
+{
+ try
+ {
+ if (layout != NNFW_LAYOUT_NONE && layout != NNFW_LAYOUT_CHANNELS_FIRST &&
+ layout != NNFW_LAYOUT_CHANNELS_LAST)
+ {
+ std::cerr << "Error during nnfw_session::set_input_layout, not supported layout" << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ _execution->setInputLayout(neurun::ir::IOIndex(index), convertLayout(layout));
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::set_input_layout : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::set_output_layout(uint32_t index, NNFW_LAYOUT layout)
+{
+ try
+ {
+ if (layout != NNFW_LAYOUT_NONE && layout != NNFW_LAYOUT_CHANNELS_FIRST &&
+ layout != NNFW_LAYOUT_CHANNELS_LAST)
+ {
+ std::cerr << "Error during nnfw_session::set_output_layout, not supported layout"
+ << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ _execution->setOutputLayout(neurun::ir::IOIndex(index), convertLayout(layout));
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::set_output_layout : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+static NNFW_TYPE datatype_to_nnfw_dtype(neurun::ir::DataType dt)
+{
+ using neurun::ir::DataType;
+ switch (dt)
+ {
+ case DataType::FLOAT32:
+ return NNFW_TYPE_TENSOR_FLOAT32;
+ case DataType::INT32:
+ return NNFW_TYPE_TENSOR_INT32;
+ case DataType::QUANT8_ASYMM:
+ return NNFW_TYPE_TENSOR_QUANT8_ASYMM;
+ case DataType::BOOL8:
+ return NNFW_TYPE_TENSOR_BOOL;
+ case DataType::UINT8:
+ return NNFW_TYPE_TENSOR_UINT8;
+ case DataType::UINT32:
+ case DataType::QUANT8_SYMM:
+ default:
+ std::cerr << "Error: Model has type that runtime API does not support." << std::endl;
+ exit(-1);
+ }
+}
+
+NNFW_STATUS nnfw_session::apply_tensorinfo(uint32_t /*index*/, nnfw_tensorinfo /*ti*/)
+{
+ std::cerr << "Error: NYI" << std::endl;
+ return NNFW_STATUS_ERROR;
+}
+
+NNFW_STATUS nnfw_session::input_tensorinfo(uint32_t index, nnfw_tensorinfo *ti)
+{
+ try
+ {
+ if (ti == nullptr)
+ {
+ std::cerr << "Error during nnfw_session::input_tensorinfo, tensorinfo is null pointer."
+ << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ if (index >= _graph->getInputs().size())
+ {
+ std::cerr << "Error during nnfw_session::input_tensorinfo, index is out of range."
+ << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ auto opidx = _graph->getInputs().at(index);
+ auto shape = _graph->operands().at(opidx).shape();
+ ti->rank = shape.rank();
+ for (int j = 0; j < ti->rank; ++j)
+ {
+ ti->dims[j] = shape.dim(j);
+ }
+ ti->dtype = datatype_to_nnfw_dtype(_graph->operands().at(opidx).typeInfo().type());
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::input_tensorinfo : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::output_tensorinfo(uint32_t index, nnfw_tensorinfo *ti)
+{
+ try
+ {
+ if (ti == nullptr)
+ {
+ std::cerr << "Error during nnfw_session::output_tensorinfo, tensorinfo is null pointer."
+ << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ if (index >= _graph->getOutputs().size())
+ {
+ std::cerr << "Error during nnfw_session::output_tensorinfo, index is out of range."
+ << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ auto opidx = _graph->getOutputs().at(index);
+ auto shape = _graph->operands().at(opidx).shape();
+ ti->rank = shape.rank();
+ for (int j = 0; j < ti->rank; ++j)
+ {
+ ti->dims[j] = shape.dim(j);
+ }
+ ti->dtype = datatype_to_nnfw_dtype(_graph->operands().at(opidx).typeInfo().type());
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::output_tensorinfo : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+NNFW_STATUS nnfw_session::register_custom_operation(const std::string &id,
+ nnfw_custom_eval eval_func)
+{
+ _kernel_registry->registerKernel(id, eval_func);
+ return NNFW_STATUS_NO_ERROR;
+}
+
+static std::string get_op_backend_string(std::string op)
+{
+#define MAP_MACRO(CircleName, NeurunName) {#CircleName, "OP_BACKEND_" #NeurunName},
+
+ static std::unordered_map<std::string, std::string> operation_map = {
+#include "OpMap.lst"
+ };
+
+#undef MAP_MACRO
+
+ auto n = operation_map.find(op);
+
+ if (n == operation_map.end())
+ {
+ // this return value is handled by a caller to return error code
+ return std::string("");
+ }
+ else
+ {
+ return n->second;
+ }
+}
+
+NNFW_STATUS nnfw_session::set_available_backends(const char *backends)
+{
+ try
+ {
+ if (!backends || null_terminating(backends, MAX_BACKEND_NAME_LENGTH) == false)
+ {
+ return NNFW_STATUS_ERROR;
+ }
+
+ _source->set("BACKENDS", backends);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::set_available_backends : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
+
+NNFW_STATUS nnfw_session::set_op_backend(const char *op, const char *backend)
+{
+ try
+ {
+ if (!op || !null_terminating(op, MAX_OP_NAME_LENGTH) || !backend ||
+ !null_terminating(backend, MAX_BACKEND_NAME_LENGTH))
+ {
+ return NNFW_STATUS_ERROR;
+ }
+
+ auto key = get_op_backend_string(op);
+
+ if (key.empty())
+ {
+ return NNFW_STATUS_ERROR;
+ }
+
+ _source->set(key, backend);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Error during nnfw_session::set_op_backend : " << e.what() << std::endl;
+ return NNFW_STATUS_ERROR;
+ }
+ return NNFW_STATUS_NO_ERROR;
+}
diff --git a/runtime/neurun/api/src/nnfw_api_internal.h b/runtime/neurun/api/src/nnfw_api_internal.h
new file mode 100644
index 000000000..40069cc55
--- /dev/null
+++ b/runtime/neurun/api/src/nnfw_api_internal.h
@@ -0,0 +1,84 @@
+/*
+ * 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 __API_NNFW_API_INTERNAL_H__
+#define __API_NNFW_API_INTERNAL_H__
+
+#include "nnfw.h"
+#include "nnfw_dev.h"
+
+#include <util/GeneralConfigSource.h>
+
+#include <string>
+#include <memory>
+
+namespace neurun
+{
+namespace frontend
+{
+namespace custom
+{
+class KernelRegistry;
+}
+} // namespace frontend
+namespace exec
+{
+class Execution;
+}
+namespace ir
+{
+class Graph;
+} // namespace ir
+} // namespace neurun
+
+struct nnfw_session
+{
+public:
+ nnfw_session();
+
+ NNFW_STATUS load_model_from_file(const char *package_file_path);
+ NNFW_STATUS prepare();
+ NNFW_STATUS run();
+
+ NNFW_STATUS set_input(uint32_t index, NNFW_TYPE type, const void *buffer, size_t length);
+ NNFW_STATUS set_output(uint32_t index, NNFW_TYPE type, void *buffer, size_t length);
+
+ NNFW_STATUS input_size(uint32_t *number);
+ NNFW_STATUS output_size(uint32_t *number);
+
+ NNFW_STATUS set_input_layout(uint32_t index, NNFW_LAYOUT layout);
+ NNFW_STATUS set_output_layout(uint32_t index, NNFW_LAYOUT layout);
+
+ NNFW_STATUS apply_tensorinfo(uint32_t index, nnfw_tensorinfo ti);
+
+ NNFW_STATUS input_tensorinfo(uint32_t index, nnfw_tensorinfo *ti);
+ NNFW_STATUS output_tensorinfo(uint32_t index, nnfw_tensorinfo *ti);
+
+ NNFW_STATUS register_custom_operation(const std::string &id, nnfw_custom_eval eval_func);
+
+ NNFW_STATUS set_available_backends(const char *backends);
+ NNFW_STATUS set_op_backend(const char *op, const char *backend);
+
+private:
+ std::shared_ptr<neurun::ir::Graph> _graph;
+ std::shared_ptr<neurun::exec::Execution> _execution;
+ std::shared_ptr<neurun::frontend::custom::KernelRegistry> _kernel_registry;
+
+protected:
+ std::unique_ptr<neurun::util::GeneralConfigSource> _source;
+};
+
+#endif // __API_NNFW_API_INTERNAL_H__
diff --git a/runtime/neurun/api/src/nnfw_debug.cc b/runtime/neurun/api/src/nnfw_debug.cc
new file mode 100644
index 000000000..4ea0a203f
--- /dev/null
+++ b/runtime/neurun/api/src/nnfw_debug.cc
@@ -0,0 +1,24 @@
+/*
+ * 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 "nnfw_debug_internal.h"
+
+NNFW_STATUS nnfw_create_debug_session(nnfw_session **session)
+{
+ *session = new nnfw_debug_session();
+
+ return NNFW_STATUS_NO_ERROR;
+}
diff --git a/runtime/neurun/api/src/nnfw_debug_internal.cc b/runtime/neurun/api/src/nnfw_debug_internal.cc
new file mode 100644
index 000000000..778efbc5c
--- /dev/null
+++ b/runtime/neurun/api/src/nnfw_debug_internal.cc
@@ -0,0 +1,25 @@
+/*
+ * 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 "nnfw_debug_internal.h"
+#include "util/EnvConfigSource.h"
+
+#include <cpp14/memory.h>
+
+nnfw_debug_session::nnfw_debug_session() : nnfw_session()
+{
+ _source = nnfw::cpp14::make_unique<neurun::util::EnvConfigSource>();
+}
diff --git a/runtime/neurun/api/src/nnfw_debug_internal.h b/runtime/neurun/api/src/nnfw_debug_internal.h
new file mode 100644
index 000000000..f4984e7a1
--- /dev/null
+++ b/runtime/neurun/api/src/nnfw_debug_internal.h
@@ -0,0 +1,29 @@
+/*
+ * 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 __API_NNFW_DEBUG_INTERNAL_H__
+#define __API_NNFW_DEBUG_INTERNAL_H__
+
+#include "nnfw_debug.h"
+#include "nnfw_api_internal.h"
+
+class nnfw_debug_session : public nnfw_session
+{
+public:
+ nnfw_debug_session();
+};
+
+#endif // __API_NNFW_DEBUG_INTERNAL_H__