diff options
Diffstat (limited to 'runtimes/neurun/src/frontend')
-rw-r--r-- | runtimes/neurun/src/frontend/compilation.cc | 5 | ||||
-rw-r--r-- | runtimes/neurun/src/frontend/execution.cc | 221 | ||||
-rw-r--r-- | runtimes/neurun/src/frontend/memory.cc | 4 | ||||
-rw-r--r-- | runtimes/neurun/src/frontend/model.cc | 262 | ||||
-rw-r--r-- | runtimes/neurun/src/frontend/wrapper/compilation.cc | 51 | ||||
-rw-r--r-- | runtimes/neurun/src/frontend/wrapper/compilation.h | 10 | ||||
-rw-r--r-- | runtimes/neurun/src/frontend/wrapper/execution.h | 20 | ||||
-rw-r--r-- | runtimes/neurun/src/frontend/wrapper/model.cc | 20 | ||||
-rw-r--r-- | runtimes/neurun/src/frontend/wrapper/model.h | 10 |
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__ |