summaryrefslogtreecommitdiff
path: root/runtimes/nn/common/Utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'runtimes/nn/common/Utils.cpp')
-rw-r--r--runtimes/nn/common/Utils.cpp397
1 files changed, 0 insertions, 397 deletions
diff --git a/runtimes/nn/common/Utils.cpp b/runtimes/nn/common/Utils.cpp
deleted file mode 100644
index 7f0adea8e..000000000
--- a/runtimes/nn/common/Utils.cpp
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright (C) 2017 The Android Open Source Project
- *
- * 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 "Utils.h"
-#include "NeuralNetworks.h"
-
-namespace nnfw {
-namespace rt {
-
-#define COUNT(X) (sizeof(X) / sizeof(X[0]))
-
-const char* kTypeNames[kNumberOfDataTypes] = {
- "FLOAT32", "INT32", "UINT32",
- "TENSOR_FLOAT32", "TENSOR_INT32", "TENSOR_QUANT8_ASYMM",
-};
-
-static_assert(COUNT(kTypeNames) == kNumberOfDataTypes, "kTypeNames is incorrect");
-
-const char* kTypeNamesOEM[kNumberOfDataTypesOEM] = {
- "OEM", "TENSOR_OEM_BYTE",
-};
-
-static_assert(COUNT(kTypeNamesOEM) == kNumberOfDataTypesOEM, "kTypeNamesOEM is incorrect");
-
-// TODO Check if this useful
-const char* kErrorNames[] = {
- "NO_ERROR", "OUT_OF_MEMORY", "INCOMPLETE", "NULL", "BAD_DATA",
-};
-
-namespace {
-
-template <typename EntryType, uint32_t entryCount, uint32_t entryCountOEM>
-EntryType tableLookup(const EntryType (&table)[entryCount],
- const EntryType (&tableOEM)[entryCountOEM],
- uint32_t code) {
- if (code < entryCount) {
- return table[code];
- } else if (code >= kOEMCodeBase && (code - kOEMCodeBase) < entryCountOEM) {
- return tableOEM[code - kOEMCodeBase];
- } else {
- nnAssert(!"tableLookup: bad code");
- return EntryType();
- }
-}
-
-}; // anonymous namespace
-
-const char* kOperationNames[kNumberOfOperationTypes] = {
- "ADD",
- "AVERAGE_POOL",
- "CONCATENATION",
- "CONV",
- "DEPTHWISE_CONV",
- "DEPTH_TO_SPACE",
- "DEQUANTIZE",
- "EMBEDDING_LOOKUP",
- "FLOOR",
- "FULLY_CONNECTED",
- "HASHTABLE_LOOKUP",
- "L2_NORMALIZATION",
- "L2_POOL",
- "LOCAL_RESPONSE_NORMALIZATION",
- "LOGISTIC",
- "LSH_PROJECTION",
- "LSTM",
- "MAX_POOL",
- "MUL",
- "RELU",
- "RELU1",
- "RELU6",
- "RESHAPE",
- "RESIZE_BILINEAR",
- "RNN",
- "SOFTMAX",
- "SPACE_TO_DEPTH",
- "SVDF",
- "TANH",
-};
-
-static_assert(COUNT(kOperationNames) == kNumberOfOperationTypes, "kOperationNames is incorrect");
-
-const char* kOperationNamesOEM[kNumberOfOperationTypesOEM] = {
- "OEM_OPERATION",
-};
-
-static_assert(COUNT(kOperationNamesOEM) == kNumberOfOperationTypesOEM,
- "kOperationNamesOEM is incorrect");
-
-const char* getOperationName(OperationType type) {
- uint32_t n = static_cast<uint32_t>(type);
- return tableLookup(kOperationNames, kOperationNamesOEM, n);
-}
-
-const uint32_t kSizeOfDataType[]{
- 4, // ANEURALNETWORKS_FLOAT32
- 4, // ANEURALNETWORKS_INT32
- 4, // ANEURALNETWORKS_UINT32
- 4, // ANEURALNETWORKS_TENSOR_FLOAT32
- 4, // ANEURALNETWORKS_TENSOR_INT32
- 1 // ANEURALNETWORKS_TENSOR_SYMMETRICAL_QUANT8
-};
-
-static_assert(COUNT(kSizeOfDataType) == kNumberOfDataTypes, "kSizeOfDataType is incorrect");
-
-const bool kScalarDataType[]{
- true, // ANEURALNETWORKS_FLOAT32
- true, // ANEURALNETWORKS_INT32
- true, // ANEURALNETWORKS_UINT32
- false, // ANEURALNETWORKS_TENSOR_FLOAT32
- false, // ANEURALNETWORKS_TENSOR_INT32
- false, // ANEURALNETWORKS_TENSOR_SYMMETRICAL_QUANT8
-};
-
-static_assert(COUNT(kScalarDataType) == kNumberOfDataTypes, "kScalarDataType is incorrect");
-
-const uint32_t kSizeOfDataTypeOEM[]{
- 0, // ANEURALNETWORKS_OEM
- 1, // ANEURALNETWORKS_TENSOR_OEM_BYTE
-};
-
-static_assert(COUNT(kSizeOfDataTypeOEM) == kNumberOfDataTypesOEM,
- "kSizeOfDataTypeOEM is incorrect");
-
-const bool kScalarDataTypeOEM[]{
- true, // ANEURALNETWORKS_OEM
- false, // ANEURALNETWORKS_TENSOR_OEM_BYTE
-};
-
-static_assert(COUNT(kScalarDataTypeOEM) == kNumberOfDataTypesOEM,
- "kScalarDataTypeOEM is incorrect");
-
-uint32_t sizeOfData(OperandType type, const std::vector<uint32_t>& dimensions) {
- int n = static_cast<int>(type);
-
- uint32_t size = tableLookup(kSizeOfDataType, kSizeOfDataTypeOEM, n);
-
- if (tableLookup(kScalarDataType, kScalarDataTypeOEM, n) == true) {
- return size;
- }
-
- for (auto d : dimensions) {
- size *= d;
- }
- return size;
-}
-
-// TODO-NNRT : Should be changed to allocate hidl_memory using Allocator.
-// And Should change naming to "allocateMemory".
-hidl_memory allocateSharedMemory(int64_t size) {
- hidl_memory memory;
-#if 0 // TODO-NNRT : Use shared memory or hidl memory
-
- // TODO: should we align memory size to nearest page? doesn't seem necessary...
- const std::string& type = "ashmem";
- sp<IAllocator> allocator = IAllocator::getService(type);
- allocator->allocate(size, [&](bool success, const hidl_memory& mem) {
- if (!success) {
- LOG(ERROR) << "unable to allocate " << size << " bytes of " << type;
- } else {
- memory = mem;
- }
- });
-#endif
- LOG(ERROR) << "Not support to allocate shared memory now.";
- return memory;
-}
-
-uint32_t alignBytesNeeded(uint32_t index, size_t length) {
- uint32_t pattern;
- if (length < 2) {
- pattern = 0; // No alignment necessary
- } else if (length < 4) {
- pattern = 1; // Align on 2-byte boundary
- } else {
- pattern = 3; // Align on 4-byte boundary
- }
- uint32_t extra = (~(index - 1)) & pattern;
- return extra;
-}
-
-// Validates the type. The used dimensions can be underspecified.
-int validateOperandType(const ANeuralNetworksOperandType& type, const char* tag,
- bool allowPartial) {
- if (!allowPartial) {
- for (uint32_t i = 0; i < type.dimensionCount; i++) {
- if (type.dimensions[i] == 0) {
- LOG(ERROR) << tag << " OperandType invalid dimensions[" << i
- << "] = " << type.dimensions[i];
- return ANEURALNETWORKS_BAD_DATA;
- }
- }
- }
- if (!validCode(kNumberOfDataTypes, kNumberOfDataTypesOEM, type.type)) {
- LOG(ERROR) << tag << " OperandType invalid type " << type.type;
- return ANEURALNETWORKS_BAD_DATA;
- }
- if (type.type == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM) {
- if (type.zeroPoint < 0 || type.zeroPoint > 255) {
- LOG(ERROR) << tag << " OperandType invalid zeroPoint " << type.zeroPoint;
- return ANEURALNETWORKS_BAD_DATA;
- }
- if (type.scale < 0.f) {
- LOG(ERROR) << tag << " OperandType invalid scale " << type.scale;
- return ANEURALNETWORKS_BAD_DATA;
- }
- }
-
- // TODO-NNRT : add 'type.type == ANEURALNETWORKS_OEM_SCALAR' later.
- // OEM operaters are not supported now.
- if (type.type == ANEURALNETWORKS_FLOAT32 ||
- type.type == ANEURALNETWORKS_INT32 ||
- type.type == ANEURALNETWORKS_UINT32) {
- if (type.dimensionCount != 0 || type.dimensions != nullptr) {
- LOG(ERROR) << tag << " Invalid dimensions for scalar type";
- return ANEURALNETWORKS_BAD_DATA;
- }
- }
-
- return ANEURALNETWORKS_NO_ERROR;
-}
-
-int validateOperandList(uint32_t count, const uint32_t* list, uint32_t operandCount,
- const char* tag) {
- for (uint32_t i = 0; i < count; i++) {
- if (list[i] >= operandCount) {
- LOG(ERROR) << tag << " invalid operand index at " << i << " = " << list[i]
- << ", operandCount " << operandCount;
- return ANEURALNETWORKS_BAD_DATA;
- }
- }
- return ANEURALNETWORKS_NO_ERROR;
-}
-
-static bool validOperandIndexes(const hidl_vec<uint32_t> indexes, size_t operandCount) {
- for (uint32_t i : indexes) {
- if (i >= operandCount) {
- LOG(ERROR) << "Index out of range " << i << "/" << operandCount;
- return false;
- }
- }
- return true;
-}
-
-static bool validOperands(const hidl_vec<Operand>& operands, const hidl_vec<uint8_t>& operandValues,
- size_t poolCount) {
- for (auto& operand : operands) {
- if (!validCode(kNumberOfDataTypes, kNumberOfDataTypesOEM,
- static_cast<uint32_t>(operand.type))) {
- LOG(ERROR) << "Invalid operand type ";
- return false;
- }
- /* TODO validate dim with type
- if (!validOperandIndexes(operand.dimensions, mDimensions)) {
- return false;
- }
- */
- switch (operand.lifetime) {
- case OperandLifeTime::CONSTANT_COPY:
- if (operand.location.offset + operand.location.length > operandValues.size()) {
- LOG(ERROR) << "OperandValue location out of range. Starts at "
- << operand.location.offset << ", length " << operand.location.length
- << ", max " << operandValues.size();
- return false;
- }
- break;
- case OperandLifeTime::TEMPORARY_VARIABLE:
- case OperandLifeTime::MODEL_INPUT:
- case OperandLifeTime::MODEL_OUTPUT:
- case OperandLifeTime::NO_VALUE:
- if (operand.location.offset != 0 || operand.location.length != 0) {
- LOG(ERROR) << "Unexpected offset " << operand.location.offset << " or length "
- << operand.location.length << " for runtime location.";
- return false;
- }
- break;
- case OperandLifeTime::CONSTANT_REFERENCE:
- if (operand.location.poolIndex >= poolCount) {
- LOG(ERROR) << "Invalid poolIndex " << operand.location.poolIndex << "/"
- << poolCount;
- return false;
- }
- break;
- // TODO: Validate that we are within the pool.
- default:
- LOG(ERROR) << "Invalid lifetime";
- return false;
- }
- }
- return true;
-}
-
-static bool validOperations(const hidl_vec<Operation>& operations, size_t operandCount) {
- for (auto& op : operations) {
- if (!validCode(kNumberOfOperationTypes, kNumberOfOperationTypesOEM,
- static_cast<uint32_t>(op.type))) {
- LOG(ERROR) << "Invalid operation type ";
- return false;
- }
- if (!validOperandIndexes(op.inputs, operandCount) ||
- !validOperandIndexes(op.outputs, operandCount)) {
- return false;
- }
- }
- return true;
-}
-
-// TODO doublecheck
-bool validateModel(const Model& model) {
- const size_t operandCount = model.operands.size();
- return (validOperands(model.operands, model.operandValues, model.pools.size()) &&
- validOperations(model.operations, operandCount) &&
- validOperandIndexes(model.inputIndexes, operandCount) &&
- validOperandIndexes(model.outputIndexes, operandCount));
-}
-
-bool validRequestArguments(const hidl_vec<RequestArgument>& arguments,
- const hidl_vec<uint32_t>& operandIndexes,
- const hidl_vec<Operand>& operands, size_t poolCount,
- const char* type) {
- const size_t argumentCount = arguments.size();
- if (argumentCount != operandIndexes.size()) {
- LOG(ERROR) << "Request specifies " << argumentCount << " " << type << "s but the model has "
- << operandIndexes.size();
- return false;
- }
- for (size_t argumentIndex = 0; argumentIndex < argumentCount; argumentIndex++) {
- const RequestArgument& argument = arguments[argumentIndex];
- const uint32_t operandIndex = operandIndexes[argumentIndex];
- const Operand& operand = operands[operandIndex];
- if (argument.hasNoValue) {
- if (argument.location.poolIndex != 0 ||
- argument.location.offset != 0 ||
- argument.location.length != 0 ||
- argument.dimensions.size() != 0) {
- LOG(ERROR) << "Request " << type << " " << argumentIndex
- << " has no value yet has details.";
- return false;
- }
- }
- if (argument.location.poolIndex >= poolCount) {
- LOG(ERROR) << "Request " << type << " " << argumentIndex << " has an invalid poolIndex "
- << argument.location.poolIndex << "/" << poolCount;
- return false;
- }
- // TODO: Validate that we are within the pool.
- uint32_t rank = argument.dimensions.size();
- if (rank > 0) {
- if (rank != operand.dimensions.size()) {
- LOG(ERROR) << "Request " << type << " " << argumentIndex
- << " has number of dimensions (" << rank
- << ") different than the model's (" << operand.dimensions.size() << ")";
- return false;
- }
- for (size_t i = 0; i < rank; i++) {
- if (argument.dimensions[i] != operand.dimensions[i] &&
- operand.dimensions[i] != 0) {
- LOG(ERROR) << "Request " << type << " " << argumentIndex
- << " has dimension " << i << " of " << operand.dimensions[i]
- << " different than the model's " << operand.dimensions[i];
- return false;
- }
- if (argument.dimensions[i] == 0) {
- LOG(ERROR) << "Request " << type << " " << argumentIndex
- << " has dimension " << i << " of zero";
- return false;
- }
- }
- }
- }
- return true;
-}
-
-// TODO doublecheck
-bool validateRequest(const Request& request, const Model& model) {
- const size_t poolCount = request.pools.size();
- return (validRequestArguments(request.inputs, model.inputIndexes, model.operands, poolCount,
- "input") &&
- validRequestArguments(request.outputs, model.outputIndexes, model.operands, poolCount,
- "output"));
-}
-
-} // namespace rt
-} // namespace nnfw