From e5e2676409a936431f87d31fb74d825257b20804 Mon Sep 17 00:00:00 2001 From: Eric Kunze Date: Tue, 13 Oct 2020 16:11:07 -0700 Subject: Initial checkin of TOSA reference_model and tests Change-Id: I2f8e7fa63e2ae40203e57d2cc8814bde3b312cb6 Signed-off-by: Eric Kunze --- reference_model/src/tensor.cc | 3008 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3008 insertions(+) create mode 100644 reference_model/src/tensor.cc (limited to 'reference_model/src/tensor.cc') diff --git a/reference_model/src/tensor.cc b/reference_model/src/tensor.cc new file mode 100644 index 0000000..179484e --- /dev/null +++ b/reference_model/src/tensor.cc @@ -0,0 +1,3008 @@ + +// Copyright (c) 2020, 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. + +#include "tensor.h" +#include "arith_util.h" + +using namespace TosaReference; +using namespace Eigen; +using namespace tosa; + +TosaReference::Tensor::Tensor(std::string tensorName_, + DType tensorDtype_, + const std::vector& tensorUsage_, + const std::vector& tensorFormat_, + std::vector shape_, + int isConst_) +{ + tensorName = std::string(tensorName_); + tensorDtype = tensorDtype_; + tensorUsage = std::vector(tensorUsage_); + tensorFormat = std::vector(tensorFormat_); + shape = std::vector(shape_); + isConst = isConst_; + producer = nullptr; + isValid = false; + consumers.clear(); + isSubgraphInput = false; + isSubgraphOutput = false; +} + +TosaReference::Tensor::~Tensor() +{} + +int TosaReference::Tensor::setIsSubgraphInput() +{ + isSubgraphInput = true; + return 0; +} + +int TosaReference::Tensor::setIsSubgraphOutput() +{ + isSubgraphOutput = true; + return 0; +} + +int TosaReference::Tensor::setProducer(GraphNode* node) +{ + ASSERT_MSG(node, "Tensor::setProducer: no node passed in"); + ASSERT_MSG(!producer, "Tensor::setProducer: producer node already set, tensor %s", tensorName.c_str()); + producer = node; + + return 0; +} + +int TosaReference::Tensor::addConsumer(GraphNode* node) +{ + ASSERT_MSG(node, "Tensor::addConsumer: no node passed in"); + consumers.push_back(node); + + return 0; +} + +int TosaReference::Tensor::dumpTensorParams(FILE* out) const +{ + fprintf(out, "Name: %s DType=%s Usage=%s isValid=%d Rank=%d Shape=%s\n", tensorName.c_str(), + EnumNamesDType()[getDtype()], getUsageAsString().c_str(), getIsValid(), getRank(), + getShapeAsString().c_str()); + + return 0; +} + +int TosaReference::Tensor::dumpTensorParams(std::ostream& out) const +{ + out << "Name: " << getName() << " DType=" << EnumNamesDType()[getDtype()] << " Usage=" << getUsageAsString() + << " isValid=" << getIsValid() << " Rank=" << getRank() << " Shape=" << getShapeAsString() << "\n"; + + return 0; +} + +int TosaReference::Tensor::readFromNpyFile(const char* filename) +{ + uint32_t elements = getElementCount(); + float* fdatabuf = nullptr; + int32_t* i32databuf = nullptr; + int64_t* i64databuf = nullptr; + bool* bdatabuf = nullptr; + NumpyUtilities::NPError nperror; + + switch (getDtype()) + { + case DType_FLOAT: + fdatabuf = (float*)calloc(sizeof(float), elements); + ASSERT_MEM(fdatabuf); + + nperror = NumpyUtilities::readFromNpyFile(filename, elements, fdatabuf); + break; + case DType_INT32: + case DType_AINT8: + case DType_UINT8: + case DType_INT4: + case DType_INT8: + case DType_INT16: + i32databuf = (int32_t*)calloc(sizeof(int32_t), elements); + ASSERT_MEM(i32databuf); + + nperror = NumpyUtilities::readFromNpyFile(filename, elements, i32databuf); + break; + case DType_INT48: + i64databuf = (int64_t*)calloc(sizeof(int64_t), elements); + ASSERT_MEM(i64databuf); + + nperror = NumpyUtilities::readFromNpyFile(filename, elements, i64databuf); + break; + case DType_BOOL: + bdatabuf = (bool*)calloc(sizeof(bool), elements); + ASSERT_MEM(bdatabuf); + + nperror = NumpyUtilities::readFromNpyFile(filename, elements, bdatabuf); + break; + default: + FATAL_ERROR("unsupported tensor type=%s", EnumNamesDType()[getDtype()]); + } + + switch (nperror) + { + case NumpyUtilities::NO_ERROR: + break; + case NumpyUtilities::FILE_NOT_FOUND: + FATAL_ERROR("readFromNpyFile: Cannot open file %s", filename); + case NumpyUtilities::FILE_IO_ERROR: + FATAL_ERROR("readFromNpyFile: IO error reading file: %s", filename); + case NumpyUtilities::FILE_TYPE_MISMATCH: + FATAL_ERROR("readFromNpyFile: Tensor type %s and Numpy file type mismatch for tensor %s filename %s", + EnumNamesDType()[getDtype()], getName().c_str(), filename); + case NumpyUtilities::HEADER_PARSE_ERROR: + FATAL_ERROR("Numpy header parsing error for file: %s", filename); + case NumpyUtilities::BUFFER_SIZE_MISMATCH: + FATAL_ERROR("Buffer size does not match numpy file size for tensor %s filename %s", getName().c_str(), + filename); + default: + FATAL_ERROR("Unknown error parsing Numpy file: %s", filename); + } + + switch (getDtype()) + { + case DType_FLOAT: + if (setTensorValueFloat(elements, fdatabuf)) + { + free(fdatabuf); + return 1; + } + break; + case DType_INT32: + case DType_AINT8: + case DType_UINT8: + case DType_INT4: + case DType_INT8: + case DType_INT16: + if (setTensorValueInt32(elements, i32databuf)) + { + free(i32databuf); + return 1; + } + break; + case DType_INT48: + if (setTensorValueInt64(elements, i64databuf)) + { + free(i64databuf); + return 1; + } + break; + case DType_BOOL: + if (setTensorValueBool(elements, bdatabuf)) + { + free(i32databuf); + return 1; + } + break; + default: + FATAL_ERROR("unsupported tensor type=%s", EnumNamesDType()[getDtype()]); + } + + setIsValid(); + + if (fdatabuf) + free(fdatabuf); + if (i32databuf) + free(i32databuf); + if (i64databuf) + free(i64databuf); + if (bdatabuf) + free(bdatabuf); + + return 0; +} + +int TosaReference::Tensor::writeToNpyFile(const char* filename) const +{ + float* fdatabuf = nullptr; + int32_t* i32databuf = nullptr; + int64_t* i64databuf = nullptr; + bool* bdatabuf = nullptr; + NumpyUtilities::NPError nperror; + int elements = getElementCount(); + + switch (getDtype()) + { + case DType_FLOAT: + fdatabuf = (float*)calloc(sizeof(float), elements); + ASSERT_MEM(fdatabuf); + + if (getTensorValueFloat(elements, fdatabuf)) + { + free(fdatabuf); + return 1; + } + + nperror = NumpyUtilities::writeToNpyFile(filename, shape, fdatabuf); + + free(fdatabuf); + break; + case DType_INT32: + case DType_AINT8: + case DType_UINT8: + case DType_INT4: + case DType_INT8: + case DType_INT16: + i32databuf = (int32_t*)calloc(sizeof(int32_t), elements); + ASSERT_MEM(i32databuf); + + if (getTensorValueInt32(elements, i32databuf)) + { + free(i32databuf); + return 1; + } + + nperror = NumpyUtilities::writeToNpyFile(filename, shape, i32databuf); + + free(i32databuf); + break; + case DType_INT48: + i64databuf = (int64_t*)calloc(sizeof(int64_t), elements); + ASSERT_MEM(i64databuf); + + if (getTensorValueInt64(elements, i64databuf)) + { + free(i64databuf); + return 1; + } + + nperror = NumpyUtilities::writeToNpyFile(filename, shape, i64databuf); + + free(i64databuf); + break; + case DType_BOOL: + bdatabuf = (bool*)calloc(sizeof(bool), elements); + ASSERT_MEM(bdatabuf); + + if (getTensorValueBool(elements, bdatabuf)) + { + free(bdatabuf); + return 1; + } + + nperror = NumpyUtilities::writeToNpyFile(filename, shape, bdatabuf); + + free(bdatabuf); + break; + default: + FATAL_ERROR("unsupported tensor type=%s", EnumNamesDType()[getDtype()]); + } + + switch (nperror) + { + case NumpyUtilities::NO_ERROR: + break; + case NumpyUtilities::FILE_NOT_FOUND: + FATAL_ERROR("writeToNpyFile: Cannot open output file %s", filename); + case NumpyUtilities::FILE_IO_ERROR: + FATAL_ERROR("writeToNpyFile: IO error writing file: %s", filename); + case NumpyUtilities::FILE_TYPE_MISMATCH: + FATAL_ERROR("writeToNpyFile: Tensor type and Numpy file type mismatch for tensor %s filename %s", + getName().c_str(), filename); + case NumpyUtilities::HEADER_PARSE_ERROR: + FATAL_ERROR("Numpy header parsing error for file: %s", filename); + case NumpyUtilities::BUFFER_SIZE_MISMATCH: + FATAL_ERROR("Buffer size does not match numpy file size for tensor %s filename %s", getName().c_str(), + filename); + default: + FATAL_ERROR("Unknown error writing Numpy file: %s", filename); + } + + return 0; +} + +template +int TosaReference::TensorTemplate::copyValueFrom(TosaReference::Tensor* src) +{ + FATAL_ERROR("TensorTemplate::copyValueFrom should not be called. " + "Implement template specialization version."); + return 0; +} + +#define DEF_CTENSOR_COPY_VALUE_FROM(RANK, TYPE) \ + template <> \ + int TosaReference::Tensor##RANK::copyValueFrom(TosaReference::Tensor* src) \ + { \ + TosaReference::Tensor##RANK* t = dynamic_cast*>(src); \ + if (!t) \ + { \ + WARNING("tensor %s templated class does not match %s", src->getName().c_str(), this->getName().c_str()); \ + return 1; \ + } \ + \ + uint32_t src_rank = src->getRank(); \ + uint32_t dst_rank = this->getRank(); \ + DType src_dtype = src->getDtype(); \ + DType dst_dtype = this->getDtype(); \ + bool tensor_match = true; \ + \ + if ((src_rank != dst_rank) || (src_dtype != dst_dtype)) \ + { \ + tensor_match = false; \ + } \ + else \ + { \ + for (uint32_t i = 0; i < src_rank; i++) \ + { \ + int src_dim = src->getShape()[i]; \ + int dst_dim = this->getShape()[i]; \ + if (src_dim != dst_dim) \ + { \ + tensor_match = false; \ + } \ + } \ + } \ + \ + if (!tensor_match) \ + { \ + WARNING("source tensor %s (rank=%u, dtype=%s, shape=%s) doesn't match destination tensor %s (rank=%u, " \ + "dtype=%s, shape=%s)", \ + src->getName().c_str(), src_rank, EnumNamesDType()[src_dtype], src->getShapeAsString().c_str(), \ + this->getName().c_str(), dst_rank, EnumNamesDType()[dst_dtype], this->getShapeAsString().c_str()); \ + return 1; \ + } \ + \ + this->getTensor() = t->getTensor(); \ + return 0; \ + } + +DEF_CTENSOR_COPY_VALUE_FROM(0, float) +DEF_CTENSOR_COPY_VALUE_FROM(1, float) +DEF_CTENSOR_COPY_VALUE_FROM(2, float) +DEF_CTENSOR_COPY_VALUE_FROM(3, float) +DEF_CTENSOR_COPY_VALUE_FROM(4, float) +DEF_CTENSOR_COPY_VALUE_FROM(5, float) +DEF_CTENSOR_COPY_VALUE_FROM(6, float) +DEF_CTENSOR_COPY_VALUE_FROM(0, int32_t) +DEF_CTENSOR_COPY_VALUE_FROM(1, int32_t) +DEF_CTENSOR_COPY_VALUE_FROM(2, int32_t) +DEF_CTENSOR_COPY_VALUE_FROM(3, int32_t) +DEF_CTENSOR_COPY_VALUE_FROM(4, int32_t) +DEF_CTENSOR_COPY_VALUE_FROM(5, int32_t) +DEF_CTENSOR_COPY_VALUE_FROM(6, int32_t) +DEF_CTENSOR_COPY_VALUE_FROM(0, int64_t) +DEF_CTENSOR_COPY_VALUE_FROM(1, int64_t) +DEF_CTENSOR_COPY_VALUE_FROM(2, int64_t) +DEF_CTENSOR_COPY_VALUE_FROM(3, int64_t) +DEF_CTENSOR_COPY_VALUE_FROM(4, int64_t) +DEF_CTENSOR_COPY_VALUE_FROM(5, int64_t) +DEF_CTENSOR_COPY_VALUE_FROM(6, int64_t) +DEF_CTENSOR_COPY_VALUE_FROM(0, bool) +DEF_CTENSOR_COPY_VALUE_FROM(1, bool) +DEF_CTENSOR_COPY_VALUE_FROM(2, bool) +DEF_CTENSOR_COPY_VALUE_FROM(3, bool) +DEF_CTENSOR_COPY_VALUE_FROM(4, bool) +DEF_CTENSOR_COPY_VALUE_FROM(5, bool) +DEF_CTENSOR_COPY_VALUE_FROM(6, bool) + +#undef DEF_CTENSOR_COPY_VALUE_FROM + +template +int TosaReference::TensorTemplate::setTensorValueFloat(const size_t buflen, const float* vals) +{ + FATAL_ERROR("TensorTemplate::setTensorValueFloat should not be called. " + "Implement template specialization version."); + return 0; +} + +template <> +int TosaReference::Tensor0::setTensorValueFloat(const size_t bufLen, const float* vals) +{ + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + (*tensor)(0) = vals[0]; + + return 0; +} + +template <> +int TosaReference::Tensor1::setTensorValueFloat(const size_t bufLen, const float* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + (*tensor)(i0) = vals[idx++]; + } + + return 0; +} + +template <> +int TosaReference::Tensor2::setTensorValueFloat(const size_t bufLen, const float* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + (*tensor)(i0, i1) = vals[idx++]; + } + } + + return 0; +} + +template <> +int TosaReference::Tensor3::setTensorValueFloat(const size_t bufLen, const float* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + (*tensor)(i0, i1, i2) = vals[idx++]; + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor4::setTensorValueFloat(const size_t bufLen, const float* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + (*tensor)(i0, i1, i2, i3) = vals[idx++]; + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor5::setTensorValueFloat(const size_t bufLen, const float* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + (*tensor)(i0, i1, i2, i3, i4) = vals[idx++]; + } + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor6::setTensorValueFloat(const size_t bufLen, const float* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + for (int i5 = 0; i5 < shape[5]; i5++) + { + (*tensor)(i0, i1, i2, i3, i4, i5) = vals[idx++]; + } + } + } + } + } + } + return 0; +} + +template +int TosaReference::TensorTemplate::setTensorValueInt32(const size_t bufLen, const int32_t* vals) +{ + FATAL_ERROR("TensorTemplate::setTensorValueInt32 should not be called. " + "Implement template specialization version."); + return 0; +} + +template <> +int TosaReference::Tensor0::setTensorValueInt32(const size_t bufLen, const int32_t* vals) +{ + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + (*tensor)(0) = vals[0]; + + return 0; +} + +template <> +int TosaReference::Tensor1::setTensorValueInt32(const size_t bufLen, const int32_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + (*tensor)(i0) = vals[idx++]; + } + + return 0; +} + +template <> +int TosaReference::Tensor2::setTensorValueInt32(const size_t bufLen, const int32_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + (*tensor)(i0, i1) = vals[idx++]; + } + } + + return 0; +} + +template <> +int TosaReference::Tensor3::setTensorValueInt32(const size_t bufLen, const int32_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + (*tensor)(i0, i1, i2) = vals[idx++]; + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor4::setTensorValueInt32(const size_t bufLen, const int32_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + (*tensor)(i0, i1, i2, i3) = vals[idx++]; + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor5::setTensorValueInt32(const size_t bufLen, const int32_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + (*tensor)(i0, i1, i2, i3, i4) = vals[idx++]; + } + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor6::setTensorValueInt32(const size_t bufLen, const int32_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + for (int i5 = 0; i5 < shape[5]; i5++) + { + (*tensor)(i0, i1, i2, i3, i4, i5) = vals[idx++]; + } + } + } + } + } + } + return 0; +} + +template +int TosaReference::TensorTemplate::setTensorValueInt64(const size_t bufLen, const int64_t* vals) +{ + FATAL_ERROR("TensorTemplate::setTensorValueInt64 should not be called. " + "Implement template specialization version."); + return 0; +} + +template <> +int TosaReference::Tensor0::setTensorValueInt64(const size_t bufLen, const int64_t* vals) +{ + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + (*tensor)(0) = vals[0]; + + return 0; +} + +template <> +int TosaReference::Tensor1::setTensorValueInt64(const size_t bufLen, const int64_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + (*tensor)(i0) = vals[idx++]; + } + + return 0; +} + +template <> +int TosaReference::Tensor2::setTensorValueInt64(const size_t bufLen, const int64_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + (*tensor)(i0, i1) = vals[idx++]; + } + } + + return 0; +} + +template <> +int TosaReference::Tensor3::setTensorValueInt64(const size_t bufLen, const int64_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + (*tensor)(i0, i1, i2) = vals[idx++]; + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor4::setTensorValueInt64(const size_t bufLen, const int64_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + (*tensor)(i0, i1, i2, i3) = vals[idx++]; + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor5::setTensorValueInt64(const size_t bufLen, const int64_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + (*tensor)(i0, i1, i2, i3, i4) = vals[idx++]; + } + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor6::setTensorValueInt64(const size_t bufLen, const int64_t* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + for (int i5 = 0; i5 < shape[5]; i5++) + { + (*tensor)(i0, i1, i2, i3, i4, i5) = vals[idx++]; + } + } + } + } + } + } + return 0; +} + +template +int TosaReference::TensorTemplate::setTensorValueBool(const size_t buflen, const bool* vals) +{ + FATAL_ERROR("TensorTemplate::setTensorValueBool should not be called. " + "Implement template specialization version."); + return 0; +} + +template <> +int TosaReference::Tensor0::setTensorValueBool(const size_t bufLen, const bool* vals) +{ + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + (*tensor)(0) = vals[0]; + + return 0; +} + +template <> +int TosaReference::Tensor1::setTensorValueBool(const size_t bufLen, const bool* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + (*tensor)(i0) = vals[idx++]; + } + + return 0; +} + +template <> +int TosaReference::Tensor2::setTensorValueBool(const size_t bufLen, const bool* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + (*tensor)(i0, i1) = vals[idx++]; + } + } + + return 0; +} + +template <> +int TosaReference::Tensor3::setTensorValueBool(const size_t bufLen, const bool* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + (*tensor)(i0, i1, i2) = vals[idx++]; + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor4::setTensorValueBool(const size_t bufLen, const bool* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + (*tensor)(i0, i1, i2, i3) = vals[idx++]; + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor5::setTensorValueBool(const size_t bufLen, const bool* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + (*tensor)(i0, i1, i2, i3, i4) = vals[idx++]; + } + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor6::setTensorValueBool(const size_t bufLen, const bool* vals) +{ + uint32_t idx = 0; + + ASSERT_MSG(bufLen == getElementCount(), "Total elements must match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + for (int i5 = 0; i5 < shape[5]; i5++) + { + (*tensor)(i0, i1, i2, i3, i4, i5) = vals[idx++]; + } + } + } + } + } + } + return 0; +} + +template +int TosaReference::TensorTemplate::getTensorValueFloat(const size_t bufLen, float* vals) const +{ + FATAL_ERROR("TensorTemplate::getTensorValueFloat should not be called. " + "Implement template specialization version."); + return 0; +} + +template <> +int TosaReference::Tensor0::getTensorValueFloat(const size_t bufLen, float* vals) const +{ + int totalVals = 1; + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + vals[0] = (*tensor)(0); + + return 0; +} + +template <> +int TosaReference::Tensor1::getTensorValueFloat(const size_t bufLen, float* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + vals[idx++] = (*tensor)(i0); + } + + return 0; +} + +template <> +int TosaReference::Tensor2::getTensorValueFloat(const size_t bufLen, float* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + vals[idx++] = (*tensor)(i0, i1); + } + } + + return 0; +} + +template <> +int TosaReference::Tensor3::getTensorValueFloat(const size_t bufLen, float* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + vals[idx++] = (*tensor)(i0, i1, i2); + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor4::getTensorValueFloat(const size_t bufLen, float* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3); + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor5::getTensorValueFloat(const size_t bufLen, float* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3, i4); + } + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor6::getTensorValueFloat(const size_t bufLen, float* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + for (int i5 = 0; i5 < shape[5]; i5++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3, i4, i5); + } + } + } + } + } + } + return 0; +} + +template +int TosaReference::TensorTemplate::getTensorValueInt32(const size_t bufLen, int32_t* vals) const +{ + FATAL_ERROR("TensorTemplate::getTensorValueInt32 should not be called. " + "Implement template specialization version."); + return 0; +} + +template <> +int TosaReference::Tensor0::getTensorValueInt32(const size_t bufLen, int32_t* vals) const +{ + int totalVals = 1; + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + vals[0] = (*tensor)(0); + + return 0; +} + +template <> +int TosaReference::Tensor1::getTensorValueInt32(const size_t bufLen, int32_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + vals[idx++] = (*tensor)(i0); + } + + return 0; +} + +template <> +int TosaReference::Tensor2::getTensorValueInt32(const size_t bufLen, int32_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + vals[idx++] = (*tensor)(i0, i1); + } + } + + return 0; +} + +template <> +int TosaReference::Tensor3::getTensorValueInt32(const size_t bufLen, int32_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + vals[idx++] = (*tensor)(i0, i1, i2); + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor4::getTensorValueInt32(const size_t bufLen, int32_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3); + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor5::getTensorValueInt32(const size_t bufLen, int32_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3, i4); + } + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor6::getTensorValueInt32(const size_t bufLen, int32_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + for (int i5 = 0; i5 < shape[5]; i5++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3, i4, i5); + } + } + } + } + } + } + return 0; +} + +template +int TosaReference::TensorTemplate::getTensorValueInt64(const size_t bufLen, int64_t* vals) const +{ + FATAL_ERROR("TensorTemplate::getTensorValueInt64 should not be called. " + "Implement template specialization version."); + return 0; +} + +template <> +int TosaReference::Tensor0::getTensorValueInt64(const size_t bufLen, int64_t* vals) const +{ + int totalVals = 1; + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + vals[0] = (*tensor)(0); + + return 0; +} + +template <> +int TosaReference::Tensor1::getTensorValueInt64(const size_t bufLen, int64_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + vals[idx++] = (*tensor)(i0); + } + + return 0; +} + +template <> +int TosaReference::Tensor2::getTensorValueInt64(const size_t bufLen, int64_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + vals[idx++] = (*tensor)(i0, i1); + } + } + + return 0; +} + +template <> +int TosaReference::Tensor3::getTensorValueInt64(const size_t bufLen, int64_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + vals[idx++] = (*tensor)(i0, i1, i2); + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor4::getTensorValueInt64(const size_t bufLen, int64_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3); + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor5::getTensorValueInt64(const size_t bufLen, int64_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3, i4); + } + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor6::getTensorValueInt64(const size_t bufLen, int64_t* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + for (int i5 = 0; i5 < shape[5]; i5++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3, i4, i5); + } + } + } + } + } + } + return 0; +} + +template +int TosaReference::TensorTemplate::getTensorValueBool(const size_t bufLen, bool* vals) const +{ + FATAL_ERROR("TensorTemplate::getTensorValueBool should not be called. " + "Implement template specialization version."); + return 0; +} + +template <> +int TosaReference::Tensor0::getTensorValueBool(const size_t bufLen, bool* vals) const +{ + int totalVals = 1; + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + vals[0] = (*tensor)(0); + + return 0; +} + +template <> +int TosaReference::Tensor1::getTensorValueBool(const size_t bufLen, bool* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + vals[idx++] = (*tensor)(i0); + } + + return 0; +} + +template <> +int TosaReference::Tensor2::getTensorValueBool(const size_t bufLen, bool* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + vals[idx++] = (*tensor)(i0, i1); + } + } + + return 0; +} + +template <> +int TosaReference::Tensor3::getTensorValueBool(const size_t bufLen, bool* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + vals[idx++] = (*tensor)(i0, i1, i2); + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor4::getTensorValueBool(const size_t bufLen, bool* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3); + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor5::getTensorValueBool(const size_t bufLen, bool* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3, i4); + } + } + } + } + } + + return 0; +} + +template <> +int TosaReference::Tensor6::getTensorValueBool(const size_t bufLen, bool* vals) const +{ + uint32_t idx = 0; + int totalVals = 1; + + for (size_t i = 0; i < shape.size(); i++) + { + totalVals *= shape[i]; + } + + ASSERT_MSG((size_t)totalVals == bufLen, "Output buffer and tensor size do not match"); + + for (int i0 = 0; i0 < shape[0]; i0++) + { + for (int i1 = 0; i1 < shape[1]; i1++) + { + for (int i2 = 0; i2 < shape[2]; i2++) + { + for (int i3 = 0; i3 < shape[3]; i3++) + { + for (int i4 = 0; i4 < shape[4]; i4++) + { + for (int i5 = 0; i5 < shape[5]; i5++) + { + vals[idx++] = (*tensor)(i0, i1, i2, i3, i4, i5); + } + } + } + } + } + } + return 0; +} + +template <> +int TosaReference::Tensor0::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor0(); + + if (tensor) + return 0; + else + return 1; +} +template <> +int TosaReference::Tensor1::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor1(shape[0]); + if (tensor) + return 0; + else + return 1; +} +template <> +int TosaReference::Tensor2::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor2(shape[0], shape[1]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor3::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor3(shape[0], shape[1], shape[2]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor4::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor4(shape[0], shape[1], shape[2], shape[3]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor5::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor5(shape[0], shape[1], shape[2], shape[3], shape[4]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor6::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor6(shape[0], shape[1], shape[2], shape[3], shape[4], shape[5]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor0::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor0(); + if (tensor) + return 0; + else + return 1; +} +template <> +int TosaReference::Tensor1::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor1(shape[0]); + if (tensor) + return 0; + else + return 1; +} +template <> +int TosaReference::Tensor2::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor2(shape[0], shape[1]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor3::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor3(shape[0], shape[1], shape[2]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor4::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor4(shape[0], shape[1], shape[2], shape[3]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor5::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor5(shape[0], shape[1], shape[2], shape[3], shape[4]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor6::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor6(shape[0], shape[1], shape[2], shape[3], shape[4], shape[5]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor0::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor0(); + if (tensor) + return 0; + else + return 1; +} +template <> +int TosaReference::Tensor1::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor1(shape[0]); + if (tensor) + return 0; + else + return 1; +} +template <> +int TosaReference::Tensor2::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor2(shape[0], shape[1]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor3::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor3(shape[0], shape[1], shape[2]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor4::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor4(shape[0], shape[1], shape[2], shape[3]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor5::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor5(shape[0], shape[1], shape[2], shape[3], shape[4]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor6::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor6(shape[0], shape[1], shape[2], shape[3], shape[4], shape[5]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor0::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor0(); + if (tensor) + return 0; + else + return 1; +} +template <> +int TosaReference::Tensor1::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor1(shape[0]); + if (tensor) + return 0; + else + return 1; +} +template <> +int TosaReference::Tensor2::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor2(shape[0], shape[1]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor3::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor3(shape[0], shape[1], shape[2]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor4::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor4(shape[0], shape[1], shape[2], shape[3]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor5::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor5(shape[0], shape[1], shape[2], shape[3], shape[4]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor6::allocate() +{ + ASSERT_MSG(tensor == nullptr, "Error: double allocate Eigen tensor"); + tensor = new ETensor6(shape[0], shape[1], shape[2], shape[3], shape[4], shape[5]); + if (tensor) + return 0; + else + return 1; +} + +template <> +int TosaReference::Tensor0::dumpTensor(FILE* out) const +{ + char fp_fmt[FOF_STR_LEN]; + snprintf(fp_fmt, FOF_STR_LEN, "[ %%%sf ]\n", g_func_config.fp_format); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, fp_fmt, (*tensor)(0)); + + return 0; +} + +template <> +int TosaReference::Tensor1::dumpTensor(FILE* out) const +{ + char fp_fmt[FOF_STR_LEN]; + snprintf(fp_fmt, FOF_STR_LEN, " %%%sf ", g_func_config.fp_format); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, fp_fmt, (*tensor)(i0)); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor2::dumpTensor(FILE* out) const +{ + char fp_fmt[FOF_STR_LEN]; + snprintf(fp_fmt, FOF_STR_LEN, " %%%sf ", g_func_config.fp_format); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, fp_fmt, (*tensor)(i0, i1)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor3::dumpTensor(FILE* out) const +{ + char fp_fmt[FOF_STR_LEN]; + snprintf(fp_fmt, FOF_STR_LEN, " %%%sf ", g_func_config.fp_format); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, fp_fmt, (*tensor)(i0, i1, i2)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor4::dumpTensor(FILE* out) const +{ + char fp_fmt[FOF_STR_LEN]; + snprintf(fp_fmt, FOF_STR_LEN, " %%%sf ", g_func_config.fp_format); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, fp_fmt, (*tensor)(i0, i1, i2, i3)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor5::dumpTensor(FILE* out) const +{ + char fp_fmt[FOF_STR_LEN]; + snprintf(fp_fmt, FOF_STR_LEN, " %%%sf ", g_func_config.fp_format); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, "["); + for (int i4 = 0; i4 < shape[4]; i4++) + { + fprintf(out, fp_fmt, (*tensor)(i0, i1, i2, i3, i4)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor6::dumpTensor(FILE* out) const +{ + char fp_fmt[FOF_STR_LEN]; + snprintf(fp_fmt, FOF_STR_LEN, " %%%sf ", g_func_config.fp_format); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, "["); + for (int i4 = 0; i4 < shape[4]; i4++) + { + fprintf(out, "["); + for (int i5 = 0; i5 < shape[5]; i5++) + { + fprintf(out, fp_fmt, (*tensor)(i0, i1, i2, i3, i4, i5)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor0::dumpTensor(FILE* out) const +{ + char i64_fmt[FOF_STR_LEN]; + snprintf(i64_fmt, FOF_STR_LEN, "[ %%ld ]\n"); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, i64_fmt, (*tensor)(0)); + + return 0; +} + +template <> +int TosaReference::Tensor1::dumpTensor(FILE* out) const +{ + char i64_fmt[FOF_STR_LEN]; + snprintf(i64_fmt, FOF_STR_LEN, " %%ld "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, i64_fmt, (*tensor)(i0)); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor2::dumpTensor(FILE* out) const +{ + char i64_fmt[FOF_STR_LEN]; + snprintf(i64_fmt, FOF_STR_LEN, " %%ld "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, i64_fmt, (*tensor)(i0, i1)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor3::dumpTensor(FILE* out) const +{ + char i64_fmt[FOF_STR_LEN]; + snprintf(i64_fmt, FOF_STR_LEN, " %%ld "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, i64_fmt, (*tensor)(i0, i1, i2)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor4::dumpTensor(FILE* out) const +{ + char i64_fmt[FOF_STR_LEN]; + snprintf(i64_fmt, FOF_STR_LEN, " %%ld "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, i64_fmt, (*tensor)(i0, i1, i2, i3)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor5::dumpTensor(FILE* out) const +{ + char i64_fmt[FOF_STR_LEN]; + snprintf(i64_fmt, FOF_STR_LEN, " %%ld "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, "["); + for (int i4 = 0; i4 < shape[4]; i4++) + { + fprintf(out, i64_fmt, (*tensor)(i0, i1, i2, i3, i4)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor6::dumpTensor(FILE* out) const +{ + char i64_fmt[FOF_STR_LEN]; + snprintf(i64_fmt, FOF_STR_LEN, " %%ld "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, "["); + for (int i4 = 0; i4 < shape[4]; i4++) + { + fprintf(out, "["); + for (int i5 = 0; i5 < shape[5]; i5++) + { + fprintf(out, i64_fmt, (*tensor)(i0, i1, i2, i3, i4, i5)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor0::dumpTensor(FILE* out) const +{ + char i32_fmt[FOF_STR_LEN]; + snprintf(i32_fmt, FOF_STR_LEN, "[ %%d ]\n"); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, i32_fmt, (*tensor)(0)); + + return 0; +} + +template <> +int TosaReference::Tensor1::dumpTensor(FILE* out) const +{ + char i32_fmt[FOF_STR_LEN]; + snprintf(i32_fmt, FOF_STR_LEN, " %%d "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, i32_fmt, (*tensor)(i0)); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor2::dumpTensor(FILE* out) const +{ + char i32_fmt[FOF_STR_LEN]; + snprintf(i32_fmt, FOF_STR_LEN, " %%d "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, i32_fmt, (*tensor)(i0, i1)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor3::dumpTensor(FILE* out) const +{ + char i32_fmt[FOF_STR_LEN]; + snprintf(i32_fmt, FOF_STR_LEN, " %%d "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, i32_fmt, (*tensor)(i0, i1, i2)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor4::dumpTensor(FILE* out) const +{ + char i32_fmt[FOF_STR_LEN]; + snprintf(i32_fmt, FOF_STR_LEN, " %%d "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, i32_fmt, (*tensor)(i0, i1, i2, i3)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor5::dumpTensor(FILE* out) const +{ + char i32_fmt[FOF_STR_LEN]; + snprintf(i32_fmt, FOF_STR_LEN, " %%d "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, "["); + for (int i4 = 0; i4 < shape[4]; i4++) + { + fprintf(out, i32_fmt, (*tensor)(i0, i1, i2, i3, i4)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor6::dumpTensor(FILE* out) const +{ + char i32_fmt[FOF_STR_LEN]; + snprintf(i32_fmt, FOF_STR_LEN, " %%d "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, "["); + for (int i4 = 0; i4 < shape[4]; i4++) + { + fprintf(out, "["); + for (int i5 = 0; i5 < shape[5]; i5++) + { + fprintf(out, i32_fmt, (*tensor)(i0, i1, i2, i3, i4, i5)); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor0::dumpTensor(FILE* out) const +{ + char bool_fmt[FOF_STR_LEN]; + snprintf(bool_fmt, FOF_STR_LEN, "[ %%s ]\n"); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, bool_fmt, bool_to_str((*tensor)(0))); + + return 0; +} + +template <> +int TosaReference::Tensor1::dumpTensor(FILE* out) const +{ + char bool_fmt[FOF_STR_LEN]; + snprintf(bool_fmt, FOF_STR_LEN, " %%s "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, bool_fmt, bool_to_str((*tensor)(i0))); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor2::dumpTensor(FILE* out) const +{ + char bool_fmt[FOF_STR_LEN]; + snprintf(bool_fmt, FOF_STR_LEN, " %%s "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, bool_fmt, bool_to_str((*tensor)(i0, i1))); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor3::dumpTensor(FILE* out) const +{ + char bool_fmt[FOF_STR_LEN]; + snprintf(bool_fmt, FOF_STR_LEN, " %%s "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, bool_fmt, bool_to_str((*tensor)(i0, i1, i2))); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor4::dumpTensor(FILE* out) const +{ + char bool_fmt[FOF_STR_LEN]; + snprintf(bool_fmt, FOF_STR_LEN, " %%s "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, bool_fmt, bool_to_str((*tensor)(i0, i1, i2, i3))); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor5::dumpTensor(FILE* out) const +{ + char bool_fmt[FOF_STR_LEN]; + snprintf(bool_fmt, FOF_STR_LEN, " %%s "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, "["); + for (int i4 = 0; i4 < shape[4]; i4++) + { + fprintf(out, bool_fmt, bool_to_str((*tensor)(i0, i1, i2, i3, i4))); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template <> +int TosaReference::Tensor6::dumpTensor(FILE* out) const +{ + char bool_fmt[FOF_STR_LEN]; + snprintf(bool_fmt, FOF_STR_LEN, " %%s "); + + if (tensor == nullptr) + { + fprintf(out, "\n"); + return 0; + } + + fprintf(out, "["); + for (int i0 = 0; i0 < shape[0]; i0++) + { + fprintf(out, "["); + for (int i1 = 0; i1 < shape[1]; i1++) + { + fprintf(out, "["); + for (int i2 = 0; i2 < shape[2]; i2++) + { + fprintf(out, "["); + for (int i3 = 0; i3 < shape[3]; i3++) + { + fprintf(out, "["); + for (int i4 = 0; i4 < shape[4]; i4++) + { + fprintf(out, "["); + for (int i5 = 0; i5 < shape[5]; i5++) + { + fprintf(out, bool_fmt, bool_to_str((*tensor)(i0, i1, i2, i3, i4, i5))); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + } + fprintf(out, "]\n"); + + return 0; +} + +template +int TosaReference::TensorTemplate::dumpTensor(FILE* out) const +{ + return 0; +} + +// template explicit specialization +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; + +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; + +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; + +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; +template class TosaReference::TensorTemplate>; -- cgit v1.2.1