#include "schema_v3.h"
#include "PluginException.h"
#include "nncc/core/ADT/tensor/Shape.h"
+#include "nncc/core/ADT/tensor/Index.h"
+#include "nncc/core/ADT/tensor/IndexRange.h"
#include "nnc/core/IR/model/operations/variable_op.h"
#include "shape_helper.h"
namespace tflite
{
+using nncc::core::ADT::tensor::Index;
+using nncc::core::ADT::tensor::IndexRange;
using VariableOp = nncc::contrib::core::IR::model::ops::VariableOp;
using nncc::core::ADT::tensor::Shape;
return std::make_shared<IrTensor>(tensorShape, tensorBufferCopy, type, elementSize);
}
+std::shared_ptr<IrTensor> IrVisitor::convertTensorForConv(std::shared_ptr<IrTensor> tensor)
+{
+ Shape inShape = tensor->getShape();
+ assert(inShape.rank() == 4);
+
+ // Changes dimension indices [0, 1, 2, 3] to [1, 2, 3, 0].
+ // This is needed because in TFLite convolution weights are stored as NHWC, and we use HWCN.
+ Shape targetShape{inShape.dim(1), inShape.dim(2), inShape.dim(3), inShape.dim(0)};
+
+ int size = targetShape.dim(0) * targetShape.dim(1) * targetShape.dim(2) * targetShape.dim(3);
+
+ std::shared_ptr<char> convertedTensorData(new char[size * tensor->getElementSize()],
+ [](char *d) { delete[] d; });
+
+ auto convertedTensor = std::make_shared<IrTensor>(targetShape, convertedTensorData,
+ tensor->getDataType(),
+ tensor->getElementSize());
+
+ // Swaps two elements in the initial and new tensors
+ // according to the correct tensor dimension order
+ auto swap = [&convertedTensor, &tensor](const Index &idx) {
+ Index targetIndex{idx.at(1), idx.at(2), idx.at(3), idx.at(0)};
+
+ // Copy element_size bytes which constitute one number
+ std::memcpy(convertedTensor->at(targetIndex), tensor->at(idx),
+ convertedTensor->getElementSize());
+ };
+
+ IndexRange(tensor->getShape()).iterate() << swap;
+
+ return convertedTensor;
+}
+
Graph *IrVisitor::getGraph() { return graph; }
void IrVisitor::setGraphOutputs()