From 55b9cf1c392208923bff757cdefd1dd38ac91aec Mon Sep 17 00:00:00 2001 From: panickal-xmos Date: Thu, 11 Jul 2024 12:30:07 +0100 Subject: [PATCH 1/6] Add support for overlapping with second operand of an overlappable op --- xformer/Analysis/MemoryPlan.cpp | 83 +++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/xformer/Analysis/MemoryPlan.cpp b/xformer/Analysis/MemoryPlan.cpp index 98d5cc0f6..51c12f7ef 100644 --- a/xformer/Analysis/MemoryPlan.cpp +++ b/xformer/Analysis/MemoryPlan.cpp @@ -162,42 +162,50 @@ std::vector MemoryPlan::getAllocatedOffsets(const bool overlapOps, if (overlapOps) { for (auto o : operations) { if (o->hasTrait() && - !alreadyVisited.contains(o) && o->getOperand(0).hasOneUse()) { - alreadyVisited.insert(o); - - llvm::SmallVector inputVals; + !alreadyVisited.contains(o)) { auto inVal = o->getOperand(0); - inputVals.push_back(inVal); - - auto outVal = o->getResult(0); - auto nextOp = *outVal.getUsers().begin(); - // Identify chain of overlappable Ops - while (outVal.hasOneUse() && !alreadyVisited.contains(nextOp) && - nextOp->hasTrait()) { - inVal = outVal; + + if ((o->getNumOperands() == 1 && inVal.hasOneUse()) || + (o->getNumOperands() == 2 && + (inVal.hasOneUse() || o->getOperand(1).hasOneUse()))) { + if ((o->getNumOperands() == 2 && !inVal.hasOneUse())) { + inVal = o->getOperand(1); + } + + alreadyVisited.insert(o); + llvm::SmallVector inputVals; inputVals.push_back(inVal); - alreadyVisited.insert(nextOp); - outVal = nextOp->getResult(0); - nextOp = *outVal.getUsers().begin(); - } - // Set first Used of output Val to the first input Val - vInfo[outVal].firstUsed = vInfo[inputVals[0]].firstUsed; - auto unalignedSizeOutVal = - utils::getShapedTypeSize(outVal.getType().dyn_cast()); - size_t maxSizeNeeded = 0; - for (auto inV : inputVals) { - auto unalignedSizeInV = - utils::getShapedTypeSize(inV.getType().dyn_cast()); - auto unalignedOffset = unalignedSizeOutVal - unalignedSizeInV; - // Align offset up to double word = 8 bytes - auto offset = ((unalignedOffset + 7) / 8) * 8; - maxSizeNeeded = std::max(vInfo[inV].size + offset, maxSizeNeeded); - inOutMap[inV] = {outVal, offset}; + auto outVal = o->getResult(0); + auto nextOp = *outVal.getUsers().begin(); + // Identify chain of overlappable Ops + while (outVal.hasOneUse() && !alreadyVisited.contains(nextOp) && + nextOp->hasTrait()) { + inVal = outVal; + inputVals.push_back(inVal); + alreadyVisited.insert(nextOp); + outVal = nextOp->getResult(0); + nextOp = *outVal.getUsers().begin(); + } + + // Set first Used of output Val to the first input Val + vInfo[outVal].firstUsed = vInfo[inputVals[0]].firstUsed; + auto unalignedSizeOutVal = + utils::getShapedTypeSize(outVal.getType().dyn_cast()); + size_t maxSizeNeeded = 0; + for (auto inV : inputVals) { + auto unalignedSizeInV = + utils::getShapedTypeSize(inV.getType().dyn_cast()); + auto unalignedOffset = unalignedSizeOutVal - unalignedSizeInV; + // Align offset up to double word = 8 bytes + auto offset = ((unalignedOffset + 7) / 8) * 8; + maxSizeNeeded = std::max(vInfo[inV].size + offset, maxSizeNeeded); + inOutMap[inV] = {outVal, offset}; + } + // The aligned input val size plus aligned offset might be larger than + // aligned output val size + vInfo[outVal].size = std::max(vInfo[outVal].size, maxSizeNeeded); } - // The aligned input val size plus aligned offset might be larger than - // aligned output val size - vInfo[outVal].size = std::max(vInfo[outVal].size, maxSizeNeeded); } } } @@ -353,6 +361,7 @@ void MemoryPlan::printMemoryPlan() { line[c] = '.'; } int memory_use = 0; + int peakSize = 0; for (int i = 0; i < nonConstantAllocatedValues.size(); ++i) { if ((t < valueInfo[nonConstantAllocatedValues[i]].firstUsed) || (t > valueInfo[nonConstantAllocatedValues[i]].lastUsed)) { @@ -362,7 +371,12 @@ void MemoryPlan::printMemoryPlan() { if (offset == -1) { continue; } + const int size = valueInfo[nonConstantAllocatedValues[i]].size; + if (peakSize < offset + size) { + peakSize = offset + size; + } + memory_use += size; const int line_start = (offset * kLineWidth) / max_size; const int line_end = ((offset + size) * kLineWidth) / max_size; @@ -377,9 +391,10 @@ void MemoryPlan::printMemoryPlan() { line[kLineWidth] = 0; llvm::outs() << llvm::format( - "\n%-20s %s%d: %s (%dk)", + "\n%-20s %s%d: %s (%dk), (%dk)", operations[t]->getName().stripDialect().str().c_str(), - t < 10 ? " " : "", t, (const char *)line, (memory_use + 1023) / 1024); + t < 10 ? " " : "", t, (const char *)line, (memory_use + 1023) / 1024, + (peakSize + 1023) / 1024); } llvm::outs() << "\n"; } From 35fbf46e4cc5da2d304a236eda7e9ad87194c33f Mon Sep 17 00:00:00 2001 From: panickal-xmos Date: Sun, 14 Jul 2024 15:01:25 +0100 Subject: [PATCH 2/6] Fix condition --- xformer/Analysis/MemoryPlan.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/xformer/Analysis/MemoryPlan.cpp b/xformer/Analysis/MemoryPlan.cpp index 51c12f7ef..d08ccd8f1 100644 --- a/xformer/Analysis/MemoryPlan.cpp +++ b/xformer/Analysis/MemoryPlan.cpp @@ -161,14 +161,25 @@ std::vector MemoryPlan::getAllocatedOffsets(const bool overlapOps, llvm::DenseSet alreadyVisited; if (overlapOps) { for (auto o : operations) { + // We iterate through overlappable ops which have not been visited yet if (o->hasTrait() && !alreadyVisited.contains(o)) { auto inVal = o->getOperand(0); - if ((o->getNumOperands() == 1 && inVal.hasOneUse()) || + // We have binary and unary ops as overlappable + // For binary ops, we might have to overlap with the second operand + // The complicated if condition below is to check for valid one operand + // or two operand cases + if ((o->getNumOperands() == 1 && inVal.hasOneUse() && + !vInfo[inVal].isConstant) || (o->getNumOperands() == 2 && - (inVal.hasOneUse() || o->getOperand(1).hasOneUse()))) { - if ((o->getNumOperands() == 2 && !inVal.hasOneUse())) { + (inVal.hasOneUse() && !vInfo[inVal].isConstant || + o->getOperand(1).hasOneUse() && + !vInfo[o->getOperand(1)].isConstant))) { + // In case of two operands and first operand is invalid, use the + // second one + if (o->getNumOperands() == 2 && + (!inVal.hasOneUse() || vInfo[inVal].isConstant)) { inVal = o->getOperand(1); } From e654cb1b642971eceb099ce69f17201aa561ca5a Mon Sep 17 00:00:00 2001 From: panickal-xmos Date: Thu, 11 Jul 2024 12:31:40 +0100 Subject: [PATCH 3/6] Add sub op using add --- xformer/Transforms/Passes.cpp | 8 +- xformer/Transforms/Passes.h | 2 +- xformer/Transforms/ReplaceAdd.cpp | 95 ----------------------- xformer/Transforms/ReplaceAddSub.cpp | 110 +++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 100 deletions(-) delete mode 100644 xformer/Transforms/ReplaceAdd.cpp create mode 100644 xformer/Transforms/ReplaceAddSub.cpp diff --git a/xformer/Transforms/Passes.cpp b/xformer/Transforms/Passes.cpp index 8a8866d4d..d0cad10e2 100644 --- a/xformer/Transforms/Passes.cpp +++ b/xformer/Transforms/Passes.cpp @@ -17,13 +17,13 @@ void buildXCorePreOpSplitPassPipeline(OpPassManager &pm) { pm.addPass(mlir::TFL::CreateTranslateToLCEPass()); // Convert dynamic shapes in batch dimension to static pm.addPass(createRemoveDynamicShapePass()); +} + +void buildXCoreRemainingPassPipeline(OpPassManager &pm) { // TFL passes pm.addPass(createOptimizeTransposePass()); pm.addPass(createReplaceAvgPoolWithConv2DPass()); pm.addPass(createReplaceFCWithConv2DPass()); -} - -void buildXCoreRemainingPassPipeline(OpPassManager &pm) { if (opSplitTensorArenaOption) { pm.addPass(createOpSplitPass()); } @@ -36,7 +36,7 @@ void buildXCoreRemainingPassPipeline(OpPassManager &pm) { pm.addPass(mlir::createCanonicalizerPass()); // XC passes - pm.addPass(createReplaceAddPass()); + pm.addPass(createReplaceAddSubPass()); pm.addPass(createReplaceMaxPoolPass()); pm.addPass(createReplaceMulPass()); pm.addPass(createReplaceTransposeConvPass()); diff --git a/xformer/Transforms/Passes.h b/xformer/Transforms/Passes.h index c41f4e7b9..32d6d581b 100644 --- a/xformer/Transforms/Passes.h +++ b/xformer/Transforms/Passes.h @@ -31,7 +31,7 @@ std::unique_ptr> createOptimizeConv2DPass(); std::unique_ptr> createOpSplitPass(); std::unique_ptr> createApplyTFLPatternsPass(); std::unique_ptr> createRemoveDynamicShapePass(); -std::unique_ptr> createReplaceAddPass(); +std::unique_ptr> createReplaceAddSubPass(); std::unique_ptr> createReplaceMulPass(); std::unique_ptr> createReplaceMaxPoolPass(); std::unique_ptr> createReplaceStridedSlicePass(); diff --git a/xformer/Transforms/ReplaceAdd.cpp b/xformer/Transforms/ReplaceAdd.cpp deleted file mode 100644 index 1e8947d6a..000000000 --- a/xformer/Transforms/ReplaceAdd.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2021 XMOS LIMITED. This Software is subject to the terms of the -// XMOS Public License: Version 1 - -#include "IR/XCoreOps.h" -#include "Utils/Util.h" - -#include "lib_nn/api/MemCpyFn.hpp" -#include "mlir/IR/TypeUtilities.h" -#include "mlir/Pass/Pass.h" -#include "mlir/Transforms/GreedyPatternRewriteDriver.h" -#include "tensorflow/compiler/mlir/lite/ir/tfl_ops.h" - -namespace mlir::xcore { - -namespace { -// Replace TFL Add with Add for XCore. -struct ReplaceAdd - : public PassWrapper> { - MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(ReplaceAdd) - - void getDependentDialects(DialectRegistry ®istry) const final { - registry.insert(); - } - StringRef getArgument() const final { return "xcore-replace-add"; } - StringRef getDescription() const final { - return "Replace TFL Add with Add for XCore."; - } - void runOnOperation() override; -}; - -struct ReplaceAddPattern : public OpRewritePattern { - using OpRewritePattern::OpRewritePattern; - - LogicalResult matchAndRewrite(TFL::AddOp addOp, - PatternRewriter &rewriter) const override { - - if (!utils::checkBinaryCompatibility(addOp)) - return failure(); - - auto lhsQType = utils::getQType(addOp.getLhs()); - auto lhsScale = lhsQType.getScale(); - auto lhsZeroPoint = lhsQType.getZeroPoint(); - - auto rhsQType = utils::getQType(addOp.getRhs()); - auto rhsScale = rhsQType.getScale(); - auto rhsZeroPoint = rhsQType.getZeroPoint(); - - auto outputQType = utils::getQType(addOp.getOutput()); - auto outputScale = outputQType.getScale(); - auto outputZeroPoint = outputQType.getZeroPoint(); - - double lhsRatio = lhsScale / outputScale; - double rhsRatio = rhsScale / outputScale; - - // We find the max in case there is a large difference - // between lhs and rhs scales. - double maxR = std::max(lhsRatio, rhsRatio); - // We want the max shift to be 14 bits - int shift = int(floor(log2(pow(2, 14) / maxR))); - - // Multipliers are converted to fixed-point - int m1 = round(lhsRatio * pow(2, shift)); - int m2 = round(rhsRatio * pow(2, shift)); - int bias = round((outputZeroPoint - (lhsZeroPoint * lhsRatio) - - (rhsZeroPoint * rhsRatio)) * - pow(2, shift)); - - auto xcAddOp = rewriter.create( - addOp.getLoc(), addOp.getType(), addOp.getLhs(), addOp.getRhs(), - rewriter.getStringAttr(addOp.getFusedActivationFunction()), - rewriter.getI32IntegerAttr(m1), rewriter.getI32IntegerAttr(m2), - rewriter.getI32IntegerAttr(bias), rewriter.getI32IntegerAttr(shift)); - rewriter.replaceOp(addOp, xcAddOp.getOutput()); - - return success(); - } -}; - -void ReplaceAdd::runOnOperation() { - auto *ctx = &getContext(); - func::FuncOp func = getOperation(); - RewritePatternSet patterns(ctx); - patterns.insert(ctx); - (void)applyPatternsAndFoldGreedily(func, std::move(patterns)); -} -} // namespace - -// Creates an instance of the ReplaceAdd pass. -std::unique_ptr> createReplaceAddPass() { - return std::make_unique(); -} - -static PassRegistration pass; - -} // namespace mlir::xcore diff --git a/xformer/Transforms/ReplaceAddSub.cpp b/xformer/Transforms/ReplaceAddSub.cpp new file mode 100644 index 000000000..7d0335463 --- /dev/null +++ b/xformer/Transforms/ReplaceAddSub.cpp @@ -0,0 +1,110 @@ +// Copyright 2021 XMOS LIMITED. This Software is subject to the terms of the +// XMOS Public License: Version 1 + +#include "IR/XCoreOps.h" +#include "Utils/Util.h" + +#include "lib_nn/api/MemCpyFn.hpp" +#include "mlir/IR/TypeUtilities.h" +#include "mlir/Pass/Pass.h" +#include "mlir/Transforms/GreedyPatternRewriteDriver.h" +#include "tensorflow/compiler/mlir/lite/ir/tfl_ops.h" + +namespace mlir::xcore { + +namespace { +// Replace TFL Add with Add for XCore. +struct ReplaceAddSub + : public PassWrapper> { + MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(ReplaceAddSub) + + void getDependentDialects(DialectRegistry ®istry) const final { + registry.insert(); + } + StringRef getArgument() const final { return "xcore-replace-addsub"; } + StringRef getDescription() const final { + return "Replace TFL Add/Sub with Add for XCore."; + } + void runOnOperation() override; +}; + +template +LogicalResult replaceAddorSub(T addOp, PatternRewriter &rewriter, + bool negateForSub) { + if (!utils::checkBinaryCompatibility(addOp)) + return failure(); + + auto lhsQType = utils::getQType(addOp.getLhs()); + auto lhsScale = lhsQType.getScale(); + auto lhsZeroPoint = lhsQType.getZeroPoint(); + + auto rhsQType = utils::getQType(addOp.getRhs()); + auto rhsScale = negateForSub ? -rhsQType.getScale() : rhsQType.getScale(); + auto rhsZeroPoint = rhsQType.getZeroPoint(); + + auto outputQType = utils::getQType(addOp.getOutput()); + auto outputScale = outputQType.getScale(); + auto outputZeroPoint = outputQType.getZeroPoint(); + + double lhsRatio = lhsScale / outputScale; + double rhsRatio = rhsScale / outputScale; + + // We find the max in case there is a large difference + // between lhs and rhs scales. + double maxR = std::max(lhsRatio, rhsRatio); + // We want the max shift to be 14 bits + int shift = int(floor(log2(pow(2, 14) / maxR))); + + // Multipliers are converted to fixed-point + int m1 = round(lhsRatio * pow(2, shift)); + int m2 = round(rhsRatio * pow(2, shift)); + int bias = round((outputZeroPoint - (lhsZeroPoint * lhsRatio) - + (rhsZeroPoint * rhsRatio)) * + pow(2, shift)); + + auto xcAddOp = rewriter.create( + addOp.getLoc(), addOp.getType(), addOp.getLhs(), addOp.getRhs(), + rewriter.getStringAttr(addOp.getFusedActivationFunction()), + rewriter.getI32IntegerAttr(m1), rewriter.getI32IntegerAttr(m2), + rewriter.getI32IntegerAttr(bias), rewriter.getI32IntegerAttr(shift)); + rewriter.replaceOp(addOp, xcAddOp.getOutput()); + + return success(); +} + +struct ReplaceAddPattern : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(TFL::AddOp addOp, + PatternRewriter &rewriter) const override { + return replaceAddorSub(addOp, rewriter, /*negateForSub=*/false); + } +}; + +struct ReplaceSubPattern : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(TFL::SubOp subOp, + PatternRewriter &rewriter) const override { + return replaceAddorSub(subOp, rewriter, /*negateForSub=*/true); + } +}; + +void ReplaceAddSub::runOnOperation() { + auto *ctx = &getContext(); + func::FuncOp func = getOperation(); + RewritePatternSet patterns(ctx); + patterns.insert(ctx); + patterns.insert(ctx); + (void)applyPatternsAndFoldGreedily(func, std::move(patterns)); +} +} // namespace + +// Creates an instance of the ReplaceAddSub pass. +std::unique_ptr> createReplaceAddSubPass() { + return std::make_unique(); +} + +static PassRegistration pass; + +} // namespace mlir::xcore From 9bb95f6a7979f9edd679cacd1cc6777c399f76af Mon Sep 17 00:00:00 2001 From: panickal-xmos Date: Sun, 14 Jul 2024 21:58:02 +0100 Subject: [PATCH 4/6] Update test --- xformer/Test/add_broadcast.mlir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xformer/Test/add_broadcast.mlir b/xformer/Test/add_broadcast.mlir index 3ff19e237..faf8920be 100644 --- a/xformer/Test/add_broadcast.mlir +++ b/xformer/Test/add_broadcast.mlir @@ -1,4 +1,4 @@ -// RUN: xcore-opt --mlir-io %s --xcore-replace-add | FileCheck %s +// RUN: xcore-opt --mlir-io %s --xcore-replace-addsub | FileCheck %s // CHECK-LABEL: add_broadcast func.func @add_broadcast(%arg0: tensor<1x15x1x1x!quant.uniform> {tf_saved_model.index_path = ["input_1"]}) -> (tensor> {tf_saved_model.index_path = ["add"]}) attributes {tf.entry_function = {inputs = "serving_default_input_1:0", outputs = "PartitionedCall:0"}, tf_saved_model.exported_names = ["serving_default"]} { From 95007ff86d0c33a01b85bb1eb8f6d6b24b1c2065 Mon Sep 17 00:00:00 2001 From: panickal-xmos Date: Thu, 18 Jul 2024 11:55:51 +0100 Subject: [PATCH 5/6] Add tests and update sub op --- integration_tests/models/8x8/test_sub/1.sh | 6 ++++++ .../models/8x8/test_sub/test_sub_0.tflite | Bin 0 -> 1336 bytes .../models/8x8/test_sub/test_sub_1.tflite | Bin 0 -> 1184 bytes .../models/8x8/test_sub/test_sub_10.tflite | Bin 0 -> 1408 bytes .../models/8x8/test_sub/test_sub_11.tflite | Bin 0 -> 1952 bytes .../models/8x8/test_sub/test_sub_12.tflite | Bin 0 -> 5640 bytes .../models/8x8/test_sub/test_sub_13.tflite | Bin 0 -> 1256 bytes .../models/8x8/test_sub/test_sub_14.tflite | Bin 0 -> 8616 bytes .../models/8x8/test_sub/test_sub_15.tflite | Bin 0 -> 1200 bytes .../models/8x8/test_sub/test_sub_16.tflite | Bin 0 -> 3840 bytes .../models/8x8/test_sub/test_sub_17.tflite | Bin 0 -> 4704 bytes .../models/8x8/test_sub/test_sub_18.tflite | Bin 0 -> 1232 bytes .../models/8x8/test_sub/test_sub_19.tflite | Bin 0 -> 1136 bytes .../models/8x8/test_sub/test_sub_2.tflite | Bin 0 -> 7752 bytes .../models/8x8/test_sub/test_sub_3.tflite | Bin 0 -> 2624 bytes .../models/8x8/test_sub/test_sub_4.tflite | Bin 0 -> 1560 bytes .../models/8x8/test_sub/test_sub_41.tflite | Bin 0 -> 1320 bytes .../models/8x8/test_sub/test_sub_42.tflite | Bin 0 -> 1312 bytes .../models/8x8/test_sub/test_sub_43.tflite | Bin 0 -> 1312 bytes .../models/8x8/test_sub/test_sub_44.tflite | Bin 0 -> 1312 bytes .../models/8x8/test_sub/test_sub_45.tflite | Bin 0 -> 1312 bytes .../models/8x8/test_sub/test_sub_46.tflite | Bin 0 -> 1312 bytes .../models/8x8/test_sub/test_sub_47.tflite | Bin 0 -> 1088 bytes .../models/8x8/test_sub/test_sub_5.tflite | Bin 0 -> 1416 bytes .../models/8x8/test_sub/test_sub_6.tflite | Bin 0 -> 1232 bytes .../models/8x8/test_sub/test_sub_7.tflite | Bin 0 -> 1136 bytes .../models/8x8/test_sub/test_sub_8.tflite | Bin 0 -> 2032 bytes .../models/8x8/test_sub/test_sub_9.tflite | Bin 0 -> 2552 bytes .../8x8/test_sub/test_sub_dual_output.tflite | Bin 0 -> 3352 bytes xformer/Transforms/ReplaceAddSub.cpp | 5 ++++- 30 files changed, 10 insertions(+), 1 deletion(-) create mode 100755 integration_tests/models/8x8/test_sub/1.sh create mode 100644 integration_tests/models/8x8/test_sub/test_sub_0.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_1.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_10.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_11.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_12.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_13.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_14.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_15.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_16.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_17.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_18.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_19.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_2.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_3.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_4.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_41.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_42.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_43.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_44.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_45.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_46.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_47.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_5.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_6.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_7.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_8.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_9.tflite create mode 100644 integration_tests/models/8x8/test_sub/test_sub_dual_output.tflite diff --git a/integration_tests/models/8x8/test_sub/1.sh b/integration_tests/models/8x8/test_sub/1.sh new file mode 100755 index 000000000..4a264cea1 --- /dev/null +++ b/integration_tests/models/8x8/test_sub/1.sh @@ -0,0 +1,6 @@ +cp $1 /tmp/ +xcore-opt /tmp/$1 --lce-translate-tfl --mlir-print-ir-after-all -o /tmp/1.tflite >/tmp/1.mlir 2>&1 +cat /tmp/1.mlir | grep -v Tensor > /tmp/2.mlir +sed -i -e 's/tfl.add/tfl.sub/g' /tmp/2.mlir +xcore-opt --mlir-io --lce-translate-tfl /tmp/2.mlir -o /tmp/t.tflite +cp /tmp/t.tflite $1 diff --git a/integration_tests/models/8x8/test_sub/test_sub_0.tflite b/integration_tests/models/8x8/test_sub/test_sub_0.tflite new file mode 100644 index 0000000000000000000000000000000000000000..3a3ed2e5cea0d473f7363f7fa2632b5c0f3fd856 GIT binary patch literal 1336 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 TM!t0Of(P0c&Xc_qL?QRTqTxJ! literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_12.tflite b/integration_tests/models/8x8/test_sub/test_sub_12.tflite new file mode 100644 index 0000000000000000000000000000000000000000..1c983b9f09bddaca3221b47347ebdd26e506fea6 GIT binary patch literal 5640 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 literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_16.tflite b/integration_tests/models/8x8/test_sub/test_sub_16.tflite new file mode 100644 index 0000000000000000000000000000000000000000..81a1e3cebce2311615a884de04c2228a9880fbd0 GIT binary patch literal 3840 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 JB(12}e+HF{#^L|~ literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_17.tflite b/integration_tests/models/8x8/test_sub/test_sub_17.tflite new file mode 100644 index 0000000000000000000000000000000000000000..3a3493806cfdf02aa9c83e6552d9b473e01a4f79 GIT binary patch literal 4704 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 Xp2^AFnsM@Rb||#>UX~^WQRMy$cPHGm literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_19.tflite b/integration_tests/models/8x8/test_sub/test_sub_19.tflite new file mode 100644 index 0000000000000000000000000000000000000000..5cde7b1e5749ef363f656861377db10ad969076e GIT binary patch literal 1136 zcmZ`&O=}Zj5T2yle6%4Z7(=1~SM<# zi3fjx2hpQF^q?n25G*2ymWZKHNsz8ZT6KM%O_oNX1JBOv?7Z{L$G$lcxpr>4m=aYK ziAYQml7cTIIZqG3o&=5q^8vwkk;lFF5cHTLG6Fmdim0>^vjjhs%-})2*3${tB12$^ zfk}bY&6k5#fjz*2VK182TuC=(wMMz_oo7AFqXMjuXCtsd2}^`EYPv4%->%E|Fko7> zM!i(suJU0j=fm=7LwsCb{vkm=h)tWWu;5+fBn}hwX?)-fUM zL@SpkI2L{*cYo|{fNDTcM$V7 X&V2lHcK$)~F+YX2b6qACM3MI|vplo3 literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_2.tflite b/integration_tests/models/8x8/test_sub/test_sub_2.tflite new file mode 100644 index 0000000000000000000000000000000000000000..578db1d86ab3e02312ece50546f1306b26d4b37d GIT binary patch literal 7752 zcmZ{JcaS6Jm0tr5pc^@KBWGX+lQDU70T$0j}C0Wv)d9+CBXiJoeqEuIQ)!kM3 z51;GGRkr@J?|hPJorC0U)-s|ss z-+S--9%B7W006x7l`HcoU;}sn3`hV4fcEEffax<0_U$u$%=GaW9H74r0PlbCEa+>V zr9brXKe+(VF$2J8-)E^m)mOlu_J@Jaf1wq98vsQ843d5(Uf=pWo~f^GeaQRx$!l-^ z?DaRk|MIJ^eeac@{@|_8_7CbA#If};sBo|s?%Vy8eG32vHNNudt3Z=x*}*f^$LnwW z_@{5ZJo}l?kNeMq`TxVR>|h_i4`m;J`Q0DA`Pz$r@yeU8y?W_KZ+!3d@Av19F`vg6 zocG69=bswn7|0;Umohl_Kn68^xjwK5wGAp8 zG1-T$kHH-c@(u9AS6+XkuRg19;R`*eb5P?z24}fx1c0ae_|wm3WS{LH)DQK$Gl<<6 zldeAu`aOu5PqFNm=l#Po4_+_g&-{3w`HuDNzKjig9;8_o0ECyZ{pFblYrR3Rz6|XD zSV7MMfS}(4UVr?2{{;g8MDJ7{CwSmGg1VXZeRlQfTE|=FnQ9O`LXM9;;+}t|9p!;5NY3_Xe|~Gy z%ZaPDWLimUQ-c+fZSC3t`a%AicR!3<+ncM>^P@>lO zKa6v24S}>H;>STg8Y}W!T(*w=s*;(=`elibJPU4_%dNs$VhHT1EdC*_hszqUc|)uW zUy>^rxcoqwi6a!DF3N*++l`NPIIV&tbu9JZ+j(C8t~o7@R@XR7$z(9r{u!Xg#%fP^ zZXo6<{Z;qVqVJApgas&mcpR>4vnD9RYe*SHGc+@1JX6;+dG@qKH#f?TT4@stJ>9J> z>W*cUF1Z^fb*UI#vaA&YvTU15a^%srpuMcIRAyT<7Z#40BT;AsCn}Yx>Zb33RwjCP zKeMX6)Ukv4JCZO-E;E^b&+F+GOgyveC`WFOej2PK zF0oTu<;L_>suoFT$1?)+eU3tB=|JtgLhIF(z&&S^Ou4O$HEQxRS!H~86$4B zZ&y3Bf2(%kq6*6|g)js-s%%+!L{=584Yf+s8)X+c;VmR}3=it-& zrX@m%&?aENhd`*0v-?XEOf z%GcADVML}H6KY@#rxf2g`+u)}OBOq9t8iYbNtmk)+_sm?=3@NW^x4lulaOIejdcl}?_Z&+oTqbCKBP;nl5kf!n=X9M9fDs+k* z4NS3iNqaA`4~hK8ZN3tfxwexR5K5jaePwK+r2`eq=aRbc`_hqT7+-Pu(w)ZjOA~t4K@lg6*kMXH`gsDTXP(Rvo%>V zdG-XtNBZZFWjOiT3d;q9}sU<&Uo}Cyk}A_*PR%9dLjEf2*r|0;yF5 zM6R|jkBh@q#|bi31&IXEC>7*m$ZkNxUqljIUZOvxcMJSfO5&@qH z1!N}tIkXMY9$^=$8m!aEb@4hqW2kd=kGD5ET%a56D1<{H&^98;o4PXN@;SILf04@u z+LI&Ebk&SRj3<>yoOE1thTZaj6ATS^{L?CyI9+T%tUh_?y(}qB_}pXBgM7@UUe46j z8;@WqmR0T2ctdHBz|y%+=vy${jifRugI;URAQvgeJRs-uV>0SGRB0`lV|JhS=Bm6A zu&*F!F6rR4+!^U`v^z?!j@6=U1vF=>NgXA9tmC)ym4IwXi;q^$g)1Q!RG2PjGADPZ z7-_>0&l>nyOuM(e$ZQj#qu-UyK!&}r=s?&sZ+zV^R|@l5Pvorsur)HgUPNp2Ttu0W z9z5iE9|A{Bpts2cJJpLS$0U&DPgJpm$T-st9@q;jm>fG`dE|;h)OPPnKbo<>lb&+@ zO4UFQaryC@vCZvLjJ$a~P<8%19S;^aHr~E`a^xtrEg-2}Is*I3=0MRBaCd);DJ7!w z)kS$a2i(np_5hLddE>UbReNJ3>HYasKtT(|la?NMDr0?!@Py)tk~ZR6Cv1UIq^siz znRHt9Zf=IFFBK&k&B>`h5j(ii6kR*KjF*Mw~>h{Gw?o7_Jq8vB2 zhFc%W6}$4Jve@v#%&M^6pyw&y*%xBJ8G&_-!ye%78gBPeUJ-ttt(o)cxuo1>I#yR* zZ{Fc_$fD>69Ex7D8h~RGJ7@t+;p`J~QID+0tLHynz!BIDhIemmOCHqaZRTV>VbbtY zbc?l(8yXCaMX`OBNRP(KL93UA+c>`+m7cbLB54s+8n!mfY>!`Cv}k5C1)E3#f=q8N zC@v(!rOBdhjVA-5FZq}Wc=Mb4?k(=22240)&Q2Bt++@{em_kMP(ryWp(XFU##4 za68$97UClIQO3NO6!`^NBU$N5yrM3Pru+>8NYDrG2)q)v8WHD=DNOhn8?Eo!_UGrg zw0Q%}0qFBkdDPJj5NCPK_K*?1ADFF=+OtG)>lTGtQJ!Iu$FS!qr-N$aGcy*x+Qqw7 zu9y{*KSg1a93 zN)-`P3c9S+3%xa%=tfu+Es~<5H~YeIT{X%3w58Bj4Y=fa(Jo5f++nUAEAl4y)@{w8 zP88~{a2W6dXdkLJxg$MO+ypl-vd5$StGo*n)G^2#&L;Apnp2l#YEyt{X;C$Fg?xQ_nHaT%JyoyOUcJ3hxPN)uj4K&}}%mMAL1a~d#(>(rGWoU%r z#f{z8wcN5ZDL`T>nKBE8YWPf>#2P;O{YTrU-Y*{5PJcAqWD7Hr?vOAa&IM;}QEr}#SsJzUiBB5$j^t#%q6CZkKnUQAW5*_Aa%HO7v_fiU4&0i< zXT4nm+#@HU&>Ty0sWm#MlQ6r^7F?H3MK!mM5 zcA~a0{qb)|p>mY$QN>8co1oe7y)NjZ-6@j@&S{~A-4{EJ#}V+3ET!TwZ__Zq1QxQD z?|tIsd*pvp(u{Iiv&*XX64@YGlL4BybUT;Z^Vck(ZJ*WO6I2M%%Ivu&OTIWm^GlYd zFjgFD>Y*lPBu?!Xa~D-1v5M`u+^oYfoITd0nGag6y-l!ZL=u3E{Cgv1Qws4$$Euqy zXrr0QE?wK*w^#x2@bu6q<|%n}nN~i^UhmZs;{Qddo>A`Ci6)2kay`N+yfEsNwAB=x z-SKjk&n{(ms%SzfHVvD+?=WI5F&Tiz6W-kgbGvbb?EvbymMTGey!(N=C2_OIeRWe> zWymE*hWSPSO)oS?x3}n@)#ZpXvXD)|tj>#3R?)HHS2f#BEHbEAL z?1j74Xc|1MO3KQhSbAC3>Xe8T1JWe*uC#J&!~f)O(yoMpQKweHx(X6e@#R==vJNkEuSyiR_;W81XlzEs zfqbzp2h=y8LPfdvRGIS0heAj4UhtHX>z)Z{RN|uespHp4XG&(h_Mi@3#%%Yp5@ncd zS0W>D?Mf~DES-)PqoNGET|GvnW1umAmnp2wBNi}I5?1`Z-bjJv73d6u*<8d8lcw%I8vOC9+A_7@g?*ZpnRJ9KM9vz*xCw|7*rdL&nUpmrPh zVOdV(kS1u3U`$HSbsp&>lXN+tt+ozL*Ap>KacOX^gEktAYuYK;Au)*nN?J-%n`ef(Bb*d(*lS zoR?L?3N7DvMK{zEZ2rCwosb|0t5{4R9}rLlrF%<8uFQHHUB7)u?Ksr`T`UP-HIrel>>s#B+)yQ3!xtX; z)8no2Cr(fqX22q9 zD|MVp3r++;snAm;1k=zy@g~GXVjF83+Mx#>!C&wkM zNXH(Zt1_*v*w|^f9Ln^Zx^j8Pa_|;ZORMuRDp4Wrj9HqT@}K!nhs1T}Q+K3D zPvOLfqW_J~@z&+d#OjXiVyPK}Zft2TY<3&4k$0JkzRN+CGLQa*RTv^=>?G1`p?kXB zWtXTrOUskTt$tEoOC=hKiSQ)JLk>eS<;O}Kf))JGKS^5T{rs{E$5D5#YnAvM<2 z>eor)+&vG^q%XKt>h1&E%%N{l#0OkQw%I423C+o)DL@_%h{WxcG0b?6*u{HJv57^Q zVQQPhIY5$@LM>l9ND!d7d1}NrJYvz}dv%gdh$Wq*E-Qr=Q4!v(<>Iw@8it0?f*|6VQj;b>7DspEQv^6mp+{Yg;bvovh}Br_lyX^5jGO z&u4g)&3NQ%RV5`si1x#jDtq4bZACq?zJFdgt;!=puIH1}i$jHajpDfGaaeLN5t58Q zE7ovyP59Bnh#rW>nvK9>CohTCyAD)=yl98?+?02nyo|%r=gUKZ`)m(a^GA)%p^BcP zS)*;mBa0Y=nKq!1Db)?+d zciJnNhIsr+qEH>GjF{gpTsNTo~y&}sU&CT0@wTdI^T?k$r z8s0y=d(tdaX(AsBd9=ng#}G3ak_Y7B6HxnN{X@bFN?n@h|F*t8hu;D+yk??--RkPX z?~LIbi^W6{1X(a(qOL|rFKD{b`kBp?W(D4VG*PYVL5XNFF)1Rz=vb%2C$J$moqeHZ z0bnCHA(v=WQ{JX|1$q2w?YkZ6a|FO)DKFVetoV~FA^6AF(ZYEOZ z3-HO|Vj~|oRnq1k_dh^77Wr1X$il3Unoky8WiMqRPxo zZeba%&TLQqXT4AFBsP0!m?6+ilV6=^iKF>3qjhvfedK7VT$ZT#CHcf=>B;*tVKOfl zKO5Q-%jcd6o)Tzkj_kg&L14=X)OsYUalpdGsS4bgGf~tWcV=tqh+iDPNbG9m;G4G-S;1I%lASnusv6jLc{8mL9no`UDfev zoj|X?8I+0P_@iGZ^9^(?k1<7sCc4{&=#tpXmX3}bP()dOy%u;F zsn5)ofcErAmx{uO0~c>+A&lD$Vp^7ccwK^TOt$3Ot4W=#73f~=&Nnp95AhR+ooepW zHkb&j=5zWPcq;3nlb#XdaVz$ma+Pbi{N%?YO~n+a|5p8lcClpX+MAk(CG}Uiq}oy0 z{j)>SiYMP)uOs=5n5jxOe{SKl*ho!EVKc2^EhoCi{kQ2PBoR!6ip{V0|BMN9Vx>5# zeUaBwpNQT}-4~RXHJGGlIL}2 zsOj#52a*pEwa}ntmJhzo9}Z988;a){rdjZUqo&_0oob{kh+Dy2N~mv7vLoXBgi-!b zkcrD{Tcx{#LYp#{7q}(CBaNlm6m3g*jR6Fm`mb`F@)pAC;({s930%|l)hw1`{Yuez0wR+pXVCzWdq)8!2Q|!7;sU4jK6xd z&sF^)e?<+*tG*2OaN5N_<*Mm3u>U%j?hkSec(j49t&ahR_s2LjeShu$<5XY%f*bv# j+?wPwCT|dPzzF^ew>Zf6d6l2n`QQEuIK%6E4RZf8OIaV}69P$^$-cH}CmE?#B!($Wf|`(skZCJbYJax> z`>SfDbWy93qBfmr(oTnL3`t0WAp}S;25b!87rZae%j>-ibka&W()Z4J_nvpYbMJl9 zceMb3b4O2i$bb=G00(>^1~NFN0@_W_fbm|4c8E(f0OtX?we`+|zRUrj0P$No014RVJQWS;0V?xwG{N#sM zhX>xj)HgiPf9UGa$AcH)*v{(LHPCvmeb#XdaUeq++lJPS4E3}I`upAWkX7 zmBFFj;TuCEgI5N6KN%RlK6rHq{AP;>?TM|;*4c&#w+!vWnbRk}XM|nB{E>nFHaH@L zXY$Pn3E@Z=L<@uw0__pvL%7m6I0W5hf1O(%^@(~!hSqW$ZqfmW3!5Xt&F@kFY+K_6?5=j=&v)XVQ21ayQx*l#jUI&b=CeHv~j3>U1|N zIelkTCg2j)nQ!+HPqU?BT~~UU^M=@OeU2afF6rgqPgIeH=X2fD9gD1W)wE0}DNJb# zaX+b_m{;G9_CEakdObPyRC27%&&p_0+53fQOq?g|V@)eUr5u6H66}s^Bi-q#<0hVS?d`lOmMcE-mBjiQnbqL z!m2*7M&GEL*jSc^N#JM6y(Etu)7B-sio1{Z?5kb%3fjn0D%qKyay{0`M4!%up6X6k z8u8cziHD-b7@_N2n*N}6;XbvPBnq*HSd2!iY0*d17|qL9V`WO2HU7@Cu!EPgPdX)- zFSnv76SJT_R~42>YH|F0N#L;S#GaB=;fU*_G()y|MW8Xq)VdV$a58)#tF9Ud<#ArA zf<+ecUn=Xhry7*fq*Zq0NV&f3V4B-Ub$__M7|+H2Mpv|o7HTJ(GEIs=(ipWYVY)sC|i`nocojMjWd?R#n|o7E4FO!%5^@=~lie95JH>|B&$HO1m+ zy3+MaO-o6f!gvXHfnY8qU)FQVVU;)CT->lb5-pU?8TacMEFvRj>NFA2ziB*wIc>|m z*=b2!_TVjL1(70JU-IpoSX}DUgHsY)TdwM4!WECuST zPjVPor0Eg@LZ-9|wZcLPDEbfo@y8%naQtF;&M-^&2GXfyVQmsBhfe zAeuNOe^e0Eh`hhHj2l-=uR?_&GgQJ=+~~StkEXSDo)*(o?7Tf`2ZwJkY?#_7eT<}- zWbgx6RlV3Pd6{_KJPXRt8drWr)VyN0yckucr2I!qKZrW&W!i-^Jb_SgjQ=*%VvRNAtZ!Z*TH0@RB|!Mjt0=FmN!zNvlEvb z_R{r|g6yrWkfM78bdC@B+=cXMk24ix>_~j5F*X3cDK?d)J0sP& zzu3)EG!;7%Cg&Vq^uqALz7Q*#d4jR205&eJJSfNy)^_c*B}yrGhC2%y>f<-7-_jGh zq*5T1k-=ET_?qUSj#W4>LIxmlPLtzWS0zCUzW04O|5HDeD#fT2M_iiuvug)8;d!(B z3m@t7DAw6{;%F_T%}iKM^fG@vz*kyNl(vxMk*_IWQw;++(Dr zmV8CK!7mA?50I+38(5nCY@u`Z5l2m_JHA?)J6r9iPatNDT#H;a@^vv%a@yQcT2^!ONEsW#mQ&sGY@Zt zDXGt8w|eKJYi7+@IID3y7b>9k;!sDnZ%0UK*g%0C)HkF literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_4.tflite b/integration_tests/models/8x8/test_sub/test_sub_4.tflite new file mode 100644 index 0000000000000000000000000000000000000000..7bf123c246573370e6fb4929377d26dc629792cb GIT binary patch literal 1560 zcmZ`(TTdHT5I)9>Szj@};RV}lzyXp_0|hsfOH{SZrHEGa_7=%(j+%kV+HRn%&*36TMV0+=YUp2jnQW&xFeF}Lr!$9vV`a$j+d5BY`lm=DHb0hl4K zrNIVDun55%oh}zi9P&K=R{%WT(Q&_{UGN!&e;ogc=XqQQX_6|yhwqR0+;3lV`rNKp zM!Z)%S7Gdh!qXVI-_h?oE+PjCa+C!3je*dV9SCjn~+k&0dd8#!6PB|s@pxDMey@H{aF-pQcT=lA&Ggy2q`LqpwoEa;Ei zc%~)a0K_is8Rsw-3fiAG$@|a~>jeFAy&4jFd@FHxLrVY7)YvI*T3=X+l?PJ#veo-y z@%B#3M!Pu{*6Nayd(FQbe00JnY6^T(-<8}7-dGej?x>mGe@Gn{lV{PM~|CV_C9pT+o>{*?Cho7UnE-i#0cP9k;$)KgrF{YA)Ksl2mOX zJ(*pg)ccHm>U2=G6p|@vTg&bBil&T0d#IMJ)AE|NnCyV2(%G-$+s|)5)NcHv+ol&9 z;s>$w`7^Yr+WPRcd5NajY&RQH8|mo{xx)xFqCwVo8$Q_8_Yve(iVF+8WYs|uFQwX!|y+})`CAp1y|1A*GGWCE}gQ`IQ;7uJW5eWY*k&*i1)nYF2rEN*o!Ji7YRh9!&Df zaV8sWj7CMGsus&`k`jd!HB_FjPP1REJ~$!I*zYcBsEtg}kZ1lPZJB~9$MMV4@8*<$ z*v;zI93ckiDH>{|^y)#OKnEC5LEU2gV;y7Nu>h>CVLV6N4T&r(3b^ZPafAJ49xxSjdT>>x?_7qA#^6j#14PO|NxnOC=gygL&dj;TA%r-wzoW?_ zoI(;hVGt%^fv-|HR9y_a6=(!b6$yM7;zs_x1bRXe;u~;9Bg9AOTEq;(4<$PBppNCW z3APZWU@(A5g0-B_0qq3JfHS_}S%0A0?e%qe26{s3de*}{PJk71tqwLQVF|$+JzlSf zFXnQ5mjQpEe<0*`sWJU{r~hg$m*YAuUu~G@ zI#rKRUC;VuOozE4j!HZ@Z|2mYw}t(#%*FGfSK}l#whlI=jxlesMhK;-9X2_gz(Jr; zC&rQEUO5l?IFqBEV8|arhcFXQPtR_)h2O}%GWHR2v%bQ&43k0NQe(YGz7j2rKm5(aZcbl4d) zjff+y@@)9-V1-d{&%HU?W`B}e$kgmgel7i2)$V$s96X*K*DH^!rfZ)M?|HrBvmCL7 zE7q2$!)wyR+6iW}!|uF4f$?fF=8b^x3^xjA#%HsGJT!=1ka h)H75#vy3&UCzUyP;{W_RtcCd~wAY^&trDWR<~NV37ft{G literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_42.tflite b/integration_tests/models/8x8/test_sub/test_sub_42.tflite new file mode 100644 index 0000000000000000000000000000000000000000..c8fdf4a0be49ffee64d938e5d07f4a689ced989f GIT binary patch literal 1312 zcmZ`(TTc^F5I&SG%hFm}DV1K-;uRDL4G_FQBr)-lpdsR;Nz>S>HBd+?#s?FP|G>l_ z;FG@a;PpvjOcd|2kchXS7@)NQr2%TSEl|I2X#<)#$+t5*XU@!b&djbu2yxs`a*7(8qYN%zw zobVowwjDX{1S`aceBN4k4Cu*9hYaxS25JB&z&m0+qRZnCK&kv1a+*BJk;1d|!?7C( zsUCy6pZsNXhq)n+3Ov|v<}~7N^XFZiOE1<6of;>pvDL64)r=9sf+;E%MOay$D$bP* zFGVS6#gkl|z+oWIA8pF=4%jF9*sFF=Fys&6=FlroXXjpC7uU#Xb?hW~l6QVB&14X` z)L8E^xkZ2xXNY}dTn&`mIt6H9h9Ui3C$Dg63glBU1!iqvn6N6nUm zJiOyU`qE~rrh4S^mc5DCms=xJ)wIbtu2~pQG$w!k{wTFf3>x3eXp+{%Kr}Nuud7VV z815S5dQ*9H#2GV=iet_4T=@P#xj|>o4!5`1pCuR4TlXZslzgzYx?U-VJ2DeG<*Ds^ z)yt86Lye#0h&5ckp)3_%pPGrLH$H!7zxBiO=yqg#Cj88Nr0$!XSU;b9m;;LV3%u6PHMA6$PO{Q+nO*Kr7nxkWuX=P~ZTsnSeahIa8 zZu?xb;iIChOf^?d%$BxU)=8zagB4Q|Tfw3uZW$}gG%dK6)%oCT gF`jcotyd?MJ?Esad^23*j8JHAIwzVXL~%C$00}M<{{R30 literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_43.tflite b/integration_tests/models/8x8/test_sub/test_sub_43.tflite new file mode 100644 index 0000000000000000000000000000000000000000..937fe3022e2829d838b825d50d3b24131ee9d6b5 GIT binary patch literal 1312 zcmZ`(TTc^F5I&SG%hFm}DV1K-;uRDL4G_FQBr)-lpdsR;Nz>S>HBd+?#s?FP|G>l_ z;FG@a;PpvjOcd|2kchXS7@)NQr2%TSEl|I2X#<)#$+t5*XU@!b&djbu2yxs`a*7(8qYN%zw zobVowwjDX{1S`aceBN4k4Cu*9hYaxS25JB&z&m0+qRZnCK&kv1a+*BJk;1d|!?7C( zsUCy6pZsNXhq)n+3Ov|v<}~7N^XFZiOE1<6of;>pvDL64)r=9sf+;E%MOay$D$bP* zFGVS6#gkl|z+oWIA8pF=4%jF9*sFF=Fys&6=FlroXXjpC7uU#Xb?hW~l6QVB&14X` z)L8E^xkZ2xXNY}dTn&`mIt6H9h9Ui3C$Dg63glBU1!iqvn6N6nUm zJiOyU`qE~rrh4S^mc5DCms=xJ)wIbtu2~pQG$w!k{wTFf3>x3eXp+{%Kr}Nuud7VV z815S5dQ*9H#2GV=iet_4T=@P#xj|>o4!5`1pCuR4TlXZslzgzYx?U-VJ2DeG<*Ds^ z)yt86Lye#0h&5ckp)3_%pPGrLH$H!7zxBiO=yqg#Cj88Nr0$!XSU;b9m;;LV3%u6PHMA6$PO{Q+nO*Kr7nxkWuX=P~ZTsnSeahIa8 zZu?xb;iIChOf^?d%$BxU)=8zagB4Q|Tfw3uZW$}gG%dK6)%oCT fF+M*>dUZnCb58ooH^Ugt2!-~hbD~*76ldcP3Dy$= literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_44.tflite b/integration_tests/models/8x8/test_sub/test_sub_44.tflite new file mode 100644 index 0000000000000000000000000000000000000000..70feb78543a53661d099f9ec210807c640ec5838 GIT binary patch literal 1312 zcmZ`(TTc^F5I&SG%hFm}DV1K-;uRDL4H&#YG|_lT&=B>}q-kuG8YrX|i07Tg*o!VdsE0Mzt1(fkr{Ik%vlC>_yg`>cOc~N@VU?Wf@l1l0dXmphc$84x*BSk zFej|Tp_YS3oL~k2kk4BSivc}Z>W~4JZ9om+1Xv^HBRV|(0F=tFA*acc94WlZbr`k* zA=P3~&y&B5?l3mQQGo~h&6q~iHhDdPT&BL=Z`jJSp)WoHukF36Abx7s2qCbX>Z@ba&eEGe)k;*Px8+1r5OwY zlj`d|EH?`<;ta8m^s7OT(MPkdqb15Ko4rw+d1A>9#f#o0EQOyxNYdojEs^@w@u=C7 zkl${4kiM|is;Tb3xNb)xHhimJs+u$zM>TV!iLJ@+KL@4ev0mewDNWLv=!s^gXLXf{ zDZ^c3TyH9m_B&(7A#u1#o(bRYDL3fs*|)9D_Giht^!n|I;gSK{Zr3a2z|qW@PI+qk zTJ^GjXW!P3a>N=gUsaY0uS`uv)2pAqx8M5ad2~CnF%y1fK3MlfPOO|wK1_wRrl0o4 z$D2otAIEeCrLOkHcyZN_W#$EwKBDOD<8fVD(I!*ZW+oaYhRo3s%cRn`ekL8?KfguM zST}sCSv9C=D^pFCW7DNAmK9RzbZ^B(#8xoxh+9SqGmUeu1vxcU7TXo;_1#eGsT8oz z>@#QG39uLc>&tnZ$ls)I9FMTuI=ZsLeUUOPBN$}!q`~o)$6AJ(U literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_45.tflite b/integration_tests/models/8x8/test_sub/test_sub_45.tflite new file mode 100644 index 0000000000000000000000000000000000000000..ad4b49749667df34e4bc0dc83a9ad93591205cbf GIT binary patch literal 1312 zcmZ`(?MqW(6n~s|Uawno%emZ3HG9=EacJ0!Qc&~)7E*l-#%L=SI%Uo1Ls0Y|1pNVh zE20m*eo7)Jd#4#>X_$t(HMAV+T5VI;?|0p>q7MA-dG2}6bI$KM=iKWMLLA%IQg0Sc zA&Fw47e--*twK0dU5IrPPzSUX2xZa zT8I*4&?A$C)nYscv=b-=&iI07{ee?%ukWO%yFH|yCm+Uf0%XXu#aJUHRzi@Y$LkgE z=d)S9%YZ-7)g5xXRG%)q(|$FZ&GMWUFahUIbOwD#+dM&^cTZ>Fr2iCbwuQwQyl>Z? z`u)s7VUE1;-V}1m?{iIVWX2o>bCv-e{(w8!9SHe5eD1Tp;2D2sKwQe@VNG1Mu7+AB z%n9posO8`hCs@Hh&ENO;SbDKs=u|&R^{vJlQcWKrESREVQG}hvsp4G8 zuu_zQ-FT9V6F30m`J+u))_{GYjlF911VjE1Du-Tq+S_-qT-+n4-+jlylf3hLX$FJ9 zr22Xf%gq9eI793s{b~?o^wI3=Xo>R5W^dGHo>;O&@uGJLOX24ak~H~sOQe2vJZiQi zSzTpf z%5c{h*PF_t{mz(iNE~jGXTtY;$_+Yu_HApk{aJD@y?%RQxMaY#+x1F0a5OWfQ=Zzs zR=w=s*|+th9I=MWSCys0D^pX^^y=sD?YF*p9^H;?%!Hqr57vE=6Dwzv4^v^S>8HK% z@#YcZ$1$BjsjGc4UR?EKnR&sak0^TkcwCoOw8_-9nTdvpA#-%ZGO6^fpGn8}&u>vQ z)(xL(Rt+lJ%2ZS3*mP-&Wrb8a-CHpcu@%fa;+B!ZOyituK~7DT#dgJdeK*v4Dg~@F z`^;H)0_?^A`f?s;@-s?5f^UcW>6_smXN1D_n$x05f){7w7dQG74*&oF literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_46.tflite b/integration_tests/models/8x8/test_sub/test_sub_46.tflite new file mode 100644 index 0000000000000000000000000000000000000000..f41c031dd1f7ae0848e6c030e739d5f0a9c1a3a9 GIT binary patch literal 1312 zcmZ`(TTc^F5I&SG%hFm}DJ#9G#VaTh8ZdZ)Xrl3wpdsp`Nz>S>HBd+`#s?FP|G>l_ z;G4$y;PpvjOcd|2n25I^7@)NQr2%TSEl|I2Y2z(U^6kvdnRDhlGqdXyLLA!F)@T(j zA&F996lP(CuSz&IT@1SgXaJ5E39JioE&pBuJtztB4!Eroq93{jF}?6ZiNknM$Mf0@ zTZl4bFd~x#YvDX6vNV*pZ}=0rz5QGCm){U0?3eiOJO4=EFs9z>+^{> zbGaPfWgrmj?g@L`T1+?I>A#fA<+x7|Sb)<HWX2o>b5;PIfuJYU6ATAB{hm|)(8)koP@K=_VNKli?xuPs z%nR$VuWj!E7g!-a?Dy5fV?s}Ub;tzICZG;*0jv@85uM&Z5K80Ml-J}*juhVI3LKk& zu;wvo`^jHMcX&3$S%nAt%`?rYZQ;JZ-`OY@3xgIXX|c7iA+-xJDyFDZlwf6HsyJ7& zP_+=HXgf5yxPU!Cfj`=mV-46R`q-;>ZzvoHqjKn#x1(bV%f&Tv`aO0GJjuJTmf>L# zxU^W`ez{eE5od^fWLzB%8M#06B37n6w>z5k*@tRwFj4Y4sTO~FD@hYyHbfhjCt_AL zDZg5GH*)wXXa&qZR>RvjcxBPH4 zKUhC({xE7VDGl{c$4YCyFS5>Cj8Vnt7)uy3iawRTJU!ktK4^^%s}oB9>gh~k_uK|W zXIt~JZrOW9U!88L9-S(0QGd z*=NqW3t%t)*OxQcQOrD?;nQc3{T#W*v9RuL;9rmPLDvy*{FcS9R?8NB{I#?mz zx2+O9Im~2ZLOFPj0K7+n*eozqN0) zz4+nbyfV1dn{Or8TkS(XzOTMh#y`vbuwEuX9_$0(f)0@D|9I1X183qHa!pXE@7(=} zUrNc2^(*U`|Kfw_MU4prXY%E F{s6^?qlW+h literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_5.tflite b/integration_tests/models/8x8/test_sub/test_sub_5.tflite new file mode 100644 index 0000000000000000000000000000000000000000..ca3e769c43e3aad77e0d7c881b9263ac79b87cbe GIT binary patch literal 1416 zcmZ`(TTfG26yBwWa$4F_X@MRnaHgVoAuS!iK`w^G3ywj9&ODkl9b2^uh16mu#zffwfDF7UTbd? zW9-*`9d!mKGLG>~&2-EFpOKj)Er;C#)B-1E4C9Rbo%vTl@5yDX4Y-oSSR?cn#Pq`t z#g5`bI-Jou*o>*bpav5M>+5X}8KHAH*zxlb5m_PL=W<%$(V`}+71F}f2-E-~KxagJgl>o11105G zpV5>jvQ{XLa2$OtE-8Qh2n{ukd1X>?d+bj zV;GiV&Rx^AQY7^W#nb$Y2>N(G`g~l;|0k3-aH&T{D{msXL-C@V4=?5N$*G!gTX`g; zH^dY#w%lDf|ASFhJ#^9B7z>YHAC_;P(rE*-#XziXE7HcoC+xU zC&sDG14B*zy4Q-J(Qha(Ob(iokx;7Q*>LIgY5VKK7AYFdNi{6iE-R8Vh2hpukA9n0PCwWf z)(4``6!$`*(XrHp+_HIV{J_W^p{l;}Rzs)mv~5BgQIEacrHxlinKcv2xk64bZU4z? z-jguRE33mBDtB5r>n6FG({!%HS}IVJV)QVNnq*%Ys#qSpBuW|e8}$v{9TA|qu3LZf z&f5ATR1%ug-50=f>-D67vG3j_d**Ffw>Q<&O`tXDMy=jW R;-j7?A=`Y4wQz_c?l0g}GPnQ$ literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_6.tflite b/integration_tests/models/8x8/test_sub/test_sub_6.tflite new file mode 100644 index 0000000000000000000000000000000000000000..ddd3ced2c1f06270dc4edd1a0829baf77fafe14f GIT binary patch literal 1232 zcmZ`(-%C?*6hF?Zb8gLvb2vBi_KP%1Tq>0*2tg@WNcJeK(Wc(eDRWA1`Pf4*K~K>` ze?Sjb^pu3q4(Od(J)I^F6=sb&JS_)9rP3QALpg zv4~CV(3Och&2u3)0kuGHj^JG6Zst87{JJ7?4Y+L(83nI`%{cU6(uD{4Qij_gixeV) z1(6g;oBrJ3Do_Lr1wtcQu*d5Ubo++;!s+|WhkjIm8S-ucWQ2qy!W?~mzr=s1QhYZ8 zT5xbU?DeE=2Jue)om48tdwD=HaOKiKDA3vK3kCeA27=vM4|GTWZ2DlmgZJysFb0V+ zvc$Sc%qe?LnYl4D#vmB81nAd--q3I`tn~-HBZ1J6HV~9snKngi{}nCBLni_vmr!1KX;lxHJ}3mu$0guF3d4@^HM= zYIdb&I+|URiC-HBPUv%m@5@^}Q>NC=Y{DooBnhJLdz>_2x<1=x?B z`sl|Dvb#e&f<%7f<|lmm4*UuJja9ZS7UxM@72q!IG+QUm{`2Z|0;iYU+yDRo literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_7.tflite b/integration_tests/models/8x8/test_sub/test_sub_7.tflite new file mode 100644 index 0000000000000000000000000000000000000000..3332f8c48d0d0552d4e656dbb279eb0ad2b9ef30 GIT binary patch literal 1136 zcmZ`&O=}ZT6unKSP11&#U>p(+IHHS2YA~jvlokZR52zsOvJi*Pv>iw$A)OQ#g8l`; zmALQ+xDZ|1MHjkK1i>JJXo(mKl?3Tn#8%@ulMJmw9-O&%?z``v`|(~{L~dM|$tOe; zMM4shm?U6JO4^fy(5HZtz~X>lU*vJ`e;9IH5g7v>21GRK@L7Q!LT2%yT<^&kbdeD- zM8Kp#>&8n%YQR2V$*eA0_Cmoh=k;3A@y;_J#?b&~$g?5npoAvE9CgEx*6&V-|3SdA zD>bK(^L#4!r~Of<)8V-xAP(G`D_70yi+a^G&X?_ZYXP=Xf4VVPZ{=zJB00Fo;V;(B z#hmdcLqk%J)TexPL8g=)=qtddz+Hmgfk*_H=A9`+=c%}r!U*jwzwm6^-eG-L&T z$279AL@|@y2}NN!3ycFAz#fs0DCw3B;pI2clgyJja@6hc$|X2hKq!rv_XC{5&xZFJ>4v#^6k@>Q%>b z&>_r3FBT`+7W$K$@O^J1HuLlM{G4F&{OXy=w8${#py1o}n}ckuZoY1ggkK#zbY^J# zh1&Vp9)9PlgKO^-gK83yi-d>^ihWgGR;!T_} Vd2@E}Ao)03F6!=0nNr|I?!SPJt8xGU literal 0 HcmV?d00001 diff --git a/integration_tests/models/8x8/test_sub/test_sub_8.tflite b/integration_tests/models/8x8/test_sub/test_sub_8.tflite new file mode 100644 index 0000000000000000000000000000000000000000..397d945444917d31ec5cae6593d632cba874a380 GIT binary patch literal 2032 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 literal 0 HcmV?d00001 diff --git a/xformer/Transforms/ReplaceAddSub.cpp b/xformer/Transforms/ReplaceAddSub.cpp index 7d0335463..b7bf738c6 100644 --- a/xformer/Transforms/ReplaceAddSub.cpp +++ b/xformer/Transforms/ReplaceAddSub.cpp @@ -39,7 +39,7 @@ LogicalResult replaceAddorSub(T addOp, PatternRewriter &rewriter, auto lhsZeroPoint = lhsQType.getZeroPoint(); auto rhsQType = utils::getQType(addOp.getRhs()); - auto rhsScale = negateForSub ? -rhsQType.getScale() : rhsQType.getScale(); + auto rhsScale = rhsQType.getScale(); auto rhsZeroPoint = rhsQType.getZeroPoint(); auto outputQType = utils::getQType(addOp.getOutput()); @@ -55,6 +55,9 @@ LogicalResult replaceAddorSub(T addOp, PatternRewriter &rewriter, // We want the max shift to be 14 bits int shift = int(floor(log2(pow(2, 14) / maxR))); + // For doing subtraction with add op + rhsRatio = negateForSub? -rhsRatio: rhsRatio; + // Multipliers are converted to fixed-point int m1 = round(lhsRatio * pow(2, shift)); int m2 = round(rhsRatio * pow(2, shift)); From b38807192b875b433a8adc1216f31cc52713c8cc Mon Sep 17 00:00:00 2001 From: panickal-xmos Date: Thu, 18 Jul 2024 12:00:48 +0100 Subject: [PATCH 6/6] Update macos arm tag for github actions --- .github/workflows/release-beta.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml index 1ae3ca09f..bc01ad9fd 100644 --- a/.github/workflows/release-beta.yml +++ b/.github/workflows/release-beta.yml @@ -112,7 +112,7 @@ jobs: if: github.event.pull_request.merged == true name: Build release wheels for macOS arm64 needs: [build-release-archive] - runs-on: macos-11 + runs-on: macos-14 strategy: matrix: python-version: [3.9] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c62e9ad0e..0adebdd57 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -122,7 +122,7 @@ jobs: macos-arm-release-wheel: name: Build release wheels for macOS arm64 needs: [build-release-archive] - runs-on: macos-11 + runs-on: macos-14 strategy: matrix: python-version: [3.9]