From 64285a1f25e2c7b85ed1f00b7947403e92baea00 Mon Sep 17 00:00:00 2001 From: Grant Watson Date: Wed, 16 Nov 2022 15:32:39 +0000 Subject: Extend reference model API with eager operator execution entrypoints - Adds a script to generate operators.h and operators.cc - Adds jinja2 templates for generating operators.h and operators.cc - Adds unit tests for a subset of the operators generated - Includes the TOSA specification as a submodule - Adds supporting C++ and header files Signed-off-by: Grant Watson Change-Id: I5b60db4c56113110d8e75fe1152525d258233f9c --- reference_model/src/array_proxy.h | 98 ++ reference_model/src/model_runner.cc | 12 +- reference_model/src/model_runner_impl.cc | 178 ++- reference_model/src/model_runner_impl.h | 7 +- reference_model/src/operators.cc | 2325 ++++++++++++++++++++++++++++++ reference_model/src/tensor.cc | 21 +- reference_model/src/tensor.h | 23 +- 7 files changed, 2599 insertions(+), 65 deletions(-) create mode 100644 reference_model/src/array_proxy.h create mode 100644 reference_model/src/operators.cc (limited to 'reference_model/src') diff --git a/reference_model/src/array_proxy.h b/reference_model/src/array_proxy.h new file mode 100644 index 0000000..f6b3105 --- /dev/null +++ b/reference_model/src/array_proxy.h @@ -0,0 +1,98 @@ + +// Copyright (c) 2022, ARM Limited. +// +// 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 ARRAY_PROXY_H_ +#define ARRAY_PROXY_H_ + +#include +#include + +template +class ArrayProxy +{ +public: + ArrayProxy(size_t n, T* ptr) noexcept + : _n(n) + , _ptr(ptr) + {} + + template ::value, int> = 0> + ArrayProxy(size_t n, typename std::remove_const_t* ptr) noexcept + : _n(n) + , _ptr(ptr) + {} + + template + ArrayProxy(T (&ptr)[S]) noexcept + : _n(S) + , _ptr(ptr) + {} + + template ::value, int> = 0> + ArrayProxy(typename std::remove_const_t (&ptr)[S]) noexcept + : _n(S) + , _ptr(ptr) + {} + + template ().data()), T*> && + std::is_convertible_v().size()), std::size_t>, + int> = 0> + ArrayProxy(O& obj) noexcept + : _n(obj.size()) + , _ptr(obj.data()) + {} + + size_t size() const noexcept + { + return _n; + } + + T* data() const noexcept + { + return _ptr; + } + + bool empty() const noexcept + { + return _n == 0; + } + + const T* begin() const noexcept + { + return _ptr; + } + + const T* end() const noexcept + { + return _ptr + _n; + } + + T& operator[](size_t idx) noexcept + { + return *(_ptr + idx); + } + + const T& operator[](size_t idx) const noexcept + { + return *(_ptr + idx); + } + +private: + size_t _n; + T* _ptr; +}; + +#endif // ARRAY_PROXY_H_ diff --git a/reference_model/src/model_runner.cc b/reference_model/src/model_runner.cc index 5c086e6..62d6ce6 100644 --- a/reference_model/src/model_runner.cc +++ b/reference_model/src/model_runner.cc @@ -55,7 +55,12 @@ GraphStatus IModelRunner::run() template int IModelRunner::setInput(std::string input_name, std::vector& vals) { - return model_runner_impl->setInput(input_name, vals); + return model_runner_impl->setInput(input_name, ArrayProxy(vals.size(), vals.data())); +} + +int IModelRunner::setInput(std::string input_name, uint8_t* raw_ptr, size_t size) +{ + return model_runner_impl->setInput(input_name, raw_ptr, size); } template @@ -64,6 +69,11 @@ std::vector IModelRunner::getOutput(std::string output_name) return model_runner_impl->getOutput(output_name); } +int IModelRunner::getOutput(std::string output_name, uint8_t* raw_ptr, size_t size) +{ + return model_runner_impl->getOutput(output_name, raw_ptr, size); +} + // Template explicit specialization template int IModelRunner::setInput(std::string input_name, std::vector& vals); template int IModelRunner::setInput(std::string input_name, std::vector& vals); diff --git a/reference_model/src/model_runner_impl.cc b/reference_model/src/model_runner_impl.cc index 8427150..1109dd6 100644 --- a/reference_model/src/model_runner_impl.cc +++ b/reference_model/src/model_runner_impl.cc @@ -45,42 +45,12 @@ void ModelRunnerImpl::setFuncDebug(func_debug_t& func_debug) GraphStatus ModelRunnerImpl::initialize(TosaSerializationHandler& serialization_handler) { validateTosaVersion(serialization_handler); + return initialize(serialization_handler.GetMainBlock(), &serialization_handler); +} - // Make nullptr in case ModelRunnerImpl is being initialized again with a different graph. - _main_gt = nullptr; - _main_gt = new SubgraphTraverser(serialization_handler.GetMainBlock(), &serialization_handler); - - if(_main_gt == nullptr) - { - WARNING("An error occurred when generating main graph traverser."); - return GraphStatus::TOSA_ERROR; - } - - if (_main_gt->initializeGraph()) - { - WARNING("Unable to initialize main graph traverser."); - return _main_gt->getGraphStatus(); - } - - if (_main_gt->linkTensorsAndNodes()) - { - WARNING("Failed to link tensors and nodes"); - return _main_gt->getGraphStatus(); - } - - if (_main_gt->validateGraph()) - { - WARNING("Failed to validate graph."); - return _main_gt->getGraphStatus(); - } - - if (_main_gt->allocateTensor()) - { - WARNING("Failed to allocate tensor."); - return _main_gt->getGraphStatus(); - } - - return _main_gt->getGraphStatus(); +GraphStatus ModelRunnerImpl::initialize(TosaSerializationBasicBlock& bb) +{ + return initialize(&bb, nullptr); } GraphStatus ModelRunnerImpl::run() @@ -156,7 +126,7 @@ done: } template -int ModelRunnerImpl::setInput(std::string input_name, std::vector& vals) +int ModelRunnerImpl::setInput(std::string input_name, ArrayProxy vals) { if (_main_gt == nullptr) { @@ -197,6 +167,44 @@ int ModelRunnerImpl::setInput(std::string input_name, std::vector& vals) return 0; } +int ModelRunnerImpl::setInput(std::string input_name, uint8_t* raw_ptr, size_t size) +{ + if (_main_gt == nullptr) + { + FATAL_ERROR("ModelRunner hasn't been initialized, please invoke initialize() before setInput()"); + } + + Tensor* tensor; + tensor = _main_gt->getInputTensorByName(input_name); + + if (!tensor) + { + WARNING("Unable to find input tensor %s", input_name.c_str()); + return 1; + } + + int status = 0; + switch (tensor->getDtype()) + { + case DType::DType_FP16: { + auto typed_ptr = reinterpret_cast(raw_ptr); + const int elements = size / sizeof(half_float::half); + status = setInput(input_name, ArrayProxy(elements, typed_ptr)); + break; + } + case DType::DType_FP32: { + auto typed_ptr = reinterpret_cast(raw_ptr); + const int elements = size / sizeof(float); + status = setInput(input_name, ArrayProxy(elements, typed_ptr)); + break; + } + default: + status = 1; + } + + return status; +} + template std::vector ModelRunnerImpl::getOutput(std::string output_name) { @@ -216,7 +224,7 @@ std::vector ModelRunnerImpl::getOutput(std::string output_name) std::vector outputs(tensor->getElementCount()); - if (tensor->writeToVector(outputs)) + if (tensor->writeToVector(ArrayProxy(outputs))) { WARNING("Unable to convert output tensor %s to vector", tensor->getName().c_str()); return std::vector(); @@ -225,6 +233,92 @@ std::vector ModelRunnerImpl::getOutput(std::string output_name) return outputs; } +int ModelRunnerImpl::getOutput(std::string output_name, uint8_t* raw_ptr, size_t size) +{ + if (_main_gt == nullptr) + { + FATAL_ERROR("ModelRunner hasn't been initialized, please invoke initialize() and run() before getOutput()"); + } + + Tensor* tensor; + tensor = _main_gt->getOutputTensorByName(output_name); + + if (!tensor) + { + WARNING("Unable to find output tensor %s", output_name.c_str()); + return 1; + } + + int status = 0; + switch (tensor->getDtype()) + { + case DType::DType_FP16: { + auto typed_ptr = reinterpret_cast(raw_ptr); + const int elements = size / sizeof(half_float::half); + status = tensor->writeToVector(ArrayProxy(elements, typed_ptr)); + break; + } + case DType::DType_FP32: { + auto typed_ptr = reinterpret_cast(raw_ptr); + const int elements = size / sizeof(float); + status = tensor->writeToVector(ArrayProxy(elements, typed_ptr)); + break; + } + default: + status = 1; + } + if (status) + { + WARNING("Unable to convert output tensor %s to vector", tensor->getName().c_str()); + return 1; + } + + return 0; +} + +GraphStatus ModelRunnerImpl::initialize(TosaSerializationBasicBlock* bb, + TosaSerializationHandler* serialization_handler) +{ + if (serialization_handler != nullptr) + validateTosaVersion(*serialization_handler); + + // Make nullptr in case ModelRunnerImpl is being initialized again with a different graph. + _main_gt = nullptr; + _main_gt = new SubgraphTraverser(bb, serialization_handler); + + if (_main_gt == nullptr) + { + WARNING("An error occurred when generating main graph traverser."); + return GraphStatus::TOSA_ERROR; + } + + if (_main_gt->initializeGraph()) + { + WARNING("Unable to initialize main graph traverser."); + return _main_gt->getGraphStatus(); + } + + if (_main_gt->linkTensorsAndNodes()) + { + WARNING("Failed to link tensors and nodes"); + return _main_gt->getGraphStatus(); + } + + if (_main_gt->validateGraph()) + { + WARNING("Failed to validate graph."); + return _main_gt->getGraphStatus(); + } + + if (_main_gt->allocateTensor()) + { + WARNING("Failed to allocate tensor."); + return _main_gt->getGraphStatus(); + } + + return _main_gt->getGraphStatus(); +} + void ModelRunnerImpl::validateTosaVersion(TosaSerializationHandler& serialization_handler) { TosaVersion model_version(TOSA_REFERENCE_MODEL_VERSION_MAJOR, @@ -266,11 +360,11 @@ void ModelRunnerImpl::checkGraphStatus(SubgraphTraverser& main_gt) } // Template explicit specialization -template int ModelRunnerImpl::setInput(std::string input_name, std::vector& vals); -template int ModelRunnerImpl::setInput(std::string input_name, std::vector& vals); -template int ModelRunnerImpl::setInput(std::string input_name, std::vector& vals); -template int ModelRunnerImpl::setInput(std::string input_name, std::vector& vals); -template int ModelRunnerImpl::setInput(std::string input_name, std::vector& vals); +template int ModelRunnerImpl::setInput(std::string input_name, ArrayProxy vals); +template int ModelRunnerImpl::setInput(std::string input_name, ArrayProxy vals); +template int ModelRunnerImpl::setInput(std::string input_name, ArrayProxy vals); +template int ModelRunnerImpl::setInput(std::string input_name, ArrayProxy vals); +template int ModelRunnerImpl::setInput(std::string input_name, ArrayProxy vals); template std::vector ModelRunnerImpl::getOutput(std::string output_name); template std::vector ModelRunnerImpl::getOutput(std::string output_name); diff --git a/reference_model/src/model_runner_impl.h b/reference_model/src/model_runner_impl.h index f26c484..b43370c 100644 --- a/reference_model/src/model_runner_impl.h +++ b/reference_model/src/model_runner_impl.h @@ -20,6 +20,7 @@ #include "graph_status.h" #include "version.h" +#include "array_proxy.h" #include "ops/op_factory.h" #include "subgraph_traverser.h" #include "tosa_serialization_handler.h" @@ -42,14 +43,17 @@ public: void setFuncConfig(func_config_t& func_config); void setFuncDebug(func_debug_t& func_debug); + GraphStatus initialize(TosaSerializationBasicBlock& bb); GraphStatus initialize(TosaSerializationHandler& serialization_handler); GraphStatus run(); template - int setInput(std::string input_name, std::vector& vals); + int setInput(std::string input_name, ArrayProxy vals); + int setInput(std::string input_name, uint8_t* raw_ptr, size_t size); template std::vector getOutput(std::string output_name); + int getOutput(std::string output_name, uint8_t* ptr, size_t size); private: SubgraphTraverser* _main_gt = nullptr; @@ -57,6 +61,7 @@ private: // Used to determine if all input tensors have been set correctly. uint32_t n_input_tensors = 0; + GraphStatus initialize(TosaSerializationBasicBlock* bb, TosaSerializationHandler* serialization_handler); void validateTosaVersion(TosaSerializationHandler& serialization_handler); void checkGraphStatus(SubgraphTraverser& main_gt); }; diff --git a/reference_model/src/operators.cc b/reference_model/src/operators.cc new file mode 100644 index 0000000..dfad9b8 --- /dev/null +++ b/reference_model/src/operators.cc @@ -0,0 +1,2325 @@ + +// Copyright (c) 2022, ARM Limited. +// +// 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. + +// THIS FILE IS GENERATED. DO NOT EDIT! +// See scripts/operator_api/generate_api.py + +#include "operators.h" +#include "model_runner_impl.h" +#include "ops/op_factory.h" + +#define TOSA_RETURN_ON_ERROR(status) \ + do \ + { \ + if (status != 0) \ + { \ + return tosa_status_error; \ + } \ + } while (false) + +#define TOSA_RETURN_ON_GRAPH_STATUS_ERROR(status) \ + do \ + { \ + if (status != GraphStatus::TOSA_VALID) \ + { \ + auto ustatus = static_cast>(status); \ + return static_cast(ustatus); \ + } \ + } while (false) + +namespace +{ + +tosa::DType translate_client_datatype(tosa_datatype_t type) +{ + switch (type) + { + case tosa_datatype_fp16_t: + return tosa::DType::DType_FP16; + case tosa_datatype_fp32_t: + return tosa::DType::DType_FP32; + default: + return tosa::DType::DType_UNKNOWN; + } +}; + +tosa::TosaSerializationTensor* translate_client_tensor(tosa_tensor_t& tensor, const std::string& name) +{ + std::vector shape(tensor.shape, tensor.shape + tensor.num_dims); + return new tosa::TosaSerializationTensor(name, shape, translate_client_datatype(tensor.data_type), {}); +} + +tosa::ResizeMode translate_client_tosa_mode(tosa_mode_t mode) +{ + switch (mode) + { + case tosa_mode_nearest: + return tosa::ResizeMode_NEAREST; + case tosa_mode_max: + case tosa_mode_bilinear: + return tosa::ResizeMode_BILINEAR; + default: + return tosa::ResizeMode_UNKNOWN; + } +} + +} // namespace + +extern "C" +{ + + tosa_status_t tosa_run_argmax(tosa_tensor_t client_input, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_ARGMAX, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("argmax", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_avg_pool2d(tosa_tensor_t client_input, + const int32_t client_kernel[2], + const int32_t client_stride[2], + const int32_t client_pad[4], + const int32_t client_input_zp, + const int32_t client_output_zp, + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector pad(&client_pad[0], &client_pad[4]); + const std::vector kernel(&client_kernel[0], &client_kernel[2]); + const std::vector stride(&client_stride[0], &client_stride[2]); + const int32_t input_zp = client_input_zp; + const int32_t output_zp = client_output_zp; + const tosa::DType accum_dtype = tosa::DType::DType_FP32; + TosaPoolAttribute attr(pad, kernel, stride, input_zp, output_zp, accum_dtype); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_AVG_POOL2D, tosa::Attribute::Attribute_PoolAttribute, + &attr, { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("avg_pool2d", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_conv2d(tosa_tensor_t client_input, + tosa_tensor_t client_weight, + tosa_tensor_t client_bias, + const int32_t client_pad[4], + const int32_t client_stride[2], + const int32_t client_dilation[2], + const int32_t client_input_zp, + const int32_t client_weight_zp, + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector pad(&client_pad[0], &client_pad[4]); + const std::vector stride(&client_stride[0], &client_stride[2]); + const std::vector dilation(&client_dilation[0], &client_dilation[2]); + const int32_t input_zp = client_input_zp; + const int32_t weight_zp = client_weight_zp; + const tosa::DType accum_dtype = tosa::DType::DType_FP32; + TosaConvAttribute attr(pad, stride, dilation, input_zp, weight_zp, accum_dtype); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* weight = translate_client_tensor(client_weight, "weight"); + tosa::TosaSerializationTensor* bias = translate_client_tensor(client_bias, "bias"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_CONV2D, tosa::Attribute::Attribute_ConvAttribute, + &attr, { input->GetName(), weight->GetName(), bias->GetName() }, + { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("conv2d", { op }, { input, weight, bias, output }, + { input->GetName(), weight->GetName(), bias->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(weight->GetName(), client_weight.data, client_weight.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(bias->GetName(), client_bias.data, client_bias.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_conv3d(tosa_tensor_t client_input, + tosa_tensor_t client_weight, + tosa_tensor_t client_bias, + const int32_t client_pad[6], + const int32_t client_stride[3], + const int32_t client_dilation[3], + const int32_t client_input_zp, + const int32_t client_weight_zp, + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector pad(&client_pad[0], &client_pad[6]); + const std::vector stride(&client_stride[0], &client_stride[3]); + const std::vector dilation(&client_dilation[0], &client_dilation[3]); + const int32_t input_zp = client_input_zp; + const int32_t weight_zp = client_weight_zp; + const tosa::DType accum_dtype = tosa::DType::DType_FP32; + TosaConvAttribute attr(pad, stride, dilation, input_zp, weight_zp, accum_dtype); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* weight = translate_client_tensor(client_weight, "weight"); + tosa::TosaSerializationTensor* bias = translate_client_tensor(client_bias, "bias"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_CONV3D, tosa::Attribute::Attribute_ConvAttribute, + &attr, { input->GetName(), weight->GetName(), bias->GetName() }, + { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("conv3d", { op }, { input, weight, bias, output }, + { input->GetName(), weight->GetName(), bias->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(weight->GetName(), client_weight.data, client_weight.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(bias->GetName(), client_bias.data, client_bias.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_depthwise_conv2d(tosa_tensor_t client_input, + tosa_tensor_t client_weight, + tosa_tensor_t client_bias, + const int32_t client_pad[4], + const int32_t client_stride[2], + const int32_t client_dilation[2], + const int32_t client_input_zp, + const int32_t client_weight_zp, + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector pad(&client_pad[0], &client_pad[4]); + const std::vector stride(&client_stride[0], &client_stride[2]); + const std::vector dilation(&client_dilation[0], &client_dilation[2]); + const int32_t input_zp = client_input_zp; + const int32_t weight_zp = client_weight_zp; + const tosa::DType accum_dtype = tosa::DType::DType_FP32; + TosaConvAttribute attr(pad, stride, dilation, input_zp, weight_zp, accum_dtype); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* weight = translate_client_tensor(client_weight, "weight"); + tosa::TosaSerializationTensor* bias = translate_client_tensor(client_bias, "bias"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator( + tosa::Op::Op_DEPTHWISE_CONV2D, tosa::Attribute::Attribute_ConvAttribute, &attr, + { input->GetName(), weight->GetName(), bias->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("depthwise_conv2d", { op }, { input, weight, bias, output }, + { input->GetName(), weight->GetName(), bias->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(weight->GetName(), client_weight.data, client_weight.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(bias->GetName(), client_bias.data, client_bias.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_fully_connected(tosa_tensor_t client_input, + const int32_t client_input_zp, + const int32_t client_weight_zp, + tosa_tensor_t client_output) + { + // Create operator attributes + const int32_t input_zp = client_input_zp; + const int32_t weight_zp = client_weight_zp; + const tosa::DType accum_dtype = tosa::DType::DType_FP32; + TosaFullyConnectedAttribute attr(input_zp, weight_zp, accum_dtype); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_FULLY_CONNECTED, + tosa::Attribute::Attribute_FullyConnectedAttribute, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("fully_connected", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_matmul(tosa_tensor_t client_a, + tosa_tensor_t client_b, + const int32_t client_a_zp, + const int32_t client_b_zp, + tosa_tensor_t client_output) + { + // Create operator attributes + const int32_t a_zp = client_a_zp; + const int32_t b_zp = client_b_zp; + const tosa::DType accum_dtype = tosa::DType::DType_FP32; + TosaMatMulAttribute attr(a_zp, b_zp, accum_dtype); + + // Create tensors + tosa::TosaSerializationTensor* a = translate_client_tensor(client_a, "a"); + tosa::TosaSerializationTensor* b = translate_client_tensor(client_b, "b"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_MATMUL, tosa::Attribute::Attribute_MatMulAttribute, + &attr, { a->GetName(), b->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("matmul", { op }, { a, b, output }, { a->GetName(), b->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(a->GetName(), client_a.data, client_a.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(b->GetName(), client_b.data, client_b.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_max_pool2d(tosa_tensor_t client_input, + const int32_t client_kernel[2], + const int32_t client_stride[2], + const int32_t client_pad[4], + const int32_t client_input_zp, + const int32_t client_output_zp, + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector pad(&client_pad[0], &client_pad[4]); + const std::vector kernel(&client_kernel[0], &client_kernel[2]); + const std::vector stride(&client_stride[0], &client_stride[2]); + const int32_t input_zp = client_input_zp; + const int32_t output_zp = client_output_zp; + const tosa::DType accum_dtype = tosa::DType::DType_FP32; + TosaPoolAttribute attr(pad, kernel, stride, input_zp, output_zp, accum_dtype); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_MAX_POOL2D, tosa::Attribute::Attribute_PoolAttribute, + &attr, { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("max_pool2d", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_transpose_conv2d(tosa_tensor_t client_input, + tosa_tensor_t client_weight, + tosa_tensor_t client_bias, + const int32_t client_out_pad[4], + const int32_t client_stride[2], + const int32_t client_out_shape[4], + const int32_t client_input_zp, + const int32_t client_weight_zp, + const int32_t client_pad_len, + const int32_t client_pad[], + const int32_t client_dilation_len, + const int32_t client_dilation[], + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector pad(&client_pad[0], &client_pad[0] + client_pad_len); + const std::vector stride(&client_stride[0], &client_stride[2]); + const std::vector dilation(&client_dilation[0], &client_dilation[0] + client_dilation_len); + const int32_t input_zp = client_input_zp; + const int32_t weight_zp = client_weight_zp; + const tosa::DType accum_dtype = tosa::DType::DType_FP32; + TosaConvAttribute attr(pad, stride, dilation, input_zp, weight_zp, accum_dtype); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* weight = translate_client_tensor(client_weight, "weight"); + tosa::TosaSerializationTensor* bias = translate_client_tensor(client_bias, "bias"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator( + tosa::Op::Op_TRANSPOSE_CONV2D, tosa::Attribute::Attribute_ConvAttribute, &attr, + { input->GetName(), weight->GetName(), bias->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("transpose_conv2d", { op }, { input, weight, bias, output }, + { input->GetName(), weight->GetName(), bias->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(weight->GetName(), client_weight.data, client_weight.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(bias->GetName(), client_bias.data, client_bias.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_clamp(tosa_tensor_t client_input, + const int32_t client_min_int, + const int32_t client_max_int, + const float client_min_fp, + const float client_max_fp, + tosa_tensor_t client_output) + { + // Create operator attributes + const int32_t min_int = client_min_int; + const int32_t max_int = client_max_int; + const float min_fp = client_min_fp; + const float max_fp = client_max_fp; + TosaClampAttribute attr(min_int, max_int, min_fp, max_fp); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_CLAMP, tosa::Attribute::Attribute_ClampAttribute, + &attr, { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("clamp", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_sigmoid(tosa_tensor_t client_input, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_SIGMOID, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("sigmoid", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_tanh(tosa_tensor_t client_input, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_TANH, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("tanh", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_add(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_ADD, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("add", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_arithmetic_right_shift(tosa_tensor_t client_input1, + tosa_tensor_t client_input2, + const bool client_round, + tosa_tensor_t client_output) + { + // Create operator attributes + const bool round = client_round; + TosaArithmeticRightShiftAttribute attr(round); + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_ARITHMETIC_RIGHT_SHIFT, + tosa::Attribute::Attribute_ArithmeticRightShiftAttribute, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("arithmetic_right_shift", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_bitwise_and(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_BITWISE_AND, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("bitwise_and", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_bitwise_or(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_BITWISE_OR, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("bitwise_or", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_bitwise_xor(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_BITWISE_XOR, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("bitwise_xor", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_intdiv(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_INTDIV, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("intdiv", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_logical_and(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_LOGICAL_AND, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("logical_and", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_logical_left_shift(tosa_tensor_t client_input1, + tosa_tensor_t client_input2, + tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = + new tosa::TosaSerializationOperator(tosa::Op::Op_LOGICAL_LEFT_SHIFT, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("logical_left_shift", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_logical_right_shift(tosa_tensor_t client_input1, + tosa_tensor_t client_input2, + tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = + new tosa::TosaSerializationOperator(tosa::Op::Op_LOGICAL_RIGHT_SHIFT, tosa::Attribute::Attribute_NONE, + &attr, { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("logical_right_shift", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_logical_or(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_LOGICAL_OR, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("logical_or", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_logical_xor(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_LOGICAL_XOR, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("logical_xor", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_maximum(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_MAXIMUM, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("maximum", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_minimum(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_MINIMUM, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("minimum", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_mul(tosa_tensor_t client_input1, + tosa_tensor_t client_input2, + const uint8_t client_shift, + tosa_tensor_t client_output) + { + // Create operator attributes + const int32_t shift = client_shift; + TosaMulAttribute attr(shift); + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_MUL, tosa::Attribute::Attribute_MulAttribute, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("mul", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_pow(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_POW, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("pow", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_sub(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_SUB, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("sub", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_table(tosa_tensor_t client_input, + const int32_t client_table_len, + const int16_t client_table[], + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector table(&client_table[0], &client_table[0] + client_table_len); + TosaTableAttribute attr(table); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_TABLE, tosa::Attribute::Attribute_TableAttribute, + &attr, { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("table", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_abs(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_ABS, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("abs", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_bitwise_not(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_BITWISE_NOT, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("bitwise_not", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_ceil(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_CEIL, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("ceil", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_clz(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_CLZ, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("clz", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_exp(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_EXP, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("exp", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_floor(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_FLOOR, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("floor", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_log(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_LOG, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("log", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_logical_not(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_LOGICAL_NOT, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("logical_not", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_negate(tosa_tensor_t client_input1, + const int32_t client_input1_zp, + const int32_t client_output_zp, + tosa_tensor_t client_output) + { + // Create operator attributes + const int32_t input1_zp = client_input1_zp; + const int32_t output_zp = client_output_zp; + TosaNegateAttribute attr(input1_zp, output_zp); + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_NEGATE, tosa::Attribute::Attribute_NegateAttribute, + &attr, { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("negate", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_reciprocal(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_RECIPROCAL, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reciprocal", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_rsqrt(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_RSQRT, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("rsqrt", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_select(tosa_tensor_t client_input1, + tosa_tensor_t client_input2, + tosa_tensor_t client_input3, + tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* input3 = translate_client_tensor(client_input3, "input3"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_SELECT, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName(), input3->GetName() }, + { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("select", { op }, { input1, input2, input3, output }, + { input1->GetName(), input2->GetName(), input3->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input3->GetName(), client_input3.data, client_input3.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_equal(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_EQUAL, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("equal", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_greater(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_GREATER, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("greater", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_greater_equal(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* input2 = translate_client_tensor(client_input2, "input2"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = + new tosa::TosaSerializationOperator(tosa::Op::Op_GREATER_EQUAL, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("greater_equal", { op }, { input1, input2, output }, + { input1->GetName(), input2->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input2->GetName(), client_input2.data, client_input2.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_reduce_all(tosa_tensor_t client_input, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_REDUCE_ALL, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reduce_all", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_reduce_any(tosa_tensor_t client_input, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_REDUCE_ANY, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reduce_any", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_reduce_max(tosa_tensor_t client_input, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_REDUCE_MAX, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reduce_max", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_reduce_min(tosa_tensor_t client_input, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_REDUCE_MIN, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reduce_min", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_reduce_product(tosa_tensor_t client_input, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_REDUCE_PRODUCT, tosa::Attribute::Attribute_NONE, + &attr, { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reduce_product", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_reduce_sum(tosa_tensor_t client_input, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_REDUCE_SUM, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reduce_sum", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_concat(tosa_tensor_t client_input1, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_CONCAT, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("concat", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_pad(tosa_tensor_t client_input1, + const int32_t client_padding_len, + const int32_t client_padding[], + const int32_t client_pad_const_int, + const float client_pad_const_fp, + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector padding(&client_padding[0], &client_padding[0] + client_padding_len); + const int32_t pad_const_int = client_pad_const_int; + const float pad_const_fp = client_pad_const_fp; + TosaPadAttribute attr(padding, pad_const_int, pad_const_fp); + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_PAD, tosa::Attribute::Attribute_PadAttribute, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("pad", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_reshape(tosa_tensor_t client_input1, + const int32_t client_new_shape_len, + const int32_t client_new_shape[], + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector new_shape(&client_new_shape[0], &client_new_shape[0] + client_new_shape_len); + TosaReshapeAttribute attr(new_shape); + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_RESHAPE, tosa::Attribute::Attribute_ReshapeAttribute, + &attr, { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reshape", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_reverse(tosa_tensor_t client_input, const int32_t client_axis, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_REVERSE, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("reverse", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_slice(tosa_tensor_t client_input1, + const int32_t client_start_len, + const int32_t client_start[], + const int32_t client_size_len, + const int32_t client_size[], + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector start(&client_start[0], &client_start[0] + client_start_len); + const std::vector size(&client_size[0], &client_size[0] + client_size_len); + TosaSliceAttribute attr(start, size); + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_SLICE, tosa::Attribute::Attribute_SliceAttribute, + &attr, { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("slice", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_tile(tosa_tensor_t client_input1, + const int32_t client_multiplies_len, + const int32_t client_multiplies[], + const int32_t client_multiples_len, + const int32_t client_multiples[], + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector multiples(&client_multiples[0], &client_multiples[0] + client_multiples_len); + TosaTileAttribute attr(multiples); + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_TILE, tosa::Attribute::Attribute_TileAttribute, + &attr, { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("tile", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_transpose(tosa_tensor_t client_input1, + const int32_t client_perms_len, + const int32_t client_perms[], + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector perms(&client_perms[0], &client_perms[0] + client_perms_len); + TosaTransposeAttribute attr(perms); + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = + new tosa::TosaSerializationOperator(tosa::Op::Op_TRANSPOSE, tosa::Attribute::Attribute_TransposeAttribute, + &attr, { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("transpose", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t + tosa_run_gather(tosa_tensor_t client_values, tosa_tensor_t client_indices, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* values = translate_client_tensor(client_values, "values"); + tosa::TosaSerializationTensor* indices = translate_client_tensor(client_indices, "indices"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_GATHER, tosa::Attribute::Attribute_NONE, &attr, + { values->GetName(), indices->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("gather", { op }, { values, indices, output }, + { values->GetName(), indices->GetName() }, { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(values->GetName(), client_values.data, client_values.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(indices->GetName(), client_indices.data, client_indices.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_scatter(tosa_tensor_t client_values_in, + tosa_tensor_t client_indices, + tosa_tensor_t client_input, + tosa_tensor_t client_values_out) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* values_in = translate_client_tensor(client_values_in, "values_in"); + tosa::TosaSerializationTensor* indices = translate_client_tensor(client_indices, "indices"); + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* values_out = translate_client_tensor(client_values_out, "values_out"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_SCATTER, tosa::Attribute::Attribute_NONE, &attr, + { values_in->GetName(), indices->GetName(), input->GetName() }, + { values_out->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("scatter", { op }, { values_in, indices, input, values_out }, + { values_in->GetName(), indices->GetName(), input->GetName() }, + { values_out->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(values_in->GetName(), client_values_in.data, client_values_in.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(indices->GetName(), client_indices.data, client_indices.size)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(values_out->GetName(), client_values_out.data, client_values_out.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_resize(tosa_tensor_t client_input, + const int16_t client_scale[4], + const int16_t client_offset[2], + const int16_t client_border[2], + const tosa_mode_t client_mode, + tosa_tensor_t client_output) + { + // Create operator attributes + const std::vector scale(&client_scale[0], &client_scale[4]); + const std::vector offset(&client_offset[0], &client_offset[2]); + const std::vector border(&client_border[0], &client_border[2]); + const ResizeMode mode = translate_client_tosa_mode(client_mode); + TosaResizeAttribute attr(scale, offset, border, mode); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_RESIZE, tosa::Attribute::Attribute_ResizeAttribute, + &attr, { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("resize", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_cast(tosa_tensor_t client_input, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_CAST, tosa::Attribute::Attribute_NONE, &attr, + { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("cast", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_rescale(tosa_tensor_t client_input, + tosa_tensor_t client_output, + const int32_t client_input_zp, + const int32_t client_output_zp, + const int32_t client_multiplier_len, + const int32_t client_multiplier[], + const int32_t client_shift_len, + const uint8_t client_shift[], + const bool client_scale32, + const bool client_double_round, + const bool client_per_channel) + { + // Create operator attributes + const int32_t input_zp = client_input_zp; + const int32_t output_zp = client_output_zp; + const std::vector multiplier(&client_multiplier[0], &client_multiplier[0] + client_multiplier_len); + const std::vector shift(&client_shift[0], &client_shift[0] + client_shift_len); + const bool scale32 = client_scale32; + const bool double_round = client_double_round; + const bool per_channel = client_per_channel; + TosaRescaleAttribute attr(input_zp, output_zp, multiplier, shift, scale32, double_round, per_channel); + + // Create tensors + tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_RESCALE, tosa::Attribute::Attribute_RescaleAttribute, + &attr, { input->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("rescale", { op }, { input, output }, { input->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + + tosa_status_t tosa_run_identity(tosa_tensor_t client_input1, tosa_tensor_t client_output) + { + // Create operator attributes + TosaNoneAttribute attr; + + // Create tensors + tosa::TosaSerializationTensor* input1 = translate_client_tensor(client_input1, "input1"); + tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output"); + + // Create operator + auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_IDENTITY, tosa::Attribute::Attribute_NONE, &attr, + { input1->GetName() }, { output->GetName() }); + + // Create a tosa single-op basic block + tosa::TosaSerializationBasicBlock block("identity", { op }, { input1, output }, { input1->GetName() }, + { output->GetName() }); + + // Setup model + TosaReference::ModelRunnerImpl runner; + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block)); + TOSA_RETURN_ON_ERROR(runner.setInput(input1->GetName(), client_input1.data, client_input1.size)); + + // Execute + TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run()); + + // Extract outputs + TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size)); + + return tosa_status_valid; + } + +} // extern "C" \ No newline at end of file diff --git a/reference_model/src/tensor.cc b/reference_model/src/tensor.cc index e9598c4..3cf4aa0 100644 --- a/reference_model/src/tensor.cc +++ b/reference_model/src/tensor.cc @@ -15,6 +15,7 @@ #include "tensor.h" #include "arith_util.h" +#include "array_proxy.h" #include "half.hpp" using namespace TosaReference; @@ -445,7 +446,7 @@ DEF_CTENSOR_COPY_VALUE_FROM(6, bool) #undef DEF_CTENSOR_COPY_VALUE_FROM -int TosaReference::Tensor::readfromVector(const std::vector& vals) +int TosaReference::Tensor::readfromVector(const ArrayProxy vals) { uint32_t elements = getElementCount(); switch (getDtype()) @@ -470,7 +471,7 @@ int TosaReference::Tensor::readfromVector(const std::vector& vals) return 0; } -int TosaReference::Tensor::readfromVector(const std::vector& vals) +int TosaReference::Tensor::readfromVector(const ArrayProxy vals) { uint32_t elements = getElementCount(); std::vector tensor(elements); @@ -502,7 +503,7 @@ int TosaReference::Tensor::readfromVector(const std::vector& v return 0; } -int TosaReference::Tensor::readfromVector(const std::vector& vals) +int TosaReference::Tensor::readfromVector(const ArrayProxy vals) { uint32_t elements = getElementCount(); switch (getDtype()) @@ -531,7 +532,7 @@ int TosaReference::Tensor::readfromVector(const std::vector& vals) return 0; } -int TosaReference::Tensor::readfromVector(const std::vector& vals) +int TosaReference::Tensor::readfromVector(const ArrayProxy vals) { uint32_t elements = getElementCount(); switch (getDtype()) @@ -555,7 +556,7 @@ int TosaReference::Tensor::readfromVector(const std::vector& vals) return 0; } -int TosaReference::Tensor::readfromVector(const std::vector& vals) +int TosaReference::Tensor::readfromVector(const ArrayProxy vals) { uint32_t elements = getElementCount(); @@ -580,7 +581,7 @@ int TosaReference::Tensor::readfromVector(const std::vector& vals return 0; } -int TosaReference::Tensor::writeToVector(std::vector& vals) +int TosaReference::Tensor::writeToVector(ArrayProxy vals) { uint32_t elements = getElementCount(); @@ -605,7 +606,7 @@ int TosaReference::Tensor::writeToVector(std::vector& vals) return 0; } -int TosaReference::Tensor::writeToVector(std::vector& vals) +int TosaReference::Tensor::writeToVector(ArrayProxy vals) { uint32_t elements = getElementCount(); std::vector tensor(elements); @@ -636,7 +637,7 @@ int TosaReference::Tensor::writeToVector(std::vector& vals) return 0; } -int TosaReference::Tensor::writeToVector(std::vector& vals) +int TosaReference::Tensor::writeToVector(ArrayProxy vals) { uint32_t elements = getElementCount(); @@ -665,7 +666,7 @@ int TosaReference::Tensor::writeToVector(std::vector& vals) return 0; } -int TosaReference::Tensor::writeToVector(std::vector& vals) +int TosaReference::Tensor::writeToVector(ArrayProxy vals) { uint32_t elements = getElementCount(); @@ -689,7 +690,7 @@ int TosaReference::Tensor::writeToVector(std::vector& vals) return 0; } -int TosaReference::Tensor::writeToVector(std::vector& vals) +int TosaReference::Tensor::writeToVector(ArrayProxy vals) { uint32_t elements = getElementCount(); diff --git a/reference_model/src/tensor.h b/reference_model/src/tensor.h index a3ce4bb..08e865a 100644 --- a/reference_model/src/tensor.h +++ b/reference_model/src/tensor.h @@ -16,6 +16,7 @@ #ifndef TOSA_REFERENCE_TENSOR_H #define TOSA_REFERENCE_TENSOR_H +#include "array_proxy.h" #include "model_common.h" #include "ops/template_types.h" #include "tosa_generated.h" @@ -228,17 +229,17 @@ public: virtual int writeToNpyFile(const char* filename) const; virtual int copyValueFrom(Tensor* tensor) = 0; - virtual int readfromVector(const std::vector& vals); - virtual int readfromVector(const std::vector& vals); - virtual int readfromVector(const std::vector& vals); - virtual int readfromVector(const std::vector& vals); - virtual int readfromVector(const std::vector& vals); - - virtual int writeToVector(std::vector& vals); - virtual int writeToVector(std::vector& vals); - virtual int writeToVector(std::vector& vals); - virtual int writeToVector(std::vector& vals); - virtual int writeToVector(std::vector& vals); + virtual int readfromVector(const ArrayProxy vals); + virtual int readfromVector(const ArrayProxy vals); + virtual int readfromVector(const ArrayProxy vals); + virtual int readfromVector(const ArrayProxy vals); + virtual int readfromVector(const ArrayProxy vals); + + virtual int writeToVector(ArrayProxy vals); + virtual int writeToVector(ArrayProxy vals); + virtual int writeToVector(ArrayProxy vals); + virtual int writeToVector(ArrayProxy vals); + virtual int writeToVector(ArrayProxy vals); const char* bool_to_str(bool in) const { -- cgit v1.2.1