// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace delegateTestInterpreter { inline TfLiteTensor* GetInputTensorFromInterpreter(TfLiteInterpreter* interpreter, int index) { TfLiteTensor* inputTensor = TfLiteInterpreterGetInputTensor(interpreter, index); if(inputTensor == nullptr) { throw armnn::Exception("Input tensor was not found at the given index: " + std::to_string(index)); } return inputTensor; } inline const TfLiteTensor* GetOutputTensorFromInterpreter(TfLiteInterpreter* interpreter, int index) { const TfLiteTensor* outputTensor = TfLiteInterpreterGetOutputTensor(interpreter, index); if(outputTensor == nullptr) { throw armnn::Exception("Output tensor was not found at the given index: " + std::to_string(index)); } return outputTensor; } inline TfLiteModel* CreateTfLiteModel(std::vector& data) { TfLiteModel* tfLiteModel = TfLiteModelCreate(data.data(), data.size()); if(tfLiteModel == nullptr) { throw armnn::Exception("An error has occurred when creating the TfLiteModel."); } return tfLiteModel; } inline TfLiteInterpreterOptions* CreateTfLiteInterpreterOptions() { TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate(); if(options == nullptr) { throw armnn::Exception("An error has occurred when creating the TfLiteInterpreterOptions."); } return options; } inline tflite::ops::builtin::BuiltinOpResolver GenerateCustomOpResolver(const std::string& opName) { tflite::ops::builtin::BuiltinOpResolver opResolver; if (opName == "MaxPool3D") { opResolver.AddCustom("MaxPool3D", tflite::ops::custom::Register_MAX_POOL_3D()); } else if (opName == "AveragePool3D") { opResolver.AddCustom("AveragePool3D", tflite::ops::custom::Register_AVG_POOL_3D()); } else { throw armnn::Exception("The custom op isn't supported by the DelegateTestInterpreter."); } return opResolver; } template inline TfLiteStatus CopyFromBufferToTensor(TfLiteTensor* tensor, std::vector& values) { // Make sure there is enough bytes allocated to copy into for uint8_t and int16_t case. if(tensor->bytes < values.size() * sizeof(T)) { throw armnn::Exception("Tensor has not been allocated to match number of values."); } // Requires uint8_t and int16_t specific case as the number of bytes is larger than values passed when creating // TFLite tensors of these types. Otherwise, use generic TfLiteTensorCopyFromBuffer function. TfLiteStatus status = kTfLiteOk; if (std::is_same::value) { for (unsigned int i = 0; i < values.size(); ++i) { tensor->data.uint8[i] = values[i]; } } else if (std::is_same::value) { for (unsigned int i = 0; i < values.size(); ++i) { tensor->data.i16[i] = values[i]; } } else { status = TfLiteTensorCopyFromBuffer(tensor, values.data(), values.size() * sizeof(T)); } return status; } } // anonymous namespace