summaryrefslogtreecommitdiff
path: root/runtimes/neurun/src/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'runtimes/neurun/src/frontend')
-rw-r--r--runtimes/neurun/src/frontend/compilation.cc5
-rw-r--r--runtimes/neurun/src/frontend/execution.cc221
-rw-r--r--runtimes/neurun/src/frontend/memory.cc4
-rw-r--r--runtimes/neurun/src/frontend/model.cc262
-rw-r--r--runtimes/neurun/src/frontend/wrapper/compilation.cc51
-rw-r--r--runtimes/neurun/src/frontend/wrapper/compilation.h10
-rw-r--r--runtimes/neurun/src/frontend/wrapper/execution.h20
-rw-r--r--runtimes/neurun/src/frontend/wrapper/model.cc20
-rw-r--r--runtimes/neurun/src/frontend/wrapper/model.h10
9 files changed, 368 insertions, 235 deletions
diff --git a/runtimes/neurun/src/frontend/compilation.cc b/runtimes/neurun/src/frontend/compilation.cc
index a135edac5..9b0719f46 100644
--- a/runtimes/neurun/src/frontend/compilation.cc
+++ b/runtimes/neurun/src/frontend/compilation.cc
@@ -32,6 +32,11 @@ int ANeuralNetworksCompilation_create(ANeuralNetworksModel *model,
return ANEURALNETWORKS_UNEXPECTED_NULL;
}
+ if (!model->isFinished())
+ {
+ return ANEURALNETWORKS_BAD_STATE;
+ }
+
std::shared_ptr<neurun::graph::Graph> internal;
model->release(internal);
diff --git a/runtimes/neurun/src/frontend/execution.cc b/runtimes/neurun/src/frontend/execution.cc
index ff34921b7..5f1729b30 100644
--- a/runtimes/neurun/src/frontend/execution.cc
+++ b/runtimes/neurun/src/frontend/execution.cc
@@ -22,7 +22,122 @@
#include "frontend/wrapper/execution.h"
#include "frontend/wrapper/event.h"
-#include "graph/operand/Index.h"
+#include "model/operand/DataType.h"
+#include "model/operand/Index.h"
+#include "graph/operand/Layout.h"
+#include "backend/BackendManager.h"
+#include "backend/interface/IConfig.h"
+#include "compiler/BackendResolver.h"
+#include "compiler/TensorInfo.h"
+#include "backend/interface/operand/ITensor.h"
+
+inline void source(ANeuralNetworksExecution *execution,
+ const ::neurun::model::operand::DataType &type, int32_t index,
+ const void *buffer, size_t length)
+{
+ const auto &operands = execution->plan().model().operands();
+ neurun::model::operand::IO::Index input_index{index};
+
+ const auto operand_index = execution->plan().model().getInputs().at(input_index);
+ auto operand = &operands.at(operand_index);
+ auto operand_li = operand->lower_info();
+ const auto output_backend = operand_li->def_backends().getOnlyElement();
+ const auto output_layout = output_backend->config()->getOperandLayout();
+ auto input_layout = execution->plan()
+ .model()
+ .backend_resolver()
+ ->getDefaultBackend()
+ ->config()
+ ->getOperandLayout();
+ if (input_layout == neurun::graph::operand::Layout::NHWC &&
+ output_layout == neurun::graph::operand::Layout::NCHW)
+ {
+ const auto tensor_info = neurun::compiler::TensorInfo(operand->shape(), operand->typeInfo());
+
+ execution->source<::neurun::exec::PermutateSource>(index, buffer, tensor_info.total_size(),
+ operand->shape());
+ return;
+ }
+ using ::neurun::model::operand::DataType;
+ switch (type)
+ {
+ case DataType::SCALAR_FLOAT32:
+ case DataType::TENSOR_FLOAT32:
+ execution->source<::neurun::exec::Source<float>>(
+ index, reinterpret_cast<const float *>(buffer), length);
+ break;
+ case DataType::SCALAR_INT32:
+ case DataType::TENSOR_INT32:
+ execution->source<::neurun::exec::Source<int32_t>>(
+ index, reinterpret_cast<const int32_t *>(buffer), length);
+ break;
+ case DataType::SCALAR_UINT32:
+ execution->source<::neurun::exec::Source<uint32_t>>(
+ index, reinterpret_cast<const uint32_t *>(buffer), length);
+ break;
+ case DataType::TENSOR_QUANT8_ASYMM:
+ execution->source<::neurun::exec::Source<uint8_t>>(
+ index, reinterpret_cast<const uint8_t *>(buffer), length);
+ break;
+ default:
+ throw std::runtime_error("Not supported, yet");
+ break;
+ }
+}
+
+inline void sink(ANeuralNetworksExecution *execution,
+ const ::neurun::model::operand::DataType &type, int32_t index, void *buffer,
+ size_t length)
+{
+ const auto &operands = execution->plan().model().operands();
+ neurun::model::operand::IO::Index input_index{index};
+
+ const auto operand_index = execution->plan().model().getOutputs().at(input_index);
+ auto operand = &operands.at(operand_index);
+ auto operand_li = operand->lower_info();
+ const auto input_backend = operand_li->def_backends().getOnlyElement();
+ const auto input_layout = input_backend->config()->getOperandLayout();
+ auto output_layout = execution->plan()
+ .model()
+ .backend_resolver()
+ ->getDefaultBackend()
+ ->config()
+ ->getOperandLayout();
+ if (input_layout == neurun::graph::operand::Layout::NCHW &&
+ output_layout == neurun::graph::operand::Layout::NHWC)
+ {
+ const auto tensor_info = neurun::compiler::TensorInfo(operand->shape(), operand->typeInfo());
+
+ execution->sink<::neurun::exec::PermutateSink>(index, buffer, tensor_info.total_size(),
+ operand->shape());
+ return;
+ }
+ using ::neurun::model::operand::DataType;
+ switch (type)
+ {
+ case DataType::SCALAR_FLOAT32:
+ case DataType::TENSOR_FLOAT32:
+ execution->sink<::neurun::exec::Sink<float>>(index, reinterpret_cast<float *>(buffer),
+ length);
+ break;
+ case DataType::SCALAR_INT32:
+ case DataType::TENSOR_INT32:
+ execution->sink<::neurun::exec::Sink<int32_t>>(index, reinterpret_cast<int32_t *>(buffer),
+ length);
+ break;
+ case DataType::SCALAR_UINT32:
+ execution->sink<::neurun::exec::Sink<uint32_t>>(index, reinterpret_cast<uint32_t *>(buffer),
+ length);
+ break;
+ case DataType::TENSOR_QUANT8_ASYMM:
+ execution->sink<::neurun::exec::Sink<uint8_t>>(index, reinterpret_cast<uint8_t *>(buffer),
+ length);
+ break;
+ default:
+ throw std::runtime_error("Not supported, yet");
+ break;
+ }
+}
//
// NNAPI Implementation
@@ -35,7 +150,13 @@ int ANeuralNetworksExecution_create(ANeuralNetworksCompilation *compilation,
return ANEURALNETWORKS_UNEXPECTED_NULL;
}
- std::shared_ptr<const neurun::codegen::Plan> plan;
+ // Can handle compiled state only
+ if (compilation->plan().state() != neurun::compiler::State::COMPILED)
+ {
+ return ANEURALNETWORKS_BAD_STATE;
+ }
+
+ std::shared_ptr<const neurun::compiler::Plan> plan;
compilation->publish(plan);
@@ -61,36 +182,23 @@ int ANeuralNetworksExecution_setInput(ANeuralNetworksExecution *execution, int32
return ANEURALNETWORKS_UNEXPECTED_NULL;
}
+ // TODO Handle optional input
+ if (buffer == nullptr)
+ {
+ throw std::runtime_error("Not supported optional input, yet");
+ }
+
const auto &operands = execution->plan().model().operands();
// TODO Check type conflicts
- // NOTE The current implemenation assumes that every input is a feature map.
- // TODO Remove this assumption
- neurun::graph::operand::IO::Index input_index{index};
+ neurun::model::operand::IO::Index input_index{index};
const auto operand_index = execution->plan().model().getInputs().at(input_index);
+ const auto data_type = operands.at(operand_index).typeInfo().type();
+ const auto operand_shape = operands.at(operand_index).shape();
- if (operands.at(operand_index).shape().rank() == 2)
- {
- assert(operands.at(operand_index).shape().dim(0) == 1);
-
- const auto len = operands.at(operand_index).shape().dim(1);
-
- execution->source<neurun::exec::VectorSource>(
- index, len, reinterpret_cast<const uint8_t *>(buffer), length);
- }
- else if (operands.at(operand_index).shape().rank() == 4)
- {
- const auto &operand_shape = operands.at(operand_index).shape().asFeature();
-
- execution->source<neurun::exec::FeatureSource>(
- index, operand_shape, reinterpret_cast<const uint8_t *>(buffer), length);
- }
- else
- {
- throw std::runtime_error{"Not supported, yet"};
- }
+ source(execution, data_type, index, buffer, length);
return ANEURALNETWORKS_NO_ERROR;
}
@@ -108,36 +216,23 @@ int ANeuralNetworksExecution_setOutput(ANeuralNetworksExecution *execution, int3
return ANEURALNETWORKS_UNEXPECTED_NULL;
}
+ // Handle optional output
+ if (buffer == nullptr)
+ {
+ return ANEURALNETWORKS_NO_ERROR;
+ }
+
const auto &operands = execution->plan().model().operands();
// TODO Check type conflicts
- // NOTE The current implemenation assumes that every output is a feature map.
- // TODO Remove this assumption
- neurun::graph::operand::IO::Index output_index{index};
+ neurun::model::operand::IO::Index output_index{index};
const auto operand_index = execution->plan().model().getOutputs().at(output_index);
+ const auto data_type = operands.at(operand_index).typeInfo().type();
+ const auto operand_shape = operands.at(operand_index).shape();
- if (operands.at(operand_index).shape().rank() == 2)
- {
- assert(operands.at(operand_index).shape().dim(0) == 1);
-
- const auto len = operands.at(operand_index).shape().dim(1);
-
- execution->sink<neurun::exec::VectorSink>(index, len, reinterpret_cast<uint8_t *>(buffer),
- length);
- }
- else if (operands.at(operand_index).shape().rank() == 4)
- {
- const auto &operand_shape = operands.at(operand_index).shape().asFeature();
-
- execution->sink<neurun::exec::FeatureSink>(index, operand_shape,
- reinterpret_cast<uint8_t *>(buffer), length);
- }
- else
- {
- throw std::runtime_error{"Not supported, yet"};
- }
+ sink(execution, data_type, index, buffer, length);
return ANEURALNETWORKS_NO_ERROR;
}
@@ -163,17 +258,16 @@ int ANeuralNetworksExecution_startCompute(ANeuralNetworksExecution *execution,
// Set input(s)
for (uint32_t n = 0; n < model.getInputs().size(); ++n)
{
- auto setter = [&](::arm_compute::ITensor &tensor) { execution->source(n).push(tensor); };
+ auto setter = [&](::neurun::backend::operand::ITensor &tensor) {
+ execution->source(n).push(tensor);
+ };
- neurun::graph::operand::IO::Index input_index{n};
+ neurun::model::operand::IO::Index input_index{n};
- ::neurun::graph::operand::Index index{model.getInputs().at(input_index)};
- auto objects = plan.operands().at(index);
+ ::neurun::model::operand::Index index{model.getInputs().at(input_index)};
+ auto object = plan.operands().at(index);
- for (auto object : objects)
- {
- object->access(setter);
- }
+ object->access(setter);
}
const auto &operations = execution->plan().operations();
@@ -186,17 +280,16 @@ int ANeuralNetworksExecution_startCompute(ANeuralNetworksExecution *execution,
// Get output(s)
for (uint32_t n = 0; n < model.getOutputs().size(); ++n)
{
- auto getter = [&](::arm_compute::ITensor &tensor) { execution->sink(n).pull(tensor); };
+ auto getter = [&](::neurun::backend::operand::ITensor &tensor) {
+ execution->sink(n).pull(tensor);
+ };
- neurun::graph::operand::IO::Index output_index{n};
+ neurun::model::operand::IO::Index output_index{n};
- ::neurun::graph::operand::Index index{model.getOutputs().at(output_index)};
- auto objects = plan.operands().at(index);
+ ::neurun::model::operand::Index index{model.getOutputs().at(output_index)};
+ auto object = plan.operands().at(index);
- for (auto object : objects)
- {
- object->access(getter);
- }
+ object->access(getter);
}
return ANEURALNETWORKS_NO_ERROR;
diff --git a/runtimes/neurun/src/frontend/memory.cc b/runtimes/neurun/src/frontend/memory.cc
index cc891feef..b2f6ab2d0 100644
--- a/runtimes/neurun/src/frontend/memory.cc
+++ b/runtimes/neurun/src/frontend/memory.cc
@@ -19,7 +19,7 @@
#include <new>
#include <memory>
-#include "nnfw/std/memory.h"
+#include "cpp14/memory.h"
#include "frontend/wrapper/memory.h"
int ANeuralNetworksMemory_createFromFd(size_t size, int protect, int fd, size_t offset,
@@ -32,7 +32,7 @@ int ANeuralNetworksMemory_createFromFd(size_t size, int protect, int fd, size_t
// Use unique pointer to avoid memory leak
std::unique_ptr<ANeuralNetworksMemory> memory_ptr =
- nnfw::make_unique<ANeuralNetworksMemory>(size, protect, fd, offset);
+ nnfw::cpp14::make_unique<ANeuralNetworksMemory>(size, protect, fd, offset);
if (memory_ptr == nullptr)
{
return ANEURALNETWORKS_OUT_OF_MEMORY;
diff --git a/runtimes/neurun/src/frontend/model.cc b/runtimes/neurun/src/frontend/model.cc
index 28a9b2515..3aa2aa2ff 100644
--- a/runtimes/neurun/src/frontend/model.cc
+++ b/runtimes/neurun/src/frontend/model.cc
@@ -21,18 +21,12 @@
#include <stdexcept>
#include <new>
-#include "nnfw/std/memory.h"
+#include "cpp14/memory.h"
#include "graph/Graph.h"
#include "frontend/wrapper/model.h"
#include "frontend/wrapper/memory.h"
-#include "graph/operation/AvgPool2D.h"
-#include "graph/operation/Concat.h"
-#include "graph/operation/Conv2D.h"
-#include "graph/operation/FullyConnected.h"
-#include "graph/operation/MaxPool2D.h"
-#include "graph/operation/Reshape.h"
-#include "graph/operation/Softmax.h"
+#include "model/operation/Node.Include.h"
int ANeuralNetworksModel_create(ANeuralNetworksModel **model)
{
@@ -94,8 +88,8 @@ int ANeuralNetworksModel_addOperand(ANeuralNetworksModel *model,
return ANEURALNETWORKS_BAD_DATA;
}
- ::neurun::graph::operand::Shape shape(type->dimensionCount);
- ::neurun::graph::operand::TypeInfo typeInfo((OperandCode)(type->type), type->scale,
+ ::neurun::model::operand::Shape shape(type->dimensionCount);
+ ::neurun::model::operand::TypeInfo typeInfo((OperandCode)(type->type), type->scale,
type->zeroPoint);
for (uint32_t axis = 0; axis < type->dimensionCount; ++axis)
@@ -115,6 +109,8 @@ int ANeuralNetworksModel_addOperand(ANeuralNetworksModel *model,
int ANeuralNetworksModel_setOperandValue(ANeuralNetworksModel *model, int32_t index,
const void *buffer, size_t length)
{
+ const bool isOptional = ((buffer == nullptr) && (length == 0));
+
if ((model == nullptr) || ((buffer == nullptr) && (length != 0)))
{
return ANEURALNETWORKS_UNEXPECTED_NULL;
@@ -130,7 +126,7 @@ int ANeuralNetworksModel_setOperandValue(ANeuralNetworksModel *model, int32_t in
{
return ANEURALNETWORKS_BAD_DATA;
}
- const neurun::graph::operand::Index ind{static_cast<uint32_t>(index)};
+ const neurun::model::operand::Index ind{static_cast<uint32_t>(index)};
if (!model->deref().operands().exist(ind))
{
@@ -138,7 +134,7 @@ int ANeuralNetworksModel_setOperandValue(ANeuralNetworksModel *model, int32_t in
}
auto &obj = model->deref().operands().at(ind);
- if (obj.operandSize() != length)
+ if ((obj.operandSize() != length) && !isOptional)
{
return ANEURALNETWORKS_BAD_DATA;
}
@@ -147,10 +143,30 @@ int ANeuralNetworksModel_setOperandValue(ANeuralNetworksModel *model, int32_t in
return ANEURALNETWORKS_BAD_DATA;
}
- using ::neurun::graph::operand::CachedData;
+ using ::neurun::model::operand::CachedData;
+ using ::neurun::model::operand::ExternalData;
- model->deref().setOperandValue(
- ind, nnfw::make_unique<CachedData>(reinterpret_cast<const uint8_t *>(buffer), length));
+ // Remain operands.at(ind).data()->base() as nullptr for optional operand
+ // This will be filled when model finished
+ if (isOptional)
+ {
+ model->setOptionalOperand(ind);
+ }
+
+ // NNAPI spec in NeuralNetworks.h
+ // For values of length greater than ANEURALNETWORKS_MAX_SIZE_OF_IMMEDIATELY_COPIED_VALUES,
+ // the application is responsible for not changing the content of this region
+ // until all executions using this model have completed
+ if (length <= ANEURALNETWORKS_MAX_SIZE_OF_IMMEDIATELY_COPIED_VALUES)
+ {
+ model->deref().setOperandValue(ind, nnfw::cpp14::make_unique<CachedData>(
+ reinterpret_cast<const uint8_t *>(buffer), length));
+ }
+ else
+ {
+ model->deref().setOperandValue(ind, nnfw::cpp14::make_unique<ExternalData>(
+ reinterpret_cast<const uint8_t *>(buffer), length));
+ }
return ANEURALNETWORKS_NO_ERROR;
}
@@ -174,7 +190,7 @@ int ANeuralNetworksModel_setOperandValueFromMemory(ANeuralNetworksModel *model,
{
return ANEURALNETWORKS_BAD_DATA;
}
- const neurun::graph::operand::Index ind{static_cast<uint32_t>(index)};
+ const neurun::model::operand::Index ind{static_cast<uint32_t>(index)};
if (!model->deref().operands().exist(ind))
{
@@ -191,10 +207,10 @@ int ANeuralNetworksModel_setOperandValueFromMemory(ANeuralNetworksModel *model,
return ANEURALNETWORKS_BAD_DATA;
}
- using ::neurun::graph::operand::ExternalData;
+ using ::neurun::model::operand::ExternalData;
model->deref().setOperandValue(
- ind, nnfw::make_unique<ExternalData>(
+ ind, nnfw::cpp14::make_unique<ExternalData>(
reinterpret_cast<const uint8_t *>(memory->base() + offset), length));
return ANEURALNETWORKS_NO_ERROR;
@@ -210,6 +226,13 @@ int ANeuralNetworksModel_addOperation(ANeuralNetworksModel *model,
return ANEURALNETWORKS_UNEXPECTED_NULL;
}
+ const ANeuralNetworksOperationType FIRST_OPERATION = ANEURALNETWORKS_ADD;
+ const ANeuralNetworksOperationType LAST_OPERATION = ANEURALNETWORKS_TRANSPOSE;
+ if ((type < FIRST_OPERATION) || (type > LAST_OPERATION))
+ {
+ return ANEURALNETWORKS_BAD_DATA;
+ }
+
if (model->isFinished())
{
return ANEURALNETWORKS_BAD_STATE;
@@ -217,7 +240,7 @@ int ANeuralNetworksModel_addOperation(ANeuralNetworksModel *model,
for (uint32_t i = 0; i < outputCount; i++)
{
- const ::neurun::graph::operand::Index ind{outputs[i]};
+ const ::neurun::model::operand::Index ind{outputs[i]};
auto &obj = model->deref().operands().at(ind);
if (!obj.setAsOperationOutput())
@@ -229,108 +252,115 @@ int ANeuralNetworksModel_addOperation(ANeuralNetworksModel *model,
auto &graph = model->deref();
auto node_param =
- neurun::graph::operation::Node::InitParam{inputCount, inputs, outputCount, outputs};
+ neurun::model::operation::Node::InitParam{inputCount, inputs, outputCount, outputs};
- switch (type)
+ try
{
- case ANEURALNETWORKS_CONV_2D:
+ switch (type)
{
- // inputCount is either 7 or 10 acccording to NN API specification.
- // - Padding is implicit when inputCount is 7
- // - Padding is explicit when inputCount is 10
- assert(inputCount == 7 || inputCount == 10);
- assert(outputCount == 1);
-
- if (inputCount == 7)
+ case ANEURALNETWORKS_CONV_2D:
{
- using GraphNode = neurun::graph::operation::Conv2D::Implicit::Node;
-
- graph.addOperation(nnfw::make_unique<GraphNode>(node_param));
+ // inputCount is either 7 or 10 acccording to NN API specification.
+ // - Padding is implicit when inputCount is 7
+ // - Padding is explicit when inputCount is 10
+ assert(inputCount == 7 || inputCount == 10);
+ assert(outputCount == 1);
+
+ if (inputCount == 7)
+ {
+ using GraphNode = neurun::model::operation::Conv2DNode;
+
+ graph.addOperation(nnfw::cpp14::make_unique<GraphNode>(node_param));
+ }
+ else
+ {
+ throw std::runtime_error{"Explicit padding in Conv2D is not supported, yet"};
+ }
+
+ break;
}
- else
+ case ANEURALNETWORKS_MAX_POOL_2D:
{
- throw std::runtime_error{"Explicit padding in Conv2D is not supported, yet"};
+ // inputCount is either 7 or 10 acccording to NN API specification.
+ // - Padding is implicit when inputCount is 7
+ // - Padding is explicit when inputCount is 10
+ assert(inputCount == 7 || inputCount == 10);
+ assert(outputCount == 1);
+
+ if (inputCount == 7)
+ {
+ using GraphNode = neurun::model::operation::MaxPool2DNode;
+
+ graph.addOperation(nnfw::cpp14::make_unique<GraphNode>(node_param));
+ }
+ else
+ {
+ throw std::runtime_error{"Explicit padding in MaxPool2D is not supported, yet"};
+ }
+
+ break;
}
-
- break;
- }
- case ANEURALNETWORKS_MAX_POOL_2D:
- {
- // inputCount is either 7 or 10 acccording to NN API specification.
- // - Padding is implicit when inputCount is 7
- // - Padding is explicit when inputCount is 10
- assert(inputCount == 7 || inputCount == 10);
- assert(outputCount == 1);
-
- if (inputCount == 7)
+ case ANEURALNETWORKS_AVERAGE_POOL_2D:
{
- using GraphNode = neurun::graph::operation::MaxPool2D::Implicit::Node;
-
- graph.addOperation(nnfw::make_unique<GraphNode>(node_param));
+ // inputCount is either 7 or 10 acccording to NN API specification.
+ // - Padding is implicit when inputCount is 7
+ // - Padding is explicit when inputCount is 10
+ assert(inputCount == 7 || inputCount == 10);
+ assert(outputCount == 1);
+
+ if (inputCount == 7)
+ {
+ using GraphNode = neurun::model::operation::AvgPool2DNode;
+
+ graph.addOperation(nnfw::cpp14::make_unique<GraphNode>(node_param));
+ }
+ else
+ {
+ throw std::runtime_error{"Explicit padding in AvgPool2D is not supported, yet"};
+ }
+
+ break;
}
- else
+ case ANEURALNETWORKS_CONCATENATION:
{
- throw std::runtime_error{"Explicit padding in MaxPool2D is not supported, yet"};
- }
-
- break;
- }
- case ANEURALNETWORKS_AVERAGE_POOL_2D:
- {
- // inputCount is either 7 or 10 acccording to NN API specification.
- // - Padding is implicit when inputCount is 7
- // - Padding is explicit when inputCount is 10
- assert(inputCount == 7 || inputCount == 10);
- assert(outputCount == 1);
+ using GraphNode = neurun::model::operation::ConcatNode;
- if (inputCount == 7)
- {
- using GraphNode = neurun::graph::operation::AvgPool2D::Implicit::Node;
+ graph.addOperation(nnfw::cpp14::make_unique<GraphNode>(node_param));
- graph.addOperation(nnfw::make_unique<GraphNode>(node_param));
+ break;
}
- else
+ case ANEURALNETWORKS_RESHAPE:
{
- throw std::runtime_error{"Explicit padding in AvgPool2D is not supported, yet"};
- }
-
- break;
- }
- case ANEURALNETWORKS_CONCATENATION:
- {
- using GraphNode = neurun::graph::operation::Concat::Node;
+ using GraphNode = neurun::model::operation::ReshapeNode;
- graph.addOperation(nnfw::make_unique<GraphNode>(node_param));
+ graph.addOperation(nnfw::cpp14::make_unique<GraphNode>(node_param));
- break;
- }
- case ANEURALNETWORKS_RESHAPE:
- {
- using GraphNode = neurun::graph::operation::Reshape::Node;
-
- graph.addOperation(nnfw::make_unique<GraphNode>(node_param));
-
- break;
- }
- case ANEURALNETWORKS_FULLY_CONNECTED:
- {
- using GraphNode = neurun::graph::operation::FullyConnected::Node;
+ break;
+ }
+ case ANEURALNETWORKS_FULLY_CONNECTED:
+ {
+ using GraphNode = neurun::model::operation::FullyConnectedNode;
- graph.addOperation(nnfw::make_unique<GraphNode>(node_param));
+ graph.addOperation(nnfw::cpp14::make_unique<GraphNode>(node_param));
- break;
- }
- case ANEURALNETWORKS_SOFTMAX:
- {
- using GraphNode = neurun::graph::operation::Softmax::Node;
+ break;
+ }
+ case ANEURALNETWORKS_SOFTMAX:
+ {
+ using GraphNode = neurun::model::operation::SoftmaxNode;
- graph.addOperation(nnfw::make_unique<GraphNode>(node_param));
+ graph.addOperation(nnfw::cpp14::make_unique<GraphNode>(node_param));
- break;
- }
- default:
- throw std::runtime_error{"Not supported operation"};
- };
+ break;
+ }
+ default:
+ throw std::runtime_error{"Not supported operation"};
+ };
+ }
+ catch (const std::exception &e)
+ {
+ return ANEURALNETWORKS_BAD_STATE;
+ }
return ANEURALNETWORKS_NO_ERROR;
}
@@ -350,9 +380,16 @@ int ANeuralNetworksModel_addOperationEx(ANeuralNetworksModel *model,
return ANEURALNETWORKS_BAD_STATE;
}
+ const ANeuralNetworksOperationTypeEx FIRST_OPERATION = ANEURALNETWORKS_GATHER_EX;
+ const ANeuralNetworksOperationTypeEx LAST_OPERATION = ANEURALNETWORKS_PRELU_EX;
+ if ((type < FIRST_OPERATION) || (type > LAST_OPERATION))
+ {
+ return ANEURALNETWORKS_BAD_DATA;
+ }
+
for (uint32_t i = 0; i < outputCount; i++)
{
- const ::neurun::graph::operand::Index ind{outputs[i]};
+ const ::neurun::model::operand::Index ind{outputs[i]};
auto &obj = model->deref().operands().at(ind);
if (!obj.setAsOperationOutput())
@@ -367,11 +404,20 @@ int ANeuralNetworksModel_addOperationEx(ANeuralNetworksModel *model,
return ANEURALNETWORKS_BAD_DATA;
}
- switch (type)
+ try
{
- default:
- throw std::runtime_error{"Not supported operation"};
+ switch (type)
+ {
+ default:
+ throw std::runtime_error{"Not supported operation"};
+ }
}
+ catch (const std::exception &e)
+ {
+ return ANEURALNETWORKS_BAD_STATE;
+ }
+
+ return ANEURALNETWORKS_NO_ERROR;
}
int ANeuralNetworksModel_identifyInputsAndOutputs(ANeuralNetworksModel *model, uint32_t inputCount,
@@ -388,7 +434,7 @@ int ANeuralNetworksModel_identifyInputsAndOutputs(ANeuralNetworksModel *model, u
return ANEURALNETWORKS_BAD_STATE;
}
- // NOTE ::neurun::graph::operand::Index uses int as its underlying type as various NNAPI
+ // NOTE ::neurun::model::operand::Index uses int as its underlying type as various NNAPI
// functions such as ANeuralNetworksModel_setOperandValue use int to represent operand index
//
// ANeuralNetworksModel_identifyInputsAndOutputs, however, uses uint32_t to represent operand
@@ -397,7 +443,7 @@ int ANeuralNetworksModel_identifyInputsAndOutputs(ANeuralNetworksModel *model, u
// Below, static_cast<int>(...) is introduced to eliminate compiler warning.
for (uint32_t n = 0; n < inputCount; ++n)
{
- const neurun::graph::operand::Index ind{static_cast<uint32_t>(inputs[n])};
+ const neurun::model::operand::Index ind{static_cast<uint32_t>(inputs[n])};
model->deref().addInput(ind);
auto &obj = model->deref().operands().at(ind);
@@ -409,7 +455,7 @@ int ANeuralNetworksModel_identifyInputsAndOutputs(ANeuralNetworksModel *model, u
for (uint32_t n = 0; n < outputCount; ++n)
{
- const neurun::graph::operand::Index ind{static_cast<uint32_t>(outputs[n])};
+ const neurun::model::operand::Index ind{static_cast<uint32_t>(outputs[n])};
model->deref().addOutput(ind);
auto &obj = model->deref().operands().at(ind);
diff --git a/runtimes/neurun/src/frontend/wrapper/compilation.cc b/runtimes/neurun/src/frontend/wrapper/compilation.cc
index 4ff33faa5..e4aa99f7a 100644
--- a/runtimes/neurun/src/frontend/wrapper/compilation.cc
+++ b/runtimes/neurun/src/frontend/wrapper/compilation.cc
@@ -14,53 +14,18 @@
* limitations under the License.
*/
-#include <NeuralNetworks.h>
-
-#include <algorithm>
-
-#include <arm_compute/core/CL/ICLTensor.h>
-
-#include <arm_compute/runtime/IFunction.h>
-#include <arm_compute/runtime/CL/CLScheduler.h>
-
-#include "internal/Convert.h"
-#include "backend/acl_cl/kernel/View.h"
-#include "backend/acl_cl/TensorBuilder.h"
-#include "internal/nnapi/kernel/Reader.h"
-#include "internal/Padding.h"
-#include "backend/IInitializerGenerator.h"
-#include "backend/IStageGenerator.h"
-
#include "compilation.h"
-#include "model.h"
-#include "logging.h"
-
-#include "graph/dumper/Dumper.h"
-#include "codegen/IPlanBuilder.h"
-#include "codegen/Planner.h"
-#include "codegen/PlanBuilder.h"
-
-#include "linear/Linear.h"
int ANeuralNetworksCompilation::finish()
{
- auto &plan = this->plan();
- const auto &operands = plan.model().operands();
-
- plan.model().lower();
- auto linear = plan.model().linearize();
-
- // Dump ops
- linear->accept(neurun::graph::dumper::Dumper{});
-
- neurun::codegen::PlanBuilder plan_builder{plan};
-
- auto tensor_builders = linear->markTensors();
-
- linear->accept(neurun::codegen::Planner{operands, plan_builder});
-
- // TODO Add optimization passes
- plan_builder.finalize(tensor_builders);
+ try
+ {
+ _compiler->compile();
+ }
+ catch (const std::exception &e)
+ {
+ return ANEURALNETWORKS_BAD_STATE;
+ }
return ANEURALNETWORKS_NO_ERROR;
}
diff --git a/runtimes/neurun/src/frontend/wrapper/compilation.h b/runtimes/neurun/src/frontend/wrapper/compilation.h
index 20d5a3d98..d4ba32ea5 100644
--- a/runtimes/neurun/src/frontend/wrapper/compilation.h
+++ b/runtimes/neurun/src/frontend/wrapper/compilation.h
@@ -17,27 +17,27 @@
#ifndef __COMPILATION_H__
#define __COMPILATION_H__
-#include "codegen/Plan.h"
+#include "compiler/Compiler.h"
#include "graph/Graph.h"
struct ANeuralNetworksCompilation
{
public:
ANeuralNetworksCompilation(const std::shared_ptr<neurun::graph::Graph> &model)
- : _plan{new neurun::codegen::Plan{model}}
+ : _compiler{new neurun::compiler::Compiler{model}}
{
// DO NOTHING
}
public:
- neurun::codegen::Plan &plan(void) { return *_plan; }
+ neurun::compiler::Plan &plan(void) { return _compiler->plan(); }
public:
- void publish(std::shared_ptr<const neurun::codegen::Plan> &plan) { plan = _plan; }
+ void publish(std::shared_ptr<const neurun::compiler::Plan> &plan) { _compiler->release(plan); }
int finish();
private:
- std::shared_ptr<neurun::codegen::Plan> _plan;
+ std::shared_ptr<neurun::compiler::Compiler> _compiler;
};
#endif
diff --git a/runtimes/neurun/src/frontend/wrapper/execution.h b/runtimes/neurun/src/frontend/wrapper/execution.h
index 374201eb2..b68a7b967 100644
--- a/runtimes/neurun/src/frontend/wrapper/execution.h
+++ b/runtimes/neurun/src/frontend/wrapper/execution.h
@@ -17,28 +17,28 @@
#ifndef __EXECUTION_H__
#define __EXECUTION_H__
-#include "codegen/Plan.h"
+#include "compiler/Plan.h"
#include "exec/Source.h"
#include "exec/Sink.h"
struct ANeuralNetworksExecution
{
public:
- ANeuralNetworksExecution(const std::shared_ptr<const neurun::codegen::Plan> &plan) : _plan{plan}
+ ANeuralNetworksExecution(const std::shared_ptr<const neurun::compiler::Plan> &plan) : _plan{plan}
{
_sources.resize(_plan->model().getInputs().size());
_sinks.resize(_plan->model().getOutputs().size());
}
public:
- const neurun::codegen::Plan &plan(void) const { return *_plan; }
+ const neurun::compiler::Plan &plan(void) const { return *_plan; }
private:
- std::shared_ptr<const neurun::codegen::Plan> _plan;
+ std::shared_ptr<const neurun::compiler::Plan> _plan;
public:
// TODO Use InputIndex instead of int
- void source(int n, std::unique_ptr<neurun::exec::Source> &&source)
+ void source(int n, std::unique_ptr<neurun::exec::ISource> &&source)
{
_sources.at(n) = std::move(source);
}
@@ -48,22 +48,22 @@ public:
}
public:
- const neurun::exec::Source &source(int n) const { return *(_sources.at(n)); }
+ const neurun::exec::ISource &source(int n) const { return *(_sources.at(n)); }
public:
// TODO Use OutputIndex instead of int
- void sink(int n, std::unique_ptr<neurun::exec::Sink> &&sink) { _sinks.at(n) = std::move(sink); }
+ void sink(int n, std::unique_ptr<neurun::exec::ISink> &&sink) { _sinks.at(n) = std::move(sink); }
template <typename T, typename... Args> void sink(int n, Args &&... args)
{
sink(n, std::unique_ptr<T>{new T{std::forward<Args>(args)...}});
}
public:
- const neurun::exec::Sink &sink(int n) const { return *(_sinks.at(n)); }
+ const neurun::exec::ISink &sink(int n) const { return *(_sinks.at(n)); }
private:
- std::vector<std::unique_ptr<neurun::exec::Source>> _sources;
- std::vector<std::unique_ptr<neurun::exec::Sink>> _sinks;
+ std::vector<std::unique_ptr<neurun::exec::ISource>> _sources;
+ std::vector<std::unique_ptr<neurun::exec::ISink>> _sinks;
};
#endif
diff --git a/runtimes/neurun/src/frontend/wrapper/model.cc b/runtimes/neurun/src/frontend/wrapper/model.cc
index c7ccbc60a..a7a9275fc 100644
--- a/runtimes/neurun/src/frontend/wrapper/model.cc
+++ b/runtimes/neurun/src/frontend/wrapper/model.cc
@@ -21,7 +21,8 @@
//
// ANeuralNetworksModel
//
-ANeuralNetworksModel::ANeuralNetworksModel() : _model{new neurun::graph::Graph}
+ANeuralNetworksModel::ANeuralNetworksModel()
+ : _model{new neurun::graph::Graph}, _optional_operands{}
{
// DO NOTHING
}
@@ -34,7 +35,24 @@ ResultCode ANeuralNetworksModel::finish()
return ANEURALNETWORKS_BAD_STATE;
}
+ fillOptionalOperand();
+
_model->finishBuilding();
return ANEURALNETWORKS_NO_ERROR;
}
+
+void ANeuralNetworksModel::fillOptionalOperand(void)
+{
+ _model->operations().iterate(
+ [&](const ::neurun::model::operation::Index &, ::neurun::model::operation::Node &node) {
+ for (auto input : node.getInputs())
+ {
+ // TODO fill default value for optional operands
+ if (_optional_operands.find(input) != _optional_operands.end())
+ {
+ throw std::runtime_error{"Optional operand is not supported yet"};
+ }
+ }
+ });
+}
diff --git a/runtimes/neurun/src/frontend/wrapper/model.h b/runtimes/neurun/src/frontend/wrapper/model.h
index 3c7b027dc..2386a648d 100644
--- a/runtimes/neurun/src/frontend/wrapper/model.h
+++ b/runtimes/neurun/src/frontend/wrapper/model.h
@@ -30,12 +30,18 @@ public:
neurun::graph::Graph &deref(void) { return *_model; }
ResultCode finish();
bool isFinished() { return !_model->isBuildingPhase(); }
-
-public:
void release(std::shared_ptr<neurun::graph::Graph> &model) { model = _model; }
+ void setOptionalOperand(const neurun::model::operand::Index idx)
+ {
+ _optional_operands.insert(idx);
+ }
+
+private:
+ void fillOptionalOperand(void);
private:
std::shared_ptr<neurun::graph::Graph> _model;
+ std::unordered_set<neurun::model::operand::Index> _optional_operands;
};
#endif // __MODEL_H__