diff --git a/ethosu/regor/compiler/graphir_optimiser.cpp b/ethosu/regor/compiler/graphir_optimiser.cpp index 7ea2812827d276abf0bed1e145371d99b7501746..1b7451a7f0573f172bb03597cb8b549f2bb6ad49 100644 --- a/ethosu/regor/compiler/graphir_optimiser.cpp +++ b/ethosu/regor/compiler/graphir_optimiser.cpp @@ -550,6 +550,39 @@ Operation *GraphIrOptimiser::RewriteConst(Graph *const graph, Operation *const o return returnOp; } +Operation *GraphIrOptimiser::RewriteIdentityResize(Graph *const graph, Operation *const operation) +{ + Operation *returnOp = operation; + OpType opType = operation->Type(); + if ( opType == OpType::Resize ) + { + auto *attr = operation->Attribute(); + const auto ofmConn = operation->Output(TensorUsage::OFM); + bool noBorder = attr->border.x == 0 && attr->border.y; + bool noOffset = attr->offset.x == 0 && attr->offset.y == 0; + bool unitUpscale = attr->scaleX.n == 1 && attr->scaleX.d == 1 && attr->scaleY.n == 1 && attr->scaleY.d == 1; + bool identityUpscaleNoRescaleRequired = + attr->mode == tosa::ResizeMode::NEAREST && attr->scaleX.n == attr->scaleX.d && + attr->scaleY.n == attr->scaleY.d; + + bool isIdentity = noBorder && noOffset && (unitUpscale || identityUpscaleNoRescaleRequired); + if ( isIdentity ) + { + const auto ifmConn = operation->Input(TensorUsage::IFM); + + auto identityOp = std::make_shared(OpType::Identity); + identityOp->ConnectInput(TensorUsage::IFM, ifmConn->tensor).Set(Quantization::Unit()).Set(ifmConn->tensor->StorageShape()); + identityOp->ConnectOutput(TensorUsage::OFM, ofmConn->tensor).Set(Quantization::Unit()).Set(ofmConn->tensor->StorageShape()); + + + returnOp = identityOp.get(); + RecordOptimisation(*operation, returnOp); + operation->Disconnect(); + } + } + return returnOp; +} + Operation *GraphIrOptimiser::RewriteFullyConnected(Graph *const graph, Operation *const operation) { UNUSED(graph); diff --git a/ethosu/regor/compiler/graphir_optimiser.hpp b/ethosu/regor/compiler/graphir_optimiser.hpp index c7a6b7b1f8d0af7cba47d976f2d7b1426aff6317..84baa4aaa1f8c3cf46ff22b8b5bd1ba79bc94f82 100644 --- a/ethosu/regor/compiler/graphir_optimiser.hpp +++ b/ethosu/regor/compiler/graphir_optimiser.hpp @@ -76,6 +76,7 @@ private: void MoveToConsumer(const Operation *const operation, Operation *const cons); Operation *MoveSplitSliceToConsumer(Graph *const, Operation *const operation); Operation *UnrollKernelStrides(Graph *const, Operation *const operation); + Operation *RewriteIdentityResize(Graph *const graph, Operation *const operation); // Utility/Helper methods Operation *MakeFillOperation(TensorConnection *const ofmConn, const Shape &ofmShape, const TensorSlice &ofmSlice, std::shared_ptr padTensor); @@ -102,6 +103,7 @@ private: {}, { &GraphIrOptimiser::RewriteConst, + &GraphIrOptimiser::RewriteIdentityResize }, }, { diff --git a/ethosu/regor/tflite/tflite_supported_operators_u55.cpp b/ethosu/regor/tflite/tflite_supported_operators_u55.cpp index eda556d8cd4b65f154c0402b54aab0e2b8ce4599..06e037c5cdd70fe65bcc6943ddca4c1ce996eb9f 100644 --- a/ethosu/regor/tflite/tflite_supported_operators_u55.cpp +++ b/ethosu/regor/tflite/tflite_supported_operators_u55.cpp @@ -180,13 +180,13 @@ bool TfLiteSupportedOperatorsU55::ConstraintResize(const Operation *op) Shape ifmShape = Shape::PadAxes(ifmConn->shape, 4, 1); Shape ofmShape = Shape::PadAxes(ofmConn->shape, 4, 1); - if ( ifmShape.Height() == ofmShape.Height() && ifmShape.Height() == ofmShape.Height() ) + if ( ifmShape.Height() == 1 && ifmShape.Width() == 1 ) { return true; } - if ( ifmShape.Height() == 1 && ifmShape.Width() == 1 ) + if ( ifmShape.Height() == ofmShape.Height() && ifmShape.Height() == ofmShape.Height() ) { - return true; + return !halfPixelCentersRB; } float hUpscale;