This commit is contained in:
@@ -1,39 +0,0 @@
|
|||||||
#include "ContractionMaterialization.hpp"
|
|
||||||
|
|
||||||
#include "src/Accelerators/PIM/Common/IR/ConstantUtils.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/CompileTime.hpp"
|
|
||||||
#include "MatrixProductLowering.hpp"
|
|
||||||
|
|
||||||
namespace onnx_mlir {
|
|
||||||
|
|
||||||
mlir::Value materializePaddedContractionInput(
|
|
||||||
mlir::Value input,
|
|
||||||
mlir::RankedTensorType paddedType,
|
|
||||||
mlir::PatternRewriter& rewriter,
|
|
||||||
mlir::Location loc) {
|
|
||||||
return createPaddedInputCompute(input, paddedType, rewriter, loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
mlir::FailureOr<mlir::Value> materializeTransposedContractionConstant(
|
|
||||||
mlir::Value input,
|
|
||||||
mlir::RankedTensorType resultType,
|
|
||||||
llvm::ArrayRef<int64_t> permutation,
|
|
||||||
mlir::PatternRewriter& rewriter,
|
|
||||||
mlir::Location loc) {
|
|
||||||
auto denseAttr = getHostConstDenseElementsAttr(input);
|
|
||||||
auto inputType = denseAttr ? mlir::dyn_cast<mlir::RankedTensorType>(denseAttr.getType()) : nullptr;
|
|
||||||
if (!inputType || !inputType.hasStaticShape() || !resultType || !resultType.hasStaticShape()
|
|
||||||
|| inputType.getRank() != resultType.getRank())
|
|
||||||
return mlir::failure();
|
|
||||||
|
|
||||||
auto transposedAttr = transposeDenseElementsAttr(denseAttr, permutation);
|
|
||||||
if (mlir::failed(transposedAttr) || transposedAttr->getType() != resultType)
|
|
||||||
return mlir::failure();
|
|
||||||
|
|
||||||
return getOrCreateConstant(rewriter,
|
|
||||||
rewriter.getInsertionBlock()->getParentOp(),
|
|
||||||
*transposedAttr,
|
|
||||||
resultType);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace onnx_mlir
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
|
||||||
|
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
|
||||||
#include "mlir/IR/PatternMatch.h"
|
|
||||||
|
|
||||||
namespace onnx_mlir {
|
|
||||||
|
|
||||||
mlir::Value materializePaddedContractionInput(
|
|
||||||
mlir::Value input,
|
|
||||||
mlir::RankedTensorType paddedType,
|
|
||||||
mlir::PatternRewriter& rewriter,
|
|
||||||
mlir::Location loc);
|
|
||||||
|
|
||||||
mlir::FailureOr<mlir::Value> materializeTransposedContractionConstant(
|
|
||||||
mlir::Value input,
|
|
||||||
mlir::RankedTensorType resultType,
|
|
||||||
llvm::ArrayRef<int64_t> permutation,
|
|
||||||
mlir::PatternRewriter& rewriter,
|
|
||||||
mlir::Location loc);
|
|
||||||
|
|
||||||
} // namespace onnx_mlir
|
|
||||||
@@ -1,902 +0,0 @@
|
|||||||
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
|
||||||
#include "mlir/Dialect/Arith/IR/Arith.h"
|
|
||||||
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
|
||||||
#include "mlir/Dialect/Linalg/IR/Linalg.h"
|
|
||||||
#include "mlir/Dialect/SCF/IR/SCF.h"
|
|
||||||
#include "mlir/Dialect/Tensor/IR/Tensor.h"
|
|
||||||
#include "mlir/Pass/Pass.h"
|
|
||||||
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
|
|
||||||
#include "mlir/Transforms/DialectConversion.h"
|
|
||||||
|
|
||||||
#include "Conversion/ONNXToSpatial/ONNXToSpatialVerifier.hpp"
|
|
||||||
#include "mlir/Transforms/Passes.h"
|
|
||||||
#include "src/Accelerators/PIM/Common/PimCommon.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Common/Support/DebugDump.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/Common/BiasAddUtils.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/Common/Common.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/Common/MatrixProductLowering.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/Common/RowStripLayoutUtils.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/Patterns.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/PlanLowering.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Dialect/Spatial/SpatialOps.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Dialect/Spatial/Transforms/MergeComputeNodes/SpatialDataflowCsvExporter.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Pass/PIMPasses.h"
|
|
||||||
|
|
||||||
using namespace mlir;
|
|
||||||
|
|
||||||
namespace onnx_mlir {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
static FailureOr<RowStripPhysicalValue> getRowStripValue(Value value) {
|
|
||||||
return getRowStripPhysicalValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value> publishRowStripValue(Operation* planOp,
|
|
||||||
Value storage,
|
|
||||||
PatternRewriter& rewriter) {
|
|
||||||
auto logicalType = dyn_cast<RankedTensorType>(planOp->getResult(0).getType());
|
|
||||||
if (!logicalType)
|
|
||||||
return planOp->emitOpError("requires ranked logical output type"), failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> value = describeRowStripPhysicalValue(storage, logicalType);
|
|
||||||
if (failed(value))
|
|
||||||
return planOp->emitOpError("lowering produced invalid row-strip physical storage"), failure();
|
|
||||||
FailureOr<Value> blueprint = createRowStripStorageBlueprint(
|
|
||||||
storage, logicalType, rewriter, planOp->getLoc());
|
|
||||||
if (failed(blueprint))
|
|
||||||
return planOp->emitOpError("failed to create row-strip storage Blueprint"), failure();
|
|
||||||
rewriter.replaceOp(planOp, *blueprint);
|
|
||||||
return *blueprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isRowStripSelected(Operation* op) {
|
|
||||||
auto selected = spatial::getSelectedPhysicalLayout(op);
|
|
||||||
return selected && *selected == spatial::PhysicalLayout::NHWCRowStrip;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isDenseSelected(Operation* op) {
|
|
||||||
auto selected = spatial::getSelectedPhysicalLayout(op);
|
|
||||||
return selected && *selected == spatial::PhysicalLayout::DenseNCHW;
|
|
||||||
}
|
|
||||||
|
|
||||||
static spatial::PhysicalLayout getKnownPhysicalLayout(Value value) {
|
|
||||||
if (auto materialize = value.getDefiningOp<spatial::SpatMaterializeLayoutOp>())
|
|
||||||
return materialize.getTargetPhysicalLayout();
|
|
||||||
if (auto blueprint = value.getDefiningOp<spatial::SpatBlueprintOp>())
|
|
||||||
return blueprint.getPhysicalLayout();
|
|
||||||
if (Operation* producer = value.getDefiningOp()) {
|
|
||||||
if (auto selected = spatial::getSelectedPhysicalLayout(producer))
|
|
||||||
return *selected;
|
|
||||||
}
|
|
||||||
return spatial::PhysicalLayout::DenseNCHW;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LogicalResult verifySelectedLayouts(
|
|
||||||
func::FuncOp funcOp, const spatial::SpatialTargetInfo& target) {
|
|
||||||
LogicalResult result = success();
|
|
||||||
funcOp.walk([&](Operation* op) {
|
|
||||||
auto capability = dyn_cast<spatial::SpatialLayoutCapabilityInterface>(op);
|
|
||||||
if (!capability)
|
|
||||||
return;
|
|
||||||
auto selected = spatial::getSelectedPhysicalLayout(op);
|
|
||||||
if (!selected) {
|
|
||||||
op->emitOpError("requires a selected physical layout from SpatialLayoutPlanning");
|
|
||||||
result = failure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (*selected != spatial::PhysicalLayout::DenseNCHW
|
|
||||||
&& *selected != spatial::PhysicalLayout::NHWCRowStrip) {
|
|
||||||
op->emitOpError("has an unsupported selected physical layout");
|
|
||||||
result = failure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SmallVector<spatial::PhysicalLayout> operandLayouts;
|
|
||||||
operandLayouts.reserve(op->getNumOperands());
|
|
||||||
for (Value operand : op->getOperands())
|
|
||||||
operandLayouts.push_back(getKnownPhysicalLayout(operand));
|
|
||||||
auto alternatives = capability.getLayoutAlternatives(target, operandLayouts);
|
|
||||||
if (llvm::none_of(alternatives, [&](const spatial::LayoutAlternative& alternative) {
|
|
||||||
return alternative.resultLayout == *selected
|
|
||||||
&& alternative.operandLayouts == operandLayouts;
|
|
||||||
})) {
|
|
||||||
op->emitOpError("selected physical layout is not lowerable for its explicit operand layouts");
|
|
||||||
result = failure();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value>
|
|
||||||
lowerRowStripRelu(const RowStripPhysicalValue& input, spatial::SpatReluPlanOp planOp, PatternRewriter& rewriter) {
|
|
||||||
return applyRowStripRelu(input, rewriter, planOp.getLoc());
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value>
|
|
||||||
lowerRowStripSilu(const RowStripPhysicalValue& input, spatial::SpatSiluPlanOp planOp, PatternRewriter& rewriter) {
|
|
||||||
return applyRowStripSilu(input, rewriter, planOp.getLoc());
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value> lowerRowStripBiasAdd(const RowStripPhysicalValue& input,
|
|
||||||
spatial::SpatBiasAddPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) {
|
|
||||||
return applyRowStripBiasAdd(input, planOp.getBias(), rewriter, planOp.getLoc());
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value> lowerRowStripAdd(const RowStripPhysicalValue& lhs,
|
|
||||||
const RowStripPhysicalValue& rhs,
|
|
||||||
spatial::SpatAddPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) {
|
|
||||||
return applyRowStripAdd(lhs, rhs, rewriter, planOp.getLoc());
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value> lowerRowStripConcat(ArrayRef<RowStripPhysicalValue> inputs,
|
|
||||||
spatial::SpatConcatPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) {
|
|
||||||
auto outputType = dyn_cast<RankedTensorType>(planOp.getOutput().getType());
|
|
||||||
if (!outputType)
|
|
||||||
return failure();
|
|
||||||
return applyRowStripConcat(inputs, outputType, rewriter, planOp.getLoc());
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value>
|
|
||||||
materializeRowStripToDense(const RowStripPhysicalValue& rowStripValue, Location loc, PatternRewriter& rewriter) {
|
|
||||||
if (rowStripValue.logicalType.getRank() != 4 || !rowStripValue.logicalType.hasStaticShape())
|
|
||||||
return failure();
|
|
||||||
return createRowStripAssemblyBlueprint(rowStripValue, rewriter, loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value> materializeDenseToRowStrip(
|
|
||||||
Value input, RankedTensorType logicalType, Location loc, PatternRewriter& rewriter) {
|
|
||||||
if (!logicalType || !logicalType.hasStaticShape() || logicalType.getRank() != 4
|
|
||||||
|| logicalType.getDimSize(0) != 1)
|
|
||||||
return failure();
|
|
||||||
auto nhwcType = RankedTensorType::get(
|
|
||||||
{1, logicalType.getDimSize(2), logicalType.getDimSize(3), logicalType.getDimSize(1)},
|
|
||||||
logicalType.getElementType(), logicalType.getEncoding());
|
|
||||||
auto rowsType = RankedTensorType::get(
|
|
||||||
{logicalType.getDimSize(2) * logicalType.getDimSize(3), logicalType.getDimSize(1)},
|
|
||||||
logicalType.getElementType(), logicalType.getEncoding());
|
|
||||||
auto rowsCompute = createSpatCompute<1>(
|
|
||||||
rewriter, loc, rowsType, {}, input, [&](Value denseInput) {
|
|
||||||
Value nhwc = createLinalgTranspose(
|
|
||||||
denseInput, nhwcType, {0, 2, 3, 1}, rewriter, loc);
|
|
||||||
Value rows = tensor::CollapseShapeOp::create(
|
|
||||||
rewriter, loc, rowsType, nhwc,
|
|
||||||
SmallVector<ReassociationIndices> {{0, 1, 2}, {3}});
|
|
||||||
spatial::SpatYieldOp::create(rewriter, loc, rows);
|
|
||||||
});
|
|
||||||
Value rows = rowsCompute->getResult(0);
|
|
||||||
FailureOr<Value> storage = createRowStripStorageFromRows(rows, logicalType, rewriter, loc);
|
|
||||||
if (failed(storage))
|
|
||||||
return failure();
|
|
||||||
return createRowStripStorageBlueprint(*storage, logicalType, rewriter, loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<Value> lowerDenseBatchBiasAdd(Value input, Value bias, RankedTensorType resultType,
|
|
||||||
PatternRewriter& rewriter, Location loc) {
|
|
||||||
auto producer = input.getDefiningOp<spatial::SpatGraphComputeBatch>();
|
|
||||||
auto inputType = dyn_cast<RankedTensorType>(input.getType());
|
|
||||||
auto biasType = dyn_cast<RankedTensorType>(bias.getType());
|
|
||||||
if (!producer || !inputType || !biasType || !inputType.hasStaticShape() || !biasType.hasStaticShape()
|
|
||||||
|| !resultType.hasStaticShape() || inputType.getDimSize(0) != producer.getLaneCount()
|
|
||||||
|| biasType.getDimSize(0) != producer.getLaneCount() || resultType.getDimSize(0) != producer.getLaneCount())
|
|
||||||
return failure();
|
|
||||||
auto inputFragmentType = spatial::getGraphBatchFragmentType(inputType, producer.getLaneCount());
|
|
||||||
auto outputFragmentType = spatial::getGraphBatchFragmentType(resultType, producer.getLaneCount());
|
|
||||||
if (failed(inputFragmentType) || failed(outputFragmentType) || inputFragmentType->getRank() != biasType.getRank()
|
|
||||||
|| inputFragmentType->getDimSize(0) != 1 || inputFragmentType->getShape().drop_front() != biasType.getShape().drop_front()
|
|
||||||
|| inputFragmentType->getRank() != outputFragmentType->getRank() + 1)
|
|
||||||
return failure();
|
|
||||||
for (auto [inputDim, outputDim] : llvm::zip(inputFragmentType->getShape().drop_front(), outputFragmentType->getShape()))
|
|
||||||
if (outputDim > inputDim)
|
|
||||||
return failure();
|
|
||||||
|
|
||||||
auto batch = createSpatComputeBatch(rewriter, loc, TypeRange {resultType}, producer.getLaneCount(), {}, ValueRange {input, bias},
|
|
||||||
[&](detail::SpatComputeBatchBodyArgs args) -> LogicalResult {
|
|
||||||
FailureOr<Value> fragment = extractGraphBatchPhysicalFragment(rewriter, loc, args.inputs[0], args.lane, *inputFragmentType);
|
|
||||||
if (failed(fragment))
|
|
||||||
return failure();
|
|
||||||
MixedSliceGeometry biasSlice;
|
|
||||||
for (int64_t dim : inputFragmentType->getShape()) {
|
|
||||||
biasSlice.offsets.push_back(biasSlice.offsets.empty() ? OpFoldResult(args.lane) : rewriter.getIndexAttr(0));
|
|
||||||
biasSlice.sizes.push_back(rewriter.getIndexAttr(dim));
|
|
||||||
biasSlice.strides.push_back(rewriter.getIndexAttr(1));
|
|
||||||
}
|
|
||||||
Value biasFragment = extractMixedSliceOrIdentity(rewriter, loc, args.inputs[1], *inputFragmentType, biasSlice);
|
|
||||||
if (!biasFragment)
|
|
||||||
return failure();
|
|
||||||
Value added = spatial::SpatVAddOp::create(rewriter, loc, *inputFragmentType, *fragment, biasFragment);
|
|
||||||
MixedSliceGeometry outputSlice;
|
|
||||||
outputSlice.offsets.assign(inputFragmentType->getRank(), rewriter.getIndexAttr(0));
|
|
||||||
outputSlice.sizes.push_back(rewriter.getIndexAttr(1));
|
|
||||||
outputSlice.strides.assign(inputFragmentType->getRank(), rewriter.getIndexAttr(1));
|
|
||||||
for (int64_t dim : outputFragmentType->getShape())
|
|
||||||
outputSlice.sizes.push_back(rewriter.getIndexAttr(dim));
|
|
||||||
Value output = extractMixedSliceOrIdentity(rewriter, loc, added, *outputFragmentType, outputSlice);
|
|
||||||
if (!output)
|
|
||||||
return failure();
|
|
||||||
publishGraphBatchPhysicalFragment(rewriter, loc, output, args.outputs.front(), args.lane);
|
|
||||||
return success();
|
|
||||||
});
|
|
||||||
if (failed(batch))
|
|
||||||
return failure();
|
|
||||||
return batch->getResult(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LowerDenseReluPlan final : OpRewritePattern<spatial::SpatReluPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatReluPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
auto selected = spatial::getSelectedPhysicalLayout(planOp.getOperation());
|
|
||||||
if (!selected || *selected != spatial::PhysicalLayout::DenseNCHW)
|
|
||||||
return failure();
|
|
||||||
|
|
||||||
auto computeOp = createSpatCompute<1>(
|
|
||||||
rewriter, planOp.getLoc(), planOp.getOutput().getType(), {}, planOp.getInput(), [&](Value x) {
|
|
||||||
auto relu = spatial::SpatReluOp::create(rewriter, planOp.getLoc(), planOp.getOutput().getType(), x);
|
|
||||||
spatial::SpatYieldOp::create(rewriter, planOp.getLoc(), relu.getResult());
|
|
||||||
});
|
|
||||||
rewriter.replaceOp(planOp, computeOp.getResults());
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerDenseSiluPlan final : OpRewritePattern<spatial::SpatSiluPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatSiluPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
auto selected = spatial::getSelectedPhysicalLayout(planOp.getOperation());
|
|
||||||
if (!selected || *selected != spatial::PhysicalLayout::DenseNCHW)
|
|
||||||
return failure();
|
|
||||||
|
|
||||||
auto computeOp = createSpatCompute<1>(
|
|
||||||
rewriter, planOp.getLoc(), planOp.getOutput().getType(), {}, planOp.getInput(), [&](Value x) {
|
|
||||||
Value sigmoid = spatial::SpatSigmoidOp::create(
|
|
||||||
rewriter, planOp.getLoc(), planOp.getOutput().getType(), x).getResult();
|
|
||||||
Value silu = spatial::SpatVMulOp::create(
|
|
||||||
rewriter, planOp.getLoc(), planOp.getOutput().getType(), x, sigmoid).getResult();
|
|
||||||
spatial::SpatYieldOp::create(rewriter, planOp.getLoc(), silu);
|
|
||||||
});
|
|
||||||
rewriter.replaceOp(planOp, computeOp.getResults());
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerDenseResizePlan final : OpRewritePattern<spatial::SpatResizeNearestPlanOp> {
|
|
||||||
explicit LowerDenseResizePlan(MLIRContext* ctx, const spatial::SpatialTargetInfo& target)
|
|
||||||
: OpRewritePattern<spatial::SpatResizeNearestPlanOp>(ctx), target(target) {}
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatResizeNearestPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isDenseSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<Value> lowered = lowerSelectedResizeNearestPlan(planOp, std::nullopt, target, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected dense nearest Resize plan");
|
|
||||||
rewriter.replaceOp(planOp, *lowered);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
const spatial::SpatialTargetInfo& target;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerDenseBiasAddPlan final : OpRewritePattern<spatial::SpatBiasAddPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatBiasAddPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isDenseSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
auto resultType = dyn_cast<RankedTensorType>(planOp.getOutput().getType());
|
|
||||||
if (!resultType)
|
|
||||||
return planOp.emitOpError("requires ranked output type");
|
|
||||||
|
|
||||||
FailureOr<Value> denseBias = materializeDenseBiasAddTensor(
|
|
||||||
planOp.getBias(), resultType, rewriter, planOp.getLoc());
|
|
||||||
if (failed(denseBias))
|
|
||||||
return planOp.emitOpError("failed to materialize dense Conv-style bias");
|
|
||||||
if (planOp.getInput().getDefiningOp<spatial::SpatGraphComputeBatch>()) {
|
|
||||||
FailureOr<Value> lowered = lowerDenseBatchBiasAdd(
|
|
||||||
planOp.getInput(), *denseBias, resultType, rewriter, planOp.getLoc());
|
|
||||||
if (succeeded(lowered)) {
|
|
||||||
rewriter.replaceOp(planOp, *lowered);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto computeOp = createSpatCompute<2>(
|
|
||||||
rewriter,
|
|
||||||
planOp.getLoc(),
|
|
||||||
planOp.getOutput().getType(),
|
|
||||||
{},
|
|
||||||
ValueRange {planOp.getInput(), *denseBias},
|
|
||||||
[&](Value x, Value y) {
|
|
||||||
auto added = spatial::SpatVAddOp::create(
|
|
||||||
rewriter, planOp.getLoc(), planOp.getOutput().getType(), x, y);
|
|
||||||
spatial::SpatYieldOp::create(rewriter, planOp.getLoc(), added.getResult());
|
|
||||||
});
|
|
||||||
rewriter.replaceOp(planOp, computeOp.getResults());
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerDenseAddPlan final : OpRewritePattern<spatial::SpatAddPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatAddPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isDenseSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
auto compute = createSpatCompute<2>(
|
|
||||||
rewriter,
|
|
||||||
planOp.getLoc(),
|
|
||||||
planOp.getOutput().getType(),
|
|
||||||
{},
|
|
||||||
ValueRange {planOp.getLhs(), planOp.getRhs()},
|
|
||||||
[&](Value lhsValue, Value rhsValue) {
|
|
||||||
Value added = spatial::SpatVAddOp::create(
|
|
||||||
rewriter, planOp.getLoc(), planOp.getOutput().getType(), lhsValue, rhsValue);
|
|
||||||
spatial::SpatYieldOp::create(rewriter, planOp.getLoc(), added);
|
|
||||||
});
|
|
||||||
rewriter.replaceOp(planOp, compute.getResults());
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerDenseConcatPlan final : OpRewritePattern<spatial::SpatConcatPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatConcatPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isDenseSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
auto compute = createSpatCompute(
|
|
||||||
rewriter,
|
|
||||||
planOp.getLoc(),
|
|
||||||
TypeRange {planOp.getOutput().getType()},
|
|
||||||
{},
|
|
||||||
planOp.getInputs(),
|
|
||||||
[&](ValueRange values) {
|
|
||||||
Value concatenated = spatial::SpatConcatOp::create(
|
|
||||||
rewriter,
|
|
||||||
planOp.getLoc(),
|
|
||||||
planOp.getOutput().getType(),
|
|
||||||
rewriter.getI64IntegerAttr(planOp.getAxis()),
|
|
||||||
values);
|
|
||||||
spatial::SpatYieldOp::create(rewriter, planOp.getLoc(), concatenated);
|
|
||||||
});
|
|
||||||
rewriter.replaceOp(planOp, compute.getResults());
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static LogicalResult lowerAddPlan(spatial::SpatAddPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) {
|
|
||||||
FailureOr<RowStripPhysicalValue> lhs = getRowStripValue(planOp.getLhs());
|
|
||||||
FailureOr<RowStripPhysicalValue> rhs = getRowStripValue(planOp.getRhs());
|
|
||||||
if (isRowStripSelected(planOp.getOperation()) && failed(lhs)) {
|
|
||||||
if (getKnownPhysicalLayout(planOp.getLhs()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
return planOp.emitOpError("selected row-strip Add plan requires row-strip inputs");
|
|
||||||
}
|
|
||||||
if (isRowStripSelected(planOp.getOperation()) && failed(rhs)) {
|
|
||||||
if (getKnownPhysicalLayout(planOp.getRhs()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
return planOp.emitOpError("selected row-strip Add plan requires row-strip inputs");
|
|
||||||
}
|
|
||||||
if (isRowStripSelected(planOp.getOperation())) {
|
|
||||||
rewriter.setInsertionPoint(planOp);
|
|
||||||
FailureOr<Value> lowered = lowerRowStripAdd(*lhs, *rhs, planOp, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Spatial add plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
return planOp.emitOpError("dense Add plan was not lowered by the selected-plan patterns");
|
|
||||||
}
|
|
||||||
|
|
||||||
static LogicalResult lowerConcatPlan(spatial::SpatConcatPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) {
|
|
||||||
SmallVector<RowStripPhysicalValue> inputs;
|
|
||||||
for (Value input : planOp.getInputs()) {
|
|
||||||
FailureOr<RowStripPhysicalValue> physical = getRowStripValue(input);
|
|
||||||
if (failed(physical)) {
|
|
||||||
inputs.clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
inputs.push_back(*physical);
|
|
||||||
}
|
|
||||||
if (isRowStripSelected(planOp.getOperation()) && inputs.size() != planOp.getInputs().size()) {
|
|
||||||
if (llvm::any_of(planOp.getInputs(), [](Value input) {
|
|
||||||
return getKnownPhysicalLayout(input) == spatial::PhysicalLayout::NHWCRowStrip;
|
|
||||||
}))
|
|
||||||
return failure();
|
|
||||||
return planOp.emitOpError("selected row-strip Concat plan requires row-strip inputs");
|
|
||||||
}
|
|
||||||
if (isRowStripSelected(planOp.getOperation())) {
|
|
||||||
rewriter.setInsertionPoint(planOp);
|
|
||||||
FailureOr<Value> lowered = lowerRowStripConcat(inputs, planOp, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Spatial concat plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
return planOp.emitOpError("dense Concat plan was not lowered by the selected-plan patterns");
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LowerSelectedConvPlan final : OpRewritePattern<spatial::SpatConv2DPlanOp> {
|
|
||||||
explicit LowerSelectedConvPlan(MLIRContext* ctx, const spatial::SpatialTargetInfo& target)
|
|
||||||
: OpRewritePattern<spatial::SpatConv2DPlanOp>(ctx), target(target) {}
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatConv2DPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (isDenseSelected(planOp.getOperation())) {
|
|
||||||
FailureOr<Value> lowered = lowerSelectedConv2DPlan(
|
|
||||||
planOp, std::nullopt, /*emitRowStripLayout=*/false, target, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected dense Spatial Conv plan");
|
|
||||||
rewriter.replaceOp(planOp, *lowered);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
|
|
||||||
FailureOr<RowStripPhysicalValue> rowStripInput = getRowStripValue(planOp.getInput());
|
|
||||||
if (failed(rowStripInput)
|
|
||||||
&& getKnownPhysicalLayout(planOp.getInput()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
std::optional<Value> physicalInput;
|
|
||||||
if (succeeded(rowStripInput))
|
|
||||||
physicalInput = rowStripInput->storage;
|
|
||||||
FailureOr<Value> lowered = lowerSelectedConv2DPlan(
|
|
||||||
planOp, physicalInput, /*emitRowStripLayout=*/true, target, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Spatial Conv plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
const spatial::SpatialTargetInfo& target;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripReluPlan final : OpRewritePattern<spatial::SpatReluPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatReluPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> input = getRowStripValue(planOp.getInput());
|
|
||||||
if (failed(input)) {
|
|
||||||
if (getKnownPhysicalLayout(planOp.getInput()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
return planOp.emitOpError("selected row-strip ReLU plan requires a row-strip input");
|
|
||||||
}
|
|
||||||
FailureOr<Value> lowered = lowerRowStripRelu(*input, planOp, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Spatial ReLU plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripSiluPlan final : OpRewritePattern<spatial::SpatSiluPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatSiluPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> input = getRowStripValue(planOp.getInput());
|
|
||||||
if (failed(input)) {
|
|
||||||
if (getKnownPhysicalLayout(planOp.getInput()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
return planOp.emitOpError("selected row-strip SiLU plan requires a row-strip input");
|
|
||||||
}
|
|
||||||
FailureOr<Value> lowered = lowerRowStripSilu(*input, planOp, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Spatial SiLU plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripResizePlan final : OpRewritePattern<spatial::SpatResizeNearestPlanOp> {
|
|
||||||
explicit LowerRowStripResizePlan(MLIRContext* ctx, const spatial::SpatialTargetInfo& target)
|
|
||||||
: OpRewritePattern<spatial::SpatResizeNearestPlanOp>(ctx), target(target) {}
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatResizeNearestPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> input = getRowStripValue(planOp.getInput());
|
|
||||||
if (failed(input)) {
|
|
||||||
if (getKnownPhysicalLayout(planOp.getInput()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
return planOp.emitOpError("selected row-strip Resize plan requires a row-strip input");
|
|
||||||
}
|
|
||||||
FailureOr<Value> lowered = lowerSelectedResizeNearestPlan(planOp, input->storage, target, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Resize plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
const spatial::SpatialTargetInfo& target;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerDenseMaxPoolPlan final : OpRewritePattern<spatial::SpatMaxPool2DPlanOp> {
|
|
||||||
explicit LowerDenseMaxPoolPlan(MLIRContext* ctx, const spatial::SpatialTargetInfo& target)
|
|
||||||
: OpRewritePattern<spatial::SpatMaxPool2DPlanOp>(ctx), target(target) {}
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatMaxPool2DPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isDenseSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<Value> lowered = lowerDenseMaxPool2DPlan(planOp, target, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected dense Spatial MaxPool plan");
|
|
||||||
rewriter.replaceOp(planOp, *lowered);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
const spatial::SpatialTargetInfo& target;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripMaxPoolPlan final : OpRewritePattern<spatial::SpatMaxPool2DPlanOp> {
|
|
||||||
explicit LowerRowStripMaxPoolPlan(MLIRContext* ctx, const spatial::SpatialTargetInfo& target)
|
|
||||||
: OpRewritePattern<spatial::SpatMaxPool2DPlanOp>(ctx), target(target) {}
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatMaxPool2DPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> input = getRowStripValue(planOp.getInput());
|
|
||||||
if (failed(input)
|
|
||||||
&& getKnownPhysicalLayout(planOp.getInput()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
std::optional<Value> physicalInput;
|
|
||||||
if (succeeded(input))
|
|
||||||
physicalInput = input->storage;
|
|
||||||
FailureOr<Value> lowered = lowerSelectedMaxPool2DPlan(planOp, physicalInput, target, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Spatial MaxPool plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
const spatial::SpatialTargetInfo& target;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripGlobalAveragePoolPlan
|
|
||||||
final : OpRewritePattern<spatial::SpatGlobalAveragePoolPlanOp> {
|
|
||||||
explicit LowerRowStripGlobalAveragePoolPlan(MLIRContext* ctx, const spatial::SpatialTargetInfo& target)
|
|
||||||
: OpRewritePattern<spatial::SpatGlobalAveragePoolPlanOp>(ctx), target(target) {}
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatGlobalAveragePoolPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> input = getRowStripValue(planOp.getInput());
|
|
||||||
if (failed(input)
|
|
||||||
&& getKnownPhysicalLayout(planOp.getInput()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
std::optional<Value> physicalInput;
|
|
||||||
if (succeeded(input))
|
|
||||||
physicalInput = input->storage;
|
|
||||||
FailureOr<Value> lowered = lowerSelectedGlobalAveragePoolPlan(planOp, physicalInput, target, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Spatial global AveragePool plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
const spatial::SpatialTargetInfo& target;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerDenseGlobalAveragePoolPlan
|
|
||||||
final : OpRewritePattern<spatial::SpatGlobalAveragePoolPlanOp> {
|
|
||||||
explicit LowerDenseGlobalAveragePoolPlan(MLIRContext* ctx,
|
|
||||||
const spatial::SpatialTargetInfo& target)
|
|
||||||
: OpRewritePattern<spatial::SpatGlobalAveragePoolPlanOp>(ctx), target(target) {}
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatGlobalAveragePoolPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isDenseSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<Value> lowered = lowerDenseGlobalAveragePoolPlan(planOp, target, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected dense Spatial global AveragePool plan");
|
|
||||||
rewriter.replaceOp(planOp, *lowered);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
const spatial::SpatialTargetInfo& target;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripBiasAddPlan final : OpRewritePattern<spatial::SpatBiasAddPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatBiasAddPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> input = getRowStripValue(planOp.getInput());
|
|
||||||
if (failed(input)) {
|
|
||||||
if (getKnownPhysicalLayout(planOp.getInput()) == spatial::PhysicalLayout::NHWCRowStrip)
|
|
||||||
return failure();
|
|
||||||
return planOp.emitOpError("selected row-strip bias_add plan requires a row-strip input");
|
|
||||||
}
|
|
||||||
FailureOr<Value> lowered = lowerRowStripBiasAdd(*input, planOp, rewriter);
|
|
||||||
if (failed(lowered))
|
|
||||||
return planOp.emitOpError("failed to lower selected row-strip Spatial bias_add plan");
|
|
||||||
if (failed(publishRowStripValue(planOp, *lowered, rewriter)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripAddPlan final : OpRewritePattern<spatial::SpatAddPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatAddPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
return lowerAddPlan(planOp, rewriter);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripConcatPlan final : OpRewritePattern<spatial::SpatConcatPlanOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatConcatPlanOp planOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (!isRowStripSelected(planOp.getOperation()))
|
|
||||||
return failure();
|
|
||||||
return lowerConcatPlan(planOp, rewriter);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerMaterializeLayout final
|
|
||||||
: OpRewritePattern<spatial::SpatMaterializeLayoutOp> {
|
|
||||||
using OpRewritePattern::OpRewritePattern;
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatMaterializeLayoutOp materializeOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
auto source = materializeOp.getSourcePhysicalLayout();
|
|
||||||
auto target = materializeOp.getTargetPhysicalLayout();
|
|
||||||
if (source == spatial::PhysicalLayout::DenseNCHW
|
|
||||||
&& target == spatial::PhysicalLayout::DenseNCHW) {
|
|
||||||
rewriter.replaceOp(materializeOp, materializeOp.getInput());
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
if (source == spatial::PhysicalLayout::DenseNCHW
|
|
||||||
&& target == spatial::PhysicalLayout::NHWCRowStrip) {
|
|
||||||
auto logicalType = dyn_cast<RankedTensorType>(materializeOp.getInput().getType());
|
|
||||||
if (!logicalType)
|
|
||||||
return materializeOp.emitOpError("requires a ranked dense input"), failure();
|
|
||||||
FailureOr<Value> rowStrip = materializeDenseToRowStrip(
|
|
||||||
materializeOp.getInput(), logicalType, materializeOp.getLoc(), rewriter);
|
|
||||||
if (failed(rowStrip))
|
|
||||||
return materializeOp.emitOpError(
|
|
||||||
"failed to materialize dense NCHW storage to row-strip layout"), failure();
|
|
||||||
rewriter.replaceOp(materializeOp, *rowStrip);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
if (source != spatial::PhysicalLayout::NHWCRowStrip
|
|
||||||
|| target != spatial::PhysicalLayout::DenseNCHW)
|
|
||||||
return materializeOp.emitOpError(
|
|
||||||
"unsupported Spatial layout materialization direction"), failure();
|
|
||||||
auto inputType = dyn_cast<RankedTensorType>(materializeOp.getInput().getType());
|
|
||||||
if (!inputType)
|
|
||||||
return materializeOp.emitOpError("requires a ranked row-strip input"), failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> rowStripValue =
|
|
||||||
getRowStripValue(materializeOp.getInput());
|
|
||||||
if (failed(rowStripValue))
|
|
||||||
return materializeOp.emitOpError(
|
|
||||||
"requires an explicitly defining row-strip physical value"), failure();
|
|
||||||
FailureOr<Value> dense = materializeRowStripToDense(
|
|
||||||
*rowStripValue, materializeOp.getLoc(), rewriter);
|
|
||||||
if (failed(dense))
|
|
||||||
return materializeOp.emitOpError(
|
|
||||||
"failed to materialize row-strip storage to dense NCHW"), failure();
|
|
||||||
rewriter.replaceOp(materializeOp, *dense);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerRowStripFlatten final
|
|
||||||
: OpRewritePattern<spatial::SpatGraphCompute> {
|
|
||||||
explicit LowerRowStripFlatten(MLIRContext* context,
|
|
||||||
const spatial::SpatialTargetInfo& target)
|
|
||||||
: OpRewritePattern<spatial::SpatGraphCompute>(context), target(target) {}
|
|
||||||
|
|
||||||
LogicalResult matchAndRewrite(spatial::SpatGraphCompute flattenOp,
|
|
||||||
PatternRewriter& rewriter) const override {
|
|
||||||
if (flattenOp.getInputs().size() != 1)
|
|
||||||
return failure();
|
|
||||||
FailureOr<RowStripPhysicalValue> input =
|
|
||||||
getRowStripValue(flattenOp.getInputs().front());
|
|
||||||
if (failed(input) || failed(canLowerFlattenFromRowStrip(flattenOp, target)))
|
|
||||||
return failure();
|
|
||||||
if (failed(lowerFlattenFromRowStrip(*input, flattenOp, target, rewriter)))
|
|
||||||
return flattenOp.emitOpError(
|
|
||||||
"failed to preserve row-strip layout through Flatten"), failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
const spatial::SpatialTargetInfo& target;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LowerSpatialPlansPass final : PassWrapper<LowerSpatialPlansPass, OperationPass<ModuleOp>> {
|
|
||||||
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(LowerSpatialPlansPass)
|
|
||||||
|
|
||||||
StringRef getArgument() const override { return "lower-spatial-plans"; }
|
|
||||||
StringRef getDescription() const override { return "Lower selected Spatial planning ops to low-level Spatial IR."; }
|
|
||||||
|
|
||||||
LowerSpatialPlansPass() = default;
|
|
||||||
explicit LowerSpatialPlansPass(const spatial::SpatialTargetInfo& target)
|
|
||||||
: target(target), hasTarget(true) {}
|
|
||||||
|
|
||||||
void runOnOperation() override {
|
|
||||||
ModuleOp moduleOp = getOperation();
|
|
||||||
if (!hasTarget) {
|
|
||||||
moduleOp.emitError("Spatial plan lowering requires an injected SpatialTargetInfo");
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MLIRContext* ctx = moduleOp.getContext();
|
|
||||||
auto entryFunc = getPimEntryFunc(moduleOp);
|
|
||||||
if (failed(entryFunc)) {
|
|
||||||
moduleOp.emitError("failed to locate the PIM entry function during LowerSpatialPlans");
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
func::FuncOp funcOp = *entryFunc;
|
|
||||||
PatternRewriter rewriter(ctx);
|
|
||||||
auto verifyLogicalPhase = [&](StringRef stage) -> bool {
|
|
||||||
if (succeeded(verifyLogicalSpatialGraphInvariants(*entryFunc)))
|
|
||||||
return true;
|
|
||||||
moduleOp.emitError() << "logical Spatial graph verification failed " << stage;
|
|
||||||
signalPassFailure();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!verifyLogicalPhase("at the start of LowerSpatialPlans"))
|
|
||||||
return;
|
|
||||||
if (failed(verifySelectedLayouts(funcOp, target))) {
|
|
||||||
moduleOp.emitError("selected Spatial layout verification failed");
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RewritePatternSet selectedPlanPatterns(ctx);
|
|
||||||
selectedPlanPatterns.add<LowerDenseReluPlan,
|
|
||||||
LowerRowStripReluPlan,
|
|
||||||
LowerDenseSiluPlan,
|
|
||||||
LowerRowStripSiluPlan,
|
|
||||||
LowerDenseBiasAddPlan,
|
|
||||||
LowerRowStripBiasAddPlan,
|
|
||||||
LowerDenseAddPlan,
|
|
||||||
LowerRowStripAddPlan,
|
|
||||||
LowerDenseConcatPlan,
|
|
||||||
LowerRowStripConcatPlan>(ctx);
|
|
||||||
selectedPlanPatterns.add<LowerSelectedConvPlan,
|
|
||||||
LowerDenseResizePlan,
|
|
||||||
LowerRowStripResizePlan,
|
|
||||||
LowerDenseMaxPoolPlan,
|
|
||||||
LowerRowStripMaxPoolPlan,
|
|
||||||
LowerDenseGlobalAveragePoolPlan,
|
|
||||||
LowerRowStripGlobalAveragePoolPlan>(ctx, target);
|
|
||||||
if (failed(applyPatternsGreedily(funcOp, std::move(selectedPlanPatterns)))) {
|
|
||||||
moduleOp.emitError("failed to lower selected Spatial plans");
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RewritePatternSet layoutPatterns(ctx);
|
|
||||||
layoutPatterns.add<LowerMaterializeLayout>(ctx);
|
|
||||||
layoutPatterns.add<LowerRowStripFlatten>(ctx, target);
|
|
||||||
ConversionTarget layoutTarget(*ctx);
|
|
||||||
layoutTarget.addLegalDialect<spatial::SpatialDialect,
|
|
||||||
tensor::TensorDialect,
|
|
||||||
linalg::LinalgDialect,
|
|
||||||
affine::AffineDialect,
|
|
||||||
arith::ArithDialect,
|
|
||||||
scf::SCFDialect,
|
|
||||||
func::FuncDialect>();
|
|
||||||
layoutTarget.addIllegalDialect<ONNXDialect>();
|
|
||||||
layoutTarget.addIllegalOp<spatial::SpatMaterializeLayoutOp>();
|
|
||||||
layoutTarget.addDynamicallyLegalOp<spatial::SpatGraphCompute>(
|
|
||||||
[&](spatial::SpatGraphCompute computeOp) {
|
|
||||||
if (computeOp.getInputs().size() != 1)
|
|
||||||
return true;
|
|
||||||
FailureOr<RowStripPhysicalValue> input =
|
|
||||||
getRowStripValue(computeOp.getInputs().front());
|
|
||||||
return failed(input) || failed(canLowerFlattenFromRowStrip(computeOp, target));
|
|
||||||
});
|
|
||||||
FrozenRewritePatternSet frozenLayoutPatterns(std::move(layoutPatterns));
|
|
||||||
if (failed(applyFullConversion(funcOp, layoutTarget,
|
|
||||||
frozenLayoutPatterns))) {
|
|
||||||
moduleOp.emitError("failed to lower explicit Spatial layout materialization");
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!verifyLogicalPhase("after selected-plan conversion"))
|
|
||||||
return;
|
|
||||||
SmallVector<spatial::SpatBlueprintOp> deadPhysicalViews;
|
|
||||||
funcOp.walk([&](spatial::SpatBlueprintOp blueprint) {
|
|
||||||
if (spatial::isPhysicalView(blueprint.getMode()) && blueprint.use_empty())
|
|
||||||
deadPhysicalViews.push_back(blueprint);
|
|
||||||
});
|
|
||||||
for (spatial::SpatBlueprintOp blueprint : deadPhysicalViews)
|
|
||||||
rewriter.eraseOp(blueprint);
|
|
||||||
bool hasIllegalOps = false;
|
|
||||||
moduleOp.walk([&](Operation* op) {
|
|
||||||
if (isa<ONNXEntryPointOp>(op))
|
|
||||||
return;
|
|
||||||
if (auto blueprint = dyn_cast<spatial::SpatBlueprintOp>(op)) {
|
|
||||||
if (spatial::isFragmentAssembly(blueprint.getMode()))
|
|
||||||
return;
|
|
||||||
op->emitOpError("planning blueprint must not remain after LowerSpatialPlans");
|
|
||||||
hasIllegalOps = true;
|
|
||||||
}
|
|
||||||
else if (isa<spatial::SpatConv2DPlanOp,
|
|
||||||
spatial::SpatBiasAddPlanOp,
|
|
||||||
spatial::SpatAddPlanOp,
|
|
||||||
spatial::SpatReluPlanOp,
|
|
||||||
spatial::SpatSiluPlanOp,
|
|
||||||
spatial::SpatResizeNearestPlanOp,
|
|
||||||
spatial::SpatMaxPool2DPlanOp,
|
|
||||||
spatial::SpatGlobalAveragePoolPlanOp,
|
|
||||||
spatial::SpatMaterializeLayoutOp>(op)
|
|
||||||
|| op->getDialect()->getNamespace() == "onnx") {
|
|
||||||
op->emitOpError("operation must not remain after LowerSpatialPlans");
|
|
||||||
hasIllegalOps = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
PassManager canonicalizationPM(ctx);
|
|
||||||
canonicalizationPM.addPass(createCanonicalizerPass());
|
|
||||||
if (failed(canonicalizationPM.run(moduleOp)))
|
|
||||||
moduleOp.emitWarning("failed to run LowerSpatialPlansPass canonicalization; continuing");
|
|
||||||
|
|
||||||
if (hasIllegalOps) {
|
|
||||||
signalPassFailure();
|
|
||||||
} else {
|
|
||||||
dumpModule(moduleOp, "spatial1_graph");
|
|
||||||
spatial::SpatialDataflowExportStage exportMode = spatial::getSpatialDataflowExportStage();
|
|
||||||
if (spatial::shouldExportSpatialDataflowStage(exportMode, spatial::SpatialDataflowExportStage::Spatial1)
|
|
||||||
&& failed(spatial::exportSpatialDataflowCsvGraph(funcOp, "spatial1_graph"))) {
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!verifyLogicalPhase("at the end of LowerSpatialPlans"))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
spatial::SpatialTargetInfo target;
|
|
||||||
bool hasTarget = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
std::unique_ptr<Pass> createLowerSpatialPlansPass() { return std::make_unique<LowerSpatialPlansPass>(); }
|
|
||||||
|
|
||||||
std::unique_ptr<Pass> createLowerSpatialPlansPass(const spatial::SpatialTargetInfo& target) {
|
|
||||||
return std::make_unique<LowerSpatialPlansPass>(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace onnx_mlir
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "mlir/IR/PatternMatch.h"
|
|
||||||
#include "mlir/Support/LogicalResult.h"
|
|
||||||
|
|
||||||
#include "src/Accelerators/PIM/Dialect/Spatial/SpatialOps.hpp"
|
|
||||||
|
|
||||||
namespace onnx_mlir {
|
|
||||||
|
|
||||||
struct RowStripPhysicalValue;
|
|
||||||
|
|
||||||
mlir::FailureOr<mlir::Value>
|
|
||||||
lowerSelectedConv2DPlan(spatial::SpatConv2DPlanOp planOp,
|
|
||||||
std::optional<mlir::Value> rowStripInput,
|
|
||||||
bool emitRowStripLayout,
|
|
||||||
const spatial::SpatialTargetInfo& target,
|
|
||||||
mlir::PatternRewriter& rewriter);
|
|
||||||
|
|
||||||
mlir::LogicalResult canLowerConvPlanToRowStrip(spatial::SpatConv2DPlanOp planOp,
|
|
||||||
const spatial::SpatialTargetInfo& target);
|
|
||||||
mlir::LogicalResult canConsumeAndProduceRowStrip(spatial::SpatConv2DPlanOp planOp,
|
|
||||||
const spatial::SpatialTargetInfo& target);
|
|
||||||
|
|
||||||
mlir::LogicalResult canLowerResizeNearestPlanToRowStrip(
|
|
||||||
spatial::SpatResizeNearestPlanOp planOp, const spatial::SpatialTargetInfo& target);
|
|
||||||
|
|
||||||
mlir::FailureOr<mlir::Value> lowerSelectedResizeNearestPlan(
|
|
||||||
spatial::SpatResizeNearestPlanOp planOp,
|
|
||||||
std::optional<mlir::Value> rowStripInput,
|
|
||||||
const spatial::SpatialTargetInfo& target,
|
|
||||||
mlir::PatternRewriter& rewriter);
|
|
||||||
|
|
||||||
mlir::LogicalResult canLowerMaxPoolPlanToRowStrip(spatial::SpatMaxPool2DPlanOp planOp,
|
|
||||||
const spatial::SpatialTargetInfo& target);
|
|
||||||
|
|
||||||
mlir::FailureOr<mlir::Value>
|
|
||||||
lowerDenseMaxPool2DPlan(spatial::SpatMaxPool2DPlanOp planOp,
|
|
||||||
const spatial::SpatialTargetInfo& target,
|
|
||||||
mlir::PatternRewriter& rewriter);
|
|
||||||
|
|
||||||
mlir::FailureOr<mlir::Value>
|
|
||||||
lowerSelectedMaxPool2DPlan(spatial::SpatMaxPool2DPlanOp planOp,
|
|
||||||
std::optional<mlir::Value> rowStripInput,
|
|
||||||
const spatial::SpatialTargetInfo& target,
|
|
||||||
mlir::PatternRewriter& rewriter);
|
|
||||||
|
|
||||||
mlir::LogicalResult
|
|
||||||
canLowerGlobalAveragePoolPlanToRowStrip(spatial::SpatGlobalAveragePoolPlanOp planOp,
|
|
||||||
const spatial::SpatialTargetInfo& target);
|
|
||||||
|
|
||||||
mlir::FailureOr<mlir::Value>
|
|
||||||
lowerDenseGlobalAveragePoolPlan(spatial::SpatGlobalAveragePoolPlanOp planOp,
|
|
||||||
const spatial::SpatialTargetInfo& target,
|
|
||||||
mlir::PatternRewriter& rewriter);
|
|
||||||
|
|
||||||
mlir::FailureOr<mlir::Value>
|
|
||||||
lowerSelectedGlobalAveragePoolPlan(spatial::SpatGlobalAveragePoolPlanOp planOp,
|
|
||||||
std::optional<mlir::Value> rowStripInput,
|
|
||||||
const spatial::SpatialTargetInfo& target,
|
|
||||||
mlir::PatternRewriter& rewriter);
|
|
||||||
|
|
||||||
} // namespace onnx_mlir
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/Common/BiasAddUtils.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/PlanLowering.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Dialect/Spatial/SpatialOps.hpp"
|
|
||||||
|
|
||||||
using namespace mlir;
|
|
||||||
|
|
||||||
namespace onnx_mlir::spatial {
|
|
||||||
|
|
||||||
static LayoutAlternative denseAlternative(Operation *op) {
|
|
||||||
LayoutAlternative alternative;
|
|
||||||
alternative.operandLayouts.assign(op->getNumOperands(), PhysicalLayout::DenseNCHW);
|
|
||||||
alternative.resultLayout = PhysicalLayout::DenseNCHW;
|
|
||||||
return alternative;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LayoutAlternative rowStripAlternative(Operation *op,
|
|
||||||
ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
LayoutAlternative alternative;
|
|
||||||
alternative.operandLayouts.assign(operandLayouts.begin(), operandLayouts.end());
|
|
||||||
alternative.resultLayout = PhysicalLayout::NHWCRowStrip;
|
|
||||||
alternative.intrinsicCost = -2;
|
|
||||||
return alternative;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool hasRowStripInput(ArrayRef<PhysicalLayout> operandLayouts, unsigned index) {
|
|
||||||
return index < operandLayouts.size()
|
|
||||||
&& operandLayouts[index] == PhysicalLayout::NHWCRowStrip;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatConv2DPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo& target, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
if (hasRowStripInput(operandLayouts, 0)) {
|
|
||||||
if (succeeded(canConsumeAndProduceRowStrip(*this, target)))
|
|
||||||
alternatives.push_back(rowStripAlternative(getOperation(), operandLayouts));
|
|
||||||
}
|
|
||||||
else if (succeeded(canLowerConvPlanToRowStrip(*this, target))) {
|
|
||||||
LayoutAlternative alternative = denseAlternative(getOperation());
|
|
||||||
alternative.resultLayout = PhysicalLayout::NHWCRowStrip;
|
|
||||||
alternative.intrinsicCost = -2;
|
|
||||||
alternatives.push_back(std::move(alternative));
|
|
||||||
}
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatReluPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo&, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
if (hasRowStripInput(operandLayouts, 0))
|
|
||||||
alternatives.push_back(rowStripAlternative(getOperation(), operandLayouts));
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatSiluPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo&, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
if (hasRowStripInput(operandLayouts, 0)) {
|
|
||||||
LayoutAlternative alternative = rowStripAlternative(getOperation(), operandLayouts);
|
|
||||||
alternative.intrinsicCost = -3;
|
|
||||||
alternatives.push_back(std::move(alternative));
|
|
||||||
}
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatResizeNearestPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo& target, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
if (hasRowStripInput(operandLayouts, 0)
|
|
||||||
&& succeeded(canLowerResizeNearestPlanToRowStrip(*this, target)))
|
|
||||||
alternatives.push_back(rowStripAlternative(getOperation(), operandLayouts));
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatMaxPool2DPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo& target, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
if (succeeded(canLowerMaxPoolPlanToRowStrip(*this, target))) {
|
|
||||||
LayoutAlternative alternative = denseAlternative(getOperation());
|
|
||||||
if (hasRowStripInput(operandLayouts, 0))
|
|
||||||
alternative = rowStripAlternative(getOperation(), operandLayouts);
|
|
||||||
alternative.resultLayout = PhysicalLayout::NHWCRowStrip;
|
|
||||||
alternative.intrinsicCost = -2;
|
|
||||||
alternatives.push_back(std::move(alternative));
|
|
||||||
}
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatGlobalAveragePoolPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo& target, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
if (succeeded(canLowerGlobalAveragePoolPlanToRowStrip(*this, target))) {
|
|
||||||
LayoutAlternative alternative = denseAlternative(getOperation());
|
|
||||||
if (hasRowStripInput(operandLayouts, 0))
|
|
||||||
alternative = rowStripAlternative(getOperation(), operandLayouts);
|
|
||||||
alternative.resultLayout = PhysicalLayout::NHWCRowStrip;
|
|
||||||
alternative.intrinsicCost = -2;
|
|
||||||
alternatives.push_back(std::move(alternative));
|
|
||||||
}
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatBiasAddPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo&, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
auto resultType = dyn_cast<RankedTensorType>(getOutput().getType());
|
|
||||||
if (resultType && hasRowStripInput(operandLayouts, 0)
|
|
||||||
&& isSupportedBiasAddValue(getBias(), resultType))
|
|
||||||
alternatives.push_back(rowStripAlternative(getOperation(),
|
|
||||||
{PhysicalLayout::NHWCRowStrip,
|
|
||||||
PhysicalLayout::DenseNCHW}));
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatAddPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo&, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
if (operandLayouts.size() >= 2 && hasRowStripInput(operandLayouts, 0)
|
|
||||||
&& hasRowStripInput(operandLayouts, 1))
|
|
||||||
alternatives.push_back(rowStripAlternative(getOperation(), operandLayouts));
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<LayoutAlternative> SpatConcatPlanOp::getLayoutAlternatives(
|
|
||||||
const SpatialTargetInfo&, ArrayRef<PhysicalLayout> operandLayouts) {
|
|
||||||
SmallVector<LayoutAlternative> alternatives {denseAlternative(getOperation())};
|
|
||||||
if (!operandLayouts.empty() && llvm::all_of(operandLayouts, [](PhysicalLayout layout) {
|
|
||||||
return layout == PhysicalLayout::NHWCRowStrip;
|
|
||||||
}))
|
|
||||||
alternatives.push_back(rowStripAlternative(getOperation(), operandLayouts));
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace onnx_mlir::spatial
|
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
|
||||||
#include "mlir/IR/PatternMatch.h"
|
|
||||||
#include "mlir/Pass/Pass.h"
|
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
|
||||||
|
|
||||||
#include "Conversion/ONNXToSpatial/ONNXToSpatialVerifier.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Common/PimCommon.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Conversion/ONNXToSpatial/Common/RowStripLayoutUtils.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Dialect/Spatial/SpatialOps.hpp"
|
|
||||||
#include "src/Accelerators/PIM/Pass/PIMPasses.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace mlir;
|
|
||||||
|
|
||||||
namespace onnx_mlir {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using LayoutMap = llvm::DenseMap<Value, spatial::PhysicalLayout>;
|
|
||||||
|
|
||||||
static spatial::PhysicalLayout getSelectedLayout(const LayoutMap& layouts, Value value) {
|
|
||||||
if (auto it = layouts.find(value); it != layouts.end())
|
|
||||||
return it->second;
|
|
||||||
if (auto materialize = value.getDefiningOp<spatial::SpatMaterializeLayoutOp>())
|
|
||||||
return materialize.getTargetPhysicalLayout();
|
|
||||||
if (auto blueprint = value.getDefiningOp<spatial::SpatBlueprintOp>())
|
|
||||||
return blueprint.getPhysicalLayout();
|
|
||||||
return spatial::PhysicalLayout::DenseNCHW;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SmallVector<spatial::PhysicalLayout> getOperandLayouts(
|
|
||||||
Operation* op, const LayoutMap& layouts) {
|
|
||||||
SmallVector<spatial::PhysicalLayout> operandLayouts;
|
|
||||||
operandLayouts.reserve(op->getNumOperands());
|
|
||||||
for (Value operand : op->getOperands())
|
|
||||||
operandLayouts.push_back(getSelectedLayout(layouts, operand));
|
|
||||||
return operandLayouts;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FailureOr<SmallVector<spatial::LayoutAlternative>> getAlternatives(
|
|
||||||
Operation* op, const LayoutMap& layouts, const spatial::SpatialTargetInfo& target) {
|
|
||||||
auto capability = dyn_cast<spatial::SpatialLayoutCapabilityInterface>(op);
|
|
||||||
if (!capability)
|
|
||||||
return failure();
|
|
||||||
SmallVector<spatial::LayoutAlternative> alternatives =
|
|
||||||
capability.getLayoutAlternatives(target, getOperandLayouts(op, layouts));
|
|
||||||
if (alternatives.empty())
|
|
||||||
return op->emitOpError("does not advertise a legal Spatial layout alternative"), failure();
|
|
||||||
for (const spatial::LayoutAlternative& alternative : alternatives)
|
|
||||||
if (alternative.operandLayouts.size() != op->getNumOperands())
|
|
||||||
return op->emitOpError("advertises a layout alternative with the wrong operand count"), failure();
|
|
||||||
return alternatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned findCurrentAlternative(
|
|
||||||
Operation* op, ArrayRef<spatial::LayoutAlternative> alternatives,
|
|
||||||
spatial::PhysicalLayout selectedResult) {
|
|
||||||
for (auto [index, alternative] : llvm::enumerate(alternatives))
|
|
||||||
if (alternative.resultLayout == selectedResult)
|
|
||||||
return index;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int64_t alternativeCost(Operation* op,
|
|
||||||
const spatial::LayoutAlternative& alternative,
|
|
||||||
const LayoutMap& layouts,
|
|
||||||
const LayoutMap& selectedResults,
|
|
||||||
const spatial::SpatialTargetInfo& target) {
|
|
||||||
int64_t cost = alternative.intrinsicCost;
|
|
||||||
SmallVector<spatial::PhysicalLayout> operandLayouts = getOperandLayouts(op, layouts);
|
|
||||||
for (auto [actual, required] : llvm::zip(operandLayouts, alternative.operandLayouts))
|
|
||||||
cost += actual != required;
|
|
||||||
|
|
||||||
Value result = op->getResult(0);
|
|
||||||
for (OpOperand& use : result.getUses()) {
|
|
||||||
auto user = dyn_cast<spatial::SpatialLayoutCapabilityInterface>(use.getOwner());
|
|
||||||
if (!user) {
|
|
||||||
if (alternative.resultLayout != spatial::PhysicalLayout::DenseNCHW) {
|
|
||||||
auto flatten = dyn_cast<spatial::SpatGraphCompute>(use.getOwner());
|
|
||||||
if (!flatten || failed(canLowerFlattenFromRowStrip(flatten, target)))
|
|
||||||
++cost;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto userAlternatives = getAlternatives(use.getOwner(), selectedResults, target);
|
|
||||||
if (failed(userAlternatives))
|
|
||||||
continue;
|
|
||||||
spatial::PhysicalLayout userResult =
|
|
||||||
selectedResults.lookup(use.getOwner()->getResult(0));
|
|
||||||
unsigned userIndex = findCurrentAlternative(use.getOwner(), *userAlternatives, userResult);
|
|
||||||
if (use.getOperandNumber() < (*userAlternatives)[userIndex].operandLayouts.size()
|
|
||||||
&& (*userAlternatives)[userIndex].operandLayouts[use.getOperandNumber()]
|
|
||||||
!= alternative.resultLayout)
|
|
||||||
++cost;
|
|
||||||
}
|
|
||||||
return cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LogicalResult materializeMismatchedUses(
|
|
||||||
IRRewriter& rewriter, Value value, const LayoutMap& layouts,
|
|
||||||
const spatial::SpatialTargetInfo& target) {
|
|
||||||
spatial::PhysicalLayout sourceLayout = getSelectedLayout(layouts, value);
|
|
||||||
SmallVector<std::pair<OpOperand*, spatial::PhysicalLayout>> mismatches;
|
|
||||||
for (OpOperand& use : value.getUses()) {
|
|
||||||
Operation* userOp = use.getOwner();
|
|
||||||
spatial::PhysicalLayout required = spatial::PhysicalLayout::DenseNCHW;
|
|
||||||
if (auto capability = dyn_cast<spatial::SpatialLayoutCapabilityInterface>(userOp)) {
|
|
||||||
auto alternatives = getAlternatives(userOp, layouts, target);
|
|
||||||
if (failed(alternatives))
|
|
||||||
return failure();
|
|
||||||
spatial::PhysicalLayout selected =
|
|
||||||
getSelectedLayout(layouts, userOp->getResult(0));
|
|
||||||
unsigned selectedIndex = findCurrentAlternative(userOp, *alternatives, selected);
|
|
||||||
required = (*alternatives)[selectedIndex].operandLayouts[use.getOperandNumber()];
|
|
||||||
}
|
|
||||||
else if (auto flatten = dyn_cast<spatial::SpatGraphCompute>(userOp);
|
|
||||||
flatten && sourceLayout == spatial::PhysicalLayout::NHWCRowStrip
|
|
||||||
&& succeeded(canLowerFlattenFromRowStrip(flatten, target))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (required != sourceLayout)
|
|
||||||
mismatches.push_back({&use, required});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto [use, required] : mismatches) {
|
|
||||||
Operation* userOp = use->getOwner();
|
|
||||||
rewriter.setInsertionPoint(userOp);
|
|
||||||
auto materialized = spatial::SpatMaterializeLayoutOp::create(
|
|
||||||
rewriter, userOp->getLoc(), use->get().getType(), use->get(),
|
|
||||||
spatial::LogicalLayoutAttr::get(
|
|
||||||
rewriter.getContext(), spatial::LogicalLayout::NCHW),
|
|
||||||
spatial::PhysicalLayoutAttr::get(rewriter.getContext(), sourceLayout),
|
|
||||||
spatial::PhysicalLayoutAttr::get(rewriter.getContext(),
|
|
||||||
required));
|
|
||||||
use->set(materialized.getResult());
|
|
||||||
}
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
static LogicalResult verifySelectedLayouts(
|
|
||||||
ArrayRef<Operation*> planOps, const LayoutMap& layouts,
|
|
||||||
const spatial::SpatialTargetInfo& target) {
|
|
||||||
for (Operation* op : planOps) {
|
|
||||||
auto selected = spatial::getSelectedPhysicalLayout(op);
|
|
||||||
if (!selected)
|
|
||||||
return op->emitOpError("requires a selected physical layout"), failure();
|
|
||||||
auto alternatives = getAlternatives(op, layouts, target);
|
|
||||||
if (failed(alternatives))
|
|
||||||
return failure();
|
|
||||||
if (llvm::none_of(*alternatives, [&](const spatial::LayoutAlternative& alternative) {
|
|
||||||
return alternative.resultLayout == *selected;
|
|
||||||
}))
|
|
||||||
return op->emitOpError("selected physical layout is not advertised by its layout contract"), failure();
|
|
||||||
}
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SpatialLayoutPlanningPass final
|
|
||||||
: PassWrapper<SpatialLayoutPlanningPass, OperationPass<ModuleOp>> {
|
|
||||||
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(SpatialLayoutPlanningPass)
|
|
||||||
|
|
||||||
StringRef getArgument() const override { return "spatial-layout-planning"; }
|
|
||||||
StringRef getDescription() const override {
|
|
||||||
return "Select Spatial layout alternatives and insert explicit reconciliation barriers.";
|
|
||||||
}
|
|
||||||
|
|
||||||
SpatialLayoutPlanningPass() = default;
|
|
||||||
explicit SpatialLayoutPlanningPass(const spatial::SpatialTargetInfo& target)
|
|
||||||
: target(target), hasTarget(true) {}
|
|
||||||
|
|
||||||
void runOnOperation() override {
|
|
||||||
ModuleOp moduleOp = getOperation();
|
|
||||||
if (!hasTarget) {
|
|
||||||
moduleOp.emitError("Spatial layout planning requires an injected SpatialTargetInfo");
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto entryFunc = getPimEntryFunc(moduleOp);
|
|
||||||
if (failed(entryFunc)) {
|
|
||||||
moduleOp.emitError("failed to locate the PIM entry function during Spatial layout planning");
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
func::FuncOp funcOp = *entryFunc;
|
|
||||||
SmallVector<Operation*> planOps;
|
|
||||||
for (Operation& op : funcOp.getBody().front())
|
|
||||||
if (isa<spatial::SpatialLayoutCapabilityInterface>(&op))
|
|
||||||
planOps.push_back(&op);
|
|
||||||
|
|
||||||
LayoutMap layouts;
|
|
||||||
for (Operation* op : planOps)
|
|
||||||
layouts[op->getResult(0)] = spatial::PhysicalLayout::DenseNCHW;
|
|
||||||
|
|
||||||
const size_t maxRounds = 2 * planOps.size() + 1;
|
|
||||||
bool converged = false;
|
|
||||||
for (size_t round = 0; round < maxRounds && !converged; ++round) {
|
|
||||||
converged = true;
|
|
||||||
SmallVector<Operation*> order(planOps);
|
|
||||||
if (round % 2)
|
|
||||||
std::reverse(order.begin(), order.end());
|
|
||||||
for (Operation* op : order) {
|
|
||||||
auto alternatives = getAlternatives(op, layouts, target);
|
|
||||||
if (failed(alternatives)) {
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spatial::PhysicalLayout current = layouts.lookup(op->getResult(0));
|
|
||||||
unsigned currentIndex = findCurrentAlternative(op, *alternatives, current);
|
|
||||||
int64_t bestCost = alternativeCost(
|
|
||||||
op, (*alternatives)[currentIndex], layouts, layouts, target);
|
|
||||||
unsigned bestIndex = currentIndex;
|
|
||||||
for (auto [index, alternative] : llvm::enumerate(*alternatives)) {
|
|
||||||
int64_t cost = alternativeCost(op, alternative, layouts, layouts, target);
|
|
||||||
if (cost < bestCost) {
|
|
||||||
bestCost = cost;
|
|
||||||
bestIndex = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spatial::PhysicalLayout selected = (*alternatives)[bestIndex].resultLayout;
|
|
||||||
if (selected != current) {
|
|
||||||
layouts[op->getResult(0)] = selected;
|
|
||||||
converged = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!converged) {
|
|
||||||
moduleOp.emitError("Spatial layout selection did not converge within its bounded iteration budget");
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
IRRewriter rewriter(&getContext());
|
|
||||||
for (Operation* op : planOps) {
|
|
||||||
op->setAttr(spatial::kSelectedLayoutAttrName,
|
|
||||||
spatial::PhysicalLayoutAttr::get(
|
|
||||||
rewriter.getContext(), layouts.lookup(op->getResult(0))));
|
|
||||||
if (failed(materializeMismatchedUses(rewriter, op->getResult(0), layouts, target))) {
|
|
||||||
signalPassFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (failed(verifySelectedLayouts(planOps, layouts, target))
|
|
||||||
|| failed(verifyLogicalSpatialGraphInvariants(*entryFunc))) {
|
|
||||||
moduleOp.emitError("Spatial layout planning verification failed");
|
|
||||||
signalPassFailure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spatial::SpatialTargetInfo target;
|
|
||||||
bool hasTarget = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
std::unique_ptr<Pass> createSpatialLayoutPlanningPass() {
|
|
||||||
return std::make_unique<SpatialLayoutPlanningPass>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Pass> createSpatialLayoutPlanningPass(
|
|
||||||
const spatial::SpatialTargetInfo& target) {
|
|
||||||
return std::make_unique<SpatialLayoutPlanningPass>(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace onnx_mlir
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ScheduledComputeMaterialization.hpp"
|
|
||||||
#include "Scheduling/MergeSchedulingAnalysis.hpp"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
namespace onnx_mlir::spatial {
|
|
||||||
|
|
||||||
struct ScheduledSpatialState {
|
|
||||||
std::optional<MergeScheduleResult> logicalSchedule;
|
|
||||||
std::optional<ScheduledComputeMaterializationResult> materialization;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace onnx_mlir::spatial
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#ifndef SPATIAL_LAYOUT_INTERFACE_TD
|
|
||||||
#define SPATIAL_LAYOUT_INTERFACE_TD
|
|
||||||
|
|
||||||
include "mlir/IR/OpBase.td"
|
|
||||||
|
|
||||||
def SpatialLayoutCapabilityInterface : OpInterface<"SpatialLayoutCapabilityInterface"> {
|
|
||||||
let description = [{
|
|
||||||
Contract implemented by logical Spatial planning operations that expose
|
|
||||||
their legal physical layout alternatives to the Spatial planner.
|
|
||||||
}];
|
|
||||||
|
|
||||||
let methods = [
|
|
||||||
InterfaceMethod<
|
|
||||||
"Return legal physical layout alternatives for this operation and its current operand layouts.",
|
|
||||||
"::llvm::SmallVector<::onnx_mlir::spatial::LayoutAlternative>",
|
|
||||||
"getLayoutAlternatives",
|
|
||||||
(ins "const ::onnx_mlir::spatial::SpatialTargetInfo &":$target,
|
|
||||||
"::llvm::ArrayRef<::onnx_mlir::spatial::PhysicalLayout>":$operandLayouts)>
|
|
||||||
];
|
|
||||||
|
|
||||||
let cppNamespace = "::onnx_mlir::spatial";
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace onnx_mlir::spatial {
|
|
||||||
|
|
||||||
struct MatrixUnitShape {
|
|
||||||
size_t rows = 128;
|
|
||||||
size_t columns = 128;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ConvLoweringStrategy : uint8_t {
|
|
||||||
Auto,
|
|
||||||
Legacy,
|
|
||||||
Depthwise,
|
|
||||||
PackedIm2Col,
|
|
||||||
StreamedPatch,
|
|
||||||
StreamedPacked,
|
|
||||||
OutputChannelTiled,
|
|
||||||
InputKTiled,
|
|
||||||
Tiled2D,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpatialTargetInfo {
|
|
||||||
MatrixUnitShape matrixShape;
|
|
||||||
size_t matrixUnitsPerProcessor = 64;
|
|
||||||
size_t processorCount = 1;
|
|
||||||
size_t vectorWidth = 16;
|
|
||||||
|
|
||||||
uint64_t convIm2colMaxElements = 1ull << 20;
|
|
||||||
uint64_t convStreamChunkPositions = 1024;
|
|
||||||
ConvLoweringStrategy convLoweringStrategy = ConvLoweringStrategy::Auto;
|
|
||||||
bool useExperimentalConvImplementation = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace onnx_mlir::spatial
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "mlir/Pass/Pass.h"
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace onnx_mlir {
|
|
||||||
namespace spatial {
|
|
||||||
struct SchedulingTarget;
|
|
||||||
struct ScheduledSpatialState;
|
|
||||||
struct SpatialTargetInfo;
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createScheduleSpatialGraphPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createScheduleSpatialGraphPass(const SchedulingTarget& target);
|
|
||||||
std::unique_ptr<mlir::Pass> createScheduleSpatialGraphPass(
|
|
||||||
const SchedulingTarget& target,
|
|
||||||
std::shared_ptr<ScheduledSpatialState> state);
|
|
||||||
std::unique_ptr<mlir::Pass> createVerifyScheduledSpatialPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createVerifyScheduledSpatialPass(
|
|
||||||
std::shared_ptr<ScheduledSpatialState> state);
|
|
||||||
std::unique_ptr<mlir::Pass> createRealizeSpatialCommunicationPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createRealizeSpatialCommunicationPass(
|
|
||||||
const SchedulingTarget& target,
|
|
||||||
std::shared_ptr<ScheduledSpatialState> state);
|
|
||||||
std::unique_ptr<mlir::Pass> createVerifyRealizedSpatialPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createVerifyRealizedSpatialPass(
|
|
||||||
std::shared_ptr<ScheduledSpatialState> state);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createONNXToSpatialPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createONNXToSpatialPass(const spatial::SpatialTargetInfo& target);
|
|
||||||
std::unique_ptr<mlir::Pass> createSpatialLayoutPlanningPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createSpatialLayoutPlanningPass(const spatial::SpatialTargetInfo& target);
|
|
||||||
std::unique_ptr<mlir::Pass> createLowerSpatialPlansPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createLowerSpatialPlansPass(const spatial::SpatialTargetInfo& target);
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createSpatialToPimPass();
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createPimBufferizationPreparationPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createPimOneShotBufferizationPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createPimMemoryNormalizationPass();
|
|
||||||
std::unique_ptr<mlir::Pass> createPimBufferizationVerificationPass();
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createTrivialGraphComputeMergePass();
|
|
||||||
std::unique_ptr<mlir::Pass> createTrivialGraphComputeMergePass(
|
|
||||||
size_t residentWeightCapacity);
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createPimHostConstantFoldingPass();
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createPimInstructionSelectionPass();
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createPimLocalMemoryPlanningPass();
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createPimVerificationPass();
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createEmitPimCodePass();
|
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createMessagePass(std::string message);
|
|
||||||
|
|
||||||
} // namespace onnx_mlir
|
|
||||||
@@ -20,5 +20,3 @@ networks/**/*.csv
|
|||||||
!networks/full_net/validation_results.csv
|
!networks/full_net/validation_results.csv
|
||||||
!networks/pimcomp_models/validation_results.csv
|
!networks/pimcomp_models/validation_results.csv
|
||||||
!networks/pimcomp_models/results.csv
|
!networks/pimcomp_models/results.csv
|
||||||
!networks/pimcomp_models/validation_results.csv
|
|
||||||
!operations/validation_results.csv
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,3 +1,5 @@
|
|||||||
model,raptor_latency_ms,pimcomp_latency_ms,raptor_energy_pj,pimcomp_energy_pj,faster_compiler,speedup
|
model,raptor_latency_ms,pimcomp_latency_ms,raptor_energy_pj,pimcomp_energy_pj,faster_compiler,speedup
|
||||||
vgg8,1.521060,7.985074,486309111.040001,1597904071.120000,raptor,5.25
|
vgg8,1.465778,7.985074,477298145.040001,1597904071.120000,raptor,5.45
|
||||||
resnet18,33.552733,58.853613,9702508727.119982,13983148468.119974,raptor,1.75
|
resnet18,28.099952,58.853733,8781611766.119984,13983168748.119974,raptor,2.09
|
||||||
|
resnet34,45.781486,91.607980,14962940227.679951,22722922369.680016,raptor,2.00
|
||||||
|
googlenet,13.371204,62.923463,6117835798.919991,14547526780.240000,raptor,4.71
|
||||||
|
|||||||
|
@@ -1,178 +1,169 @@
|
|||||||
Operation,Result,Compile,Host mem,Cores mem,Cores,Xbars,Latency,Power,Energy
|
Operation,Result,Compile,Host mem,Cores mem,Cores,Xbars,Latency,Power,Energy
|
||||||
add/after_gemm,PASS,-,0.01 MiB,0.01 MiB,5,4,0.007784 ms,104.703618 mW,815012.960000 pJ
|
add/after_gemm,PASS,0.063 s,0.01 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
add/basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
add/basic,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
add/broadcast_row,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
add/broadcast_row,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
add/channel_broadcast_1024,PASS,-,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
add/channel_broadcast_1024,PASS,0.061 s,0.02 MiB,0.01 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
add/leading_dimension_broadcast,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
add/leading_dimension_broadcast,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
concat/channel_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000457 ms,78.157549 mW,35718.000000 pJ
|
concat/channel_axis,PASS,0.069 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
concat/negative_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,0.001043 ms,78.092042 mW,81450.000000 pJ
|
concat/negative_axis,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
concat/three_inputs_channel_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000644 ms,78.149068 mW,50328.000000 pJ
|
concat/three_inputs_channel_axis,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
conv/batch_2,PASS,-,0.00 MiB,0.00 MiB,2,2,0.013694 ms,82.623885 mW,1131451.480000 pJ
|
conv/batch_2,PASS,0.066 s,0.00 MiB,0.00 MiB,2,2,SKIP,SKIP,SKIP
|
||||||
conv/batch_4_pointwise,PASS,-,0.00 MiB,0.01 MiB,5,4,0.003932 ms,116.078576 mW,456420.960000 pJ
|
conv/batch_4_pointwise,PASS,0.065 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
conv/conv_1x3x224x224_w64x3x7x7_b64,PASS,-,24.14 MiB,61.87 MiB,168,169,38.414551 ms,185.256473 mW,7116544212.120002 pJ
|
conv/depthwise_1024_channels,PASS,0.083 s,0.19 MiB,0.38 MiB,129,128,SKIP,SKIP,SKIP
|
||||||
conv/depthwise_1024_channels,PASS,-,0.19 MiB,0.38 MiB,129,128,0.220751 ms,178.454307 mW,39393966.720000 pJ
|
conv/depthwise_grouped,PASS,0.071 s,0.01 MiB,0.00 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
conv/depthwise_grouped,PASS,-,0.01 MiB,0.00 MiB,5,4,0.006234 ms,107.776541 mW,671878.960000 pJ
|
conv/dilated_3x3,PASS,0.068 s,0.01 MiB,0.01 MiB,10,9,SKIP,SKIP,SKIP
|
||||||
conv/dilated_3x3,PASS,-,0.01 MiB,0.01 MiB,10,9,0.008713 ms,118.767263 mW,1034819.160000 pJ
|
conv/dynamic,PASS,0.065 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
conv/dynamic,PASS,-,0.00 MiB,0.00 MiB,5,0,0.001835 ms,92.281199 mW,169336.000000 pJ
|
conv/explicit_padding,PASS,0.062 s,0.01 MiB,0.02 MiB,17,16,SKIP,SKIP,SKIP
|
||||||
conv/explicit_padding,PASS,-,0.01 MiB,0.02 MiB,17,16,0.010007 ms,145.338047 mW,1454397.840000 pJ
|
conv/grouped_many_groups,PASS,0.442 s,0.05 MiB,0.09 MiB,65,64,SKIP,SKIP,SKIP
|
||||||
conv/grouped_many_groups,PASS,-,0.05 MiB,0.09 MiB,65,64,0.181897 ms,142.207471 mW,25867112.360000 pJ
|
conv/grouped_two_groups,PASS,0.060 s,0.00 MiB,0.00 MiB,3,2,SKIP,SKIP,SKIP
|
||||||
conv/grouped_two_groups,PASS,-,0.00 MiB,0.00 MiB,3,2,0.005361 ms,101.457653 mW,543914.480000 pJ
|
conv/huge_pointwise_1024,PASS,0.156 s,0.01 MiB,0.11 MiB,73,64,SKIP,SKIP,SKIP
|
||||||
conv/huge_pointwise_1024,PASS,-,0.01 MiB,0.11 MiB,73,64,0.015615 ms,249.545140 mW,3896647.360000 pJ
|
conv/huge_pointwise_1024_dynamic,PASS,0.079 s,8.04 MiB,12.61 MiB,168,0,SKIP,SKIP,SKIP
|
||||||
conv/huge_pointwise_1024_dynamic,PASS,-,8.04 MiB,12.61 MiB,168,0,2.627964 ms,169.518697 mW,445489032.000000 pJ
|
conv/kernel_3x3,PASS,0.062 s,0.01 MiB,0.01 MiB,10,9,SKIP,SKIP,SKIP
|
||||||
conv/kernel_3x3,PASS,-,0.01 MiB,0.01 MiB,10,9,0.007186 ms,123.801859 mW,889640.160000 pJ
|
conv/kernel_equals_input_spatial,PASS,0.064 s,0.00 MiB,0.00 MiB,2,2,SKIP,SKIP,SKIP
|
||||||
conv/kernel_equals_input_spatial,PASS,-,0.00 MiB,0.00 MiB,2,2,0.004639 ms,89.607562 mW,415689.480000 pJ
|
conv/large_input_channels_1x1,PASS,0.089 s,0.01 MiB,0.02 MiB,9,8,SKIP,SKIP,SKIP
|
||||||
conv/large_input_channels_1x1,PASS,-,0.01 MiB,0.02 MiB,9,8,0.007648 ms,117.824519 mW,901121.920000 pJ
|
conv/large_output_channels_1x1,PASS,0.098 s,0.01 MiB,0.02 MiB,17,8,SKIP,SKIP,SKIP
|
||||||
conv/large_output_channels_1x1,PASS,-,0.01 MiB,0.02 MiB,17,8,0.008871 ms,128.442782 mW,1139415.920000 pJ
|
conv/large_spatial,PASS,0.069 s,0.01 MiB,0.04 MiB,37,36,SKIP,SKIP,SKIP
|
||||||
conv/large_spatial,PASS,-,0.01 MiB,0.04 MiB,37,36,0.017018 ms,172.073372 mW,2928344.640000 pJ
|
conv/multi_channel,PASS,0.066 s,0.00 MiB,0.00 MiB,4,3,SKIP,SKIP,SKIP
|
||||||
conv/multi_channel,PASS,-,0.00 MiB,0.00 MiB,4,3,0.006482 ms,105.683542 mW,685040.720000 pJ
|
conv/non_square_kernel_1x3,PASS,0.061 s,0.00 MiB,0.00 MiB,3,2,SKIP,SKIP,SKIP
|
||||||
conv/non_square_kernel_1x3,PASS,-,0.00 MiB,0.00 MiB,3,2,0.006842 ms,99.349968 mW,679752.480000 pJ
|
conv/non_square_kernel_3x1,PASS,0.064 s,0.00 MiB,0.00 MiB,3,2,SKIP,SKIP,SKIP
|
||||||
conv/non_square_kernel_3x1,PASS,-,0.00 MiB,0.00 MiB,3,2,0.013484 ms,95.889683 mW,1292976.480000 pJ
|
conv/non_uniform_stride,PASS,0.062 s,0.00 MiB,0.00 MiB,4,3,SKIP,SKIP,SKIP
|
||||||
conv/non_uniform_stride,PASS,-,0.00 MiB,0.00 MiB,4,3,0.007601 ms,104.048772 mW,790874.720000 pJ
|
conv/pointwise_1x1,PASS,0.059 s,0.00 MiB,0.00 MiB,1,1,SKIP,SKIP,SKIP
|
||||||
conv/output_channel_grouping_minimal,PASS,-,0.10 MiB,0.34 MiB,131,128,0.258453 ms,170.730913 mW,44125916.720000 pJ
|
conv/pointwise_tiled_chain,PASS,0.604 s,0.01 MiB,0.04 MiB,20,80,SKIP,SKIP,SKIP
|
||||||
conv/pointwise_1x1,PASS,-,0.00 MiB,0.00 MiB,1,1,0.012303 ms,80.244188 mW,987244.240000 pJ
|
conv/real_asymmetric_padding,PASS,0.060 s,0.01 MiB,0.03 MiB,29,28,SKIP,SKIP,SKIP
|
||||||
conv/pointwise_tiled_chain,PASS,-,0.01 MiB,0.04 MiB,20,80,0.041886 ms,153.880896 mW,6445455.200000 pJ
|
conv/relu_conv_store,PASS,0.091 s,0.16 MiB,0.67 MiB,168,184,SKIP,SKIP,SKIP
|
||||||
conv/real_asymmetric_padding,PASS,-,0.01 MiB,0.03 MiB,29,28,0.014457 ms,153.669968 mW,2221606.720000 pJ
|
conv/same_lower_3x3,PASS,0.078 s,0.01 MiB,0.02 MiB,26,25,SKIP,SKIP,SKIP
|
||||||
conv/relu_conv_store,PASS,-,0.16 MiB,0.67 MiB,168,184,0.562898 ms,183.084489 mW,103057892.800000 pJ
|
conv/same_padding_3x3,PASS,0.070 s,0.01 MiB,0.02 MiB,26,25,SKIP,SKIP,SKIP
|
||||||
conv/same_lower_3x3,PASS,-,0.01 MiB,0.02 MiB,26,25,0.013331 ms,166.154752 mW,2215009.000000 pJ
|
conv/simple,PASS,0.064 s,0.00 MiB,0.00 MiB,1,1,SKIP,SKIP,SKIP
|
||||||
conv/same_padding_3x3,PASS,-,0.01 MiB,0.02 MiB,26,25,0.013331 ms,166.154752 mW,2215009.000000 pJ
|
conv/stride_2,PASS,0.064 s,0.01 MiB,0.00 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
conv/simple,PASS,-,0.00 MiB,0.00 MiB,1,1,0.004301 ms,83.833583 mW,360568.240000 pJ
|
conv/with_bias_3x3,PASS,0.067 s,0.00 MiB,0.01 MiB,4,3,SKIP,SKIP,SKIP
|
||||||
conv/strategy_depthwise_16,PASS,-,0.06 MiB,0.35 MiB,168,168,0.335115 ms,197.936467 mW,66331479.080000 pJ
|
conv/with_constant,PASS,0.070 s,0.00 MiB,0.00 MiB,1,1,SKIP,SKIP,SKIP
|
||||||
conv/strategy_input_k_tiled,PASS,-,0.08 MiB,0.27 MiB,109,108,0.353736 ms,170.812713 mW,60422605.920000 pJ
|
conv/without_kernel_shape_attr,PASS,0.069 s,0.01 MiB,0.01 MiB,10,9,SKIP,SKIP,SKIP
|
||||||
conv/strategy_output_channel_tiled,PASS,-,0.03 MiB,0.16 MiB,74,72,0.091463 ms,155.743189 mW,14244739.280000 pJ
|
conv/yolo11n_depthwise_head,PASS,1.482 s,8.66 MiB,34.24 MiB,168,255,SKIP,SKIP,SKIP
|
||||||
conv/strategy_streamed_packed,PASS,-,3.34 MiB,7.89 MiB,168,168,9.353833 ms,179.858301 mW,1682364509.560000 pJ
|
conv/yolo11n_heavy,PASS,0.431 s,4.82 MiB,19.10 MiB,161,800,SKIP,SKIP,SKIP
|
||||||
conv/strategy_streamed_patch,PASS,-,0.34 MiB,1.32 MiB,168,168,1.904655 ms,181.910449 mW,346476645.640000 pJ
|
conv/yolo11n_stem,PASS,0.783 s,12.86 MiB,37.59 MiB,168,488,SKIP,SKIP,SKIP
|
||||||
conv/strategy_tiled_2d,PASS,-,0.11 MiB,0.44 MiB,168,168,0.415594 ms,182.127047 mW,75690907.840000 pJ
|
div/after_gemm,PASS,0.072 s,0.01 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
conv/stride_2,PASS,-,0.01 MiB,0.00 MiB,5,4,0.005237 ms,110.780019 mW,580154.960000 pJ
|
div/basic,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
conv/with_bias_3x3,PASS,-,0.00 MiB,0.01 MiB,4,3,0.007452 ms,104.162738 mW,776220.720000 pJ
|
div/channel_broadcast_1024,PASS,0.066 s,0.02 MiB,0.01 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
conv/with_constant,PASS,-,0.00 MiB,0.00 MiB,1,1,0.006622 ms,81.738182 mW,541270.240000 pJ
|
div/leading_dimension_broadcast,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
conv/without_kernel_shape_attr,PASS,-,0.01 MiB,0.01 MiB,10,9,0.007186 ms,123.801859 mW,889640.160000 pJ
|
div/runtime_scalar_rhs,PASS,0.056 s,0.02 MiB,0.01 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
conv/yolo11n_depthwise_head,PASS,-,8.66 MiB,34.24 MiB,168,255,42.701404 ms,200.519161 mW,8562449708.000010 pJ
|
div/scalar_constant,PASS,0.073 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
conv/yolo11n_heavy,PASS,-,4.82 MiB,19.10 MiB,161,800,8.535404 ms,350.863768 mW,2994764012.000010 pJ
|
gather/3d_input_axis1,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
conv/yolo11n_stem,PASS,-,12.86 MiB,37.59 MiB,168,488,14.239985 ms,301.233376 mW,4289558753.000010 pJ
|
gather/axis0_matrix_indices,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
div/after_gemm,PASS,-,0.01 MiB,0.01 MiB,5,4,0.007784 ms,104.703618 mW,815012.960000 pJ
|
gather/axis1,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
div/basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
gather/negative_axis,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
div/channel_broadcast_1024,PASS,-,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
gather/negative_indices,PASS,0.063 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
div/leading_dimension_broadcast,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
gemm/alpha_beta,PASS,0.067 s,0.01 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
div/runtime_scalar_rhs,PASS,-,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
gemm/bias_rank2_broadcast,PASS,0.060 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
div/scalar_constant,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
gemm/dynamic,PASS,0.064 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
gather/3d_input_axis1,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000589 ms,78.081494 mW,45990.000000 pJ
|
gemm/dynamic_alpha,PASS,0.062 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
gather/axis0_matrix_indices,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000697 ms,78.068867 mW,54414.000000 pJ
|
gemm/dynamic_beta,PASS,0.060 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
gather/axis1,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000801 ms,78.059925 mW,62526.000000 pJ
|
gemm/dynamic_bias,PASS,0.058 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
gather/negative_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,0.001437 ms,78.033403 mW,112134.000000 pJ
|
gemm/dynamic_bias_alpha_beta,PASS,0.067 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
gather/negative_indices,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000376 ms,78.127660 mW,29376.000000 pJ
|
gemm/dynamic_transB,PASS,0.062 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
gemm/alpha_beta,PASS,-,0.01 MiB,0.01 MiB,5,4,0.007456 ms,105.272125 mW,784908.960000 pJ
|
gemm/huge_1024,PASS,0.147 s,0.01 MiB,0.10 MiB,73,64,SKIP,SKIP,SKIP
|
||||||
gemm/bias_rank2_broadcast,PASS,-,0.00 MiB,0.01 MiB,5,4,0.007072 ms,105.979208 mW,749484.960000 pJ
|
gemm/large,PASS,0.068 s,0.02 MiB,0.03 MiB,17,16,SKIP,SKIP,SKIP
|
||||||
gemm/dynamic,PASS,-,0.00 MiB,0.00 MiB,5,0,0.002421 ms,91.480793 mW,221475.000000 pJ
|
gemm/large_k_small_n,PASS,0.095 s,0.01 MiB,0.01 MiB,9,8,SKIP,SKIP,SKIP
|
||||||
gemm/dynamic_alpha,PASS,-,0.00 MiB,0.00 MiB,5,0,0.003262 ms,91.415696 mW,298198.000000 pJ
|
gemm/non_square,PASS,0.063 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemm/dynamic_beta,PASS,-,0.00 MiB,0.00 MiB,5,0,0.004365 ms,91.316151 mW,398595.000000 pJ
|
gemm/scalar_bias,PASS,0.060 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemm/dynamic_bias,PASS,-,0.00 MiB,0.00 MiB,5,0,0.002665 ms,91.445779 mW,243703.000000 pJ
|
gemm/simple,PASS,0.072 s,0.03 MiB,0.08 MiB,42,40,SKIP,SKIP,SKIP
|
||||||
gemm/dynamic_bias_alpha_beta,PASS,-,0.00 MiB,0.00 MiB,5,0,0.005629 ms,91.279268 mW,513811.000000 pJ
|
gemm/small,PASS,0.065 s,0.00 MiB,0.00 MiB,2,2,SKIP,SKIP,SKIP
|
||||||
gemm/dynamic_transB,PASS,-,0.00 MiB,0.00 MiB,5,0,0.001301 ms,91.378171 mW,118883.000000 pJ
|
gemm/small_k_large_n,PASS,0.097 s,0.01 MiB,0.02 MiB,17,8,SKIP,SKIP,SKIP
|
||||||
gemm/huge_1024,PASS,-,0.01 MiB,0.10 MiB,73,64,0.017522 ms,215.037402 mW,3767885.360000 pJ
|
gemm/transA,PASS,0.064 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemm/large,PASS,-,0.02 MiB,0.03 MiB,17,16,0.011229 ms,140.152181 mW,1573768.840000 pJ
|
gemm/transA_transB,PASS,0.069 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemm/large_k_small_n,PASS,-,0.01 MiB,0.01 MiB,9,8,0.004748 ms,133.481449 mW,633769.920000 pJ
|
gemm/transB,PASS,0.062 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemm/non_square,PASS,-,0.00 MiB,0.01 MiB,5,4,0.003527 ms,118.958310 mW,419565.960000 pJ
|
gemm/transB_with_bias,PASS,0.055 s,0.01 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemm/scalar_bias,PASS,-,0.00 MiB,0.01 MiB,5,4,0.007072 ms,105.979208 mW,749484.960000 pJ
|
gemm/with_bias,PASS,0.067 s,0.01 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemm/simple,PASS,-,0.03 MiB,0.08 MiB,42,40,0.021640 ms,151.774196 mW,3284393.600000 pJ
|
gemv/constant,PASS,0.064 s,0.00 MiB,0.00 MiB,0,0,SKIP,SKIP,SKIP
|
||||||
gemm/small,PASS,-,0.00 MiB,0.00 MiB,2,2,0.004420 ms,90.144000 mW,398436.480000 pJ
|
gemv/simple,PASS,0.069 s,0.00 MiB,0.01 MiB,6,4,SKIP,SKIP,SKIP
|
||||||
gemm/small_k_large_n,PASS,-,0.01 MiB,0.02 MiB,17,8,0.007962 ms,131.005014 mW,1043061.920000 pJ
|
gemv/with_heterogeneous_constant,PASS,0.066 s,0.00 MiB,0.01 MiB,6,4,SKIP,SKIP,SKIP
|
||||||
gemm/transA,PASS,-,0.00 MiB,0.01 MiB,5,4,0.005762 ms,109.140743 mW,628868.960000 pJ
|
gemv/with_homogeneous_constant,PASS,0.070 s,0.00 MiB,0.01 MiB,6,4,SKIP,SKIP,SKIP
|
||||||
gemm/transA_transB,PASS,-,0.00 MiB,0.01 MiB,5,4,0.005762 ms,109.140743 mW,628868.960000 pJ
|
gemv/with_scalar_constant,PASS,0.070 s,0.00 MiB,0.01 MiB,6,4,SKIP,SKIP,SKIP
|
||||||
gemm/transB,PASS,-,0.00 MiB,0.01 MiB,5,4,0.003527 ms,118.958310 mW,419565.960000 pJ
|
matmul/basic,PASS,0.062 s,0.00 MiB,0.00 MiB,2,2,SKIP,SKIP,SKIP
|
||||||
gemm/transB_with_bias,PASS,-,0.01 MiB,0.01 MiB,5,4,0.005046 ms,110.546762 mW,557818.960000 pJ
|
matmul/batched_3d,PASS,0.066 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemm/with_bias,PASS,-,0.01 MiB,0.01 MiB,5,4,0.005562 ms,108.767882 mW,604966.960000 pJ
|
matmul/batched_3d_dynamic,PASS,0.057 s,0.00 MiB,0.00 MiB,4,0,SKIP,SKIP,SKIP
|
||||||
gemv/constant,PASS,-,0.00 MiB,0.00 MiB,0,0,0.000000 ms,2.000000 mW,0.000000 pJ
|
matmul/batched_left_constant,PASS,0.070 s,0.00 MiB,0.02 MiB,9,8,SKIP,SKIP,SKIP
|
||||||
gemv/simple,PASS,-,0.00 MiB,0.01 MiB,6,4,0.005160 ms,111.150380 mW,573535.960000 pJ
|
matmul/batched_lhs_broadcast,PASS,0.063 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemv/with_heterogeneous_constant,PASS,-,0.00 MiB,0.01 MiB,6,4,0.005549 ms,109.816536 mW,609371.960000 pJ
|
matmul/batched_rhs_broadcast,PASS,0.062 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
gemv/with_homogeneous_constant,PASS,-,0.00 MiB,0.01 MiB,6,4,0.005549 ms,109.816536 mW,609371.960000 pJ
|
matmul/dynamic,PASS,0.060 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
gemv/with_scalar_constant,PASS,-,0.00 MiB,0.01 MiB,6,4,0.005549 ms,109.816536 mW,609371.960000 pJ
|
matmul/huge_1024,PASS,0.145 s,0.01 MiB,0.10 MiB,73,64,SKIP,SKIP,SKIP
|
||||||
matmul/basic,PASS,-,0.00 MiB,0.00 MiB,2,2,0.004420 ms,90.144000 mW,398436.480000 pJ
|
matmul/left_constant,PASS,0.051 s,0.00 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
matmul/batched_3d,PASS,-,0.00 MiB,0.01 MiB,5,4,0.005958 ms,108.588949 mW,646972.960000 pJ
|
matmul/matrix_vector,PASS,0.095 s,0.52 MiB,0.78 MiB,168,173,SKIP,SKIP,SKIP
|
||||||
matmul/batched_3d_dynamic,PASS,-,0.00 MiB,0.00 MiB,4,0,0.001822 ms,92.192645 mW,167975.000000 pJ
|
matmul/vector_matrix,PASS,0.087 s,0.01 MiB,0.01 MiB,9,8,SKIP,SKIP,SKIP
|
||||||
matmul/batched_left_constant,PASS,-,0.00 MiB,0.02 MiB,9,8,0.008822 ms,114.385164 mW,1009105.920000 pJ
|
matmul/yolo_attention,PASS,0.385 s,1.02 MiB,43.44 MiB,168,0,SKIP,SKIP,SKIP
|
||||||
matmul/batched_lhs_broadcast,PASS,-,0.00 MiB,0.01 MiB,5,4,0.005681 ms,109.389361 mW,621440.960000 pJ
|
mul/after_conv,PASS,0.055 s,0.00 MiB,0.00 MiB,4,3,SKIP,SKIP,SKIP
|
||||||
matmul/batched_rhs_broadcast,PASS,-,0.00 MiB,0.01 MiB,5,4,0.005958 ms,108.588949 mW,646972.960000 pJ
|
mul/basic,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
matmul/dynamic,PASS,-,0.00 MiB,0.00 MiB,5,0,0.001621 ms,91.421962 mW,148195.000000 pJ
|
mul/channel_broadcast_1024,PASS,0.058 s,0.02 MiB,0.01 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
matmul/huge_1024,PASS,-,0.01 MiB,0.10 MiB,73,64,0.017522 ms,215.037402 mW,3767885.360000 pJ
|
mul/leading_dimension_broadcast,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
matmul/left_constant,PASS,-,0.00 MiB,0.01 MiB,5,4,0.005853 ms,108.861944 mW,637168.960000 pJ
|
mul/scalar_constant,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
matmul/matrix_vector,PASS,-,0.52 MiB,0.78 MiB,168,173,0.384660 ms,202.131271 mW,77751814.880000 pJ
|
pool/avg_basic,PASS,0.063 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
matmul/vector_matrix,PASS,-,0.01 MiB,0.01 MiB,9,8,0.007409 ms,118.680243 mW,879301.920000 pJ
|
pool/avg_ceil_mode,PASS,0.063 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
matmul/yolo_attention,PASS,-,1.02 MiB,43.44 MiB,168,0,8.151445 ms,170.003707 mW,1385775865.000000 pJ
|
pool/avg_explicit_padding,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
mul/after_conv,PASS,-,0.00 MiB,0.00 MiB,4,3,0.005453 ms,107.639046 mW,586955.720000 pJ
|
pool/avg_include_pad,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
mul/after_conv_scalar_constant,PASS,-,0.00 MiB,0.00 MiB,4,3,0.005453 ms,107.639046 mW,586955.720000 pJ
|
pool/avg_large_channels,PASS,0.059 s,0.04 MiB,0.02 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
mul/basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
pool/avg_non_uniform_stride,PASS,0.066 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
mul/channel_broadcast_1024,PASS,-,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
pool/avg_real_asymmetric_padding,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
mul/leading_dimension_broadcast,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
pool/max_after_conv,PASS,0.069 s,0.00 MiB,0.00 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
mul/scalar_constant,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
pool/max_basic,PASS,0.064 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
pool/avg_basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.011939 ms,78.022112 mW,931506.000000 pJ
|
pool/max_ceil_mode,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
pool/avg_ceil_mode,PASS,-,0.00 MiB,0.00 MiB,1,0,0.004359 ms,78.033035 mW,340146.000000 pJ
|
pool/max_global_style_kernel_equals_input,PASS,0.063 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
pool/avg_explicit_padding,PASS,-,0.00 MiB,0.00 MiB,1,0,0.008822 ms,78.027205 mW,688356.000000 pJ
|
pool/max_non_square_kernel,PASS,0.067 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
pool/avg_include_pad,PASS,-,0.00 MiB,0.00 MiB,1,0,0.008506 ms,78.016929 mW,663612.000000 pJ
|
pool/max_real_asymmetric_padding,PASS,0.063 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
pool/avg_large_channels,PASS,-,0.04 MiB,0.02 MiB,1,0,0.235874 ms,78.004172 mW,18399156.000000 pJ
|
pool/max_same_upper,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
pool/avg_non_uniform_stride,PASS,-,0.00 MiB,0.00 MiB,1,0,0.014513 ms,78.016537 mW,1132254.000000 pJ
|
pool/max_stride2_multichannel,PASS,0.076 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
pool/avg_real_asymmetric_padding,PASS,-,0.00 MiB,0.00 MiB,1,0,0.025206 ms,78.024756 mW,1966692.000000 pJ
|
reduce_mean/4d_spatial,PASS,0.058 s,0.00 MiB,0.00 MiB,3,0,SKIP,SKIP,SKIP
|
||||||
pool/max_after_conv,PASS,-,0.00 MiB,0.00 MiB,5,4,0.012215 ms,99.115019 mW,1210689.960000 pJ
|
reduce_mean/4d_spatial_keepdims_0,PASS,0.068 s,0.00 MiB,0.00 MiB,4,0,SKIP,SKIP,SKIP
|
||||||
pool/max_basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.004160 ms,78.063462 mW,324744.000000 pJ
|
reduce_mean/after_conv,PASS,0.067 s,0.00 MiB,0.00 MiB,5,3,SKIP,SKIP,SKIP
|
||||||
pool/max_ceil_mode,PASS,-,0.00 MiB,0.00 MiB,1,0,0.001940 ms,78.074227 mW,151464.000000 pJ
|
reduce_mean/all_axes_keepdims_0,PASS,0.057 s,0.00 MiB,0.00 MiB,2,0,SKIP,SKIP,SKIP
|
||||||
pool/max_global_style_kernel_equals_input,PASS,-,0.00 MiB,0.00 MiB,1,0,0.008443 ms,78.008528 mW,658626.000000 pJ
|
reduce_mean/all_axes_keepdims_1,PASS,0.053 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
pool/max_non_square_kernel,PASS,-,0.00 MiB,0.00 MiB,1,0,0.013626 ms,78.017613 mW,1063068.000000 pJ
|
reduce_mean/basic,PASS,0.058 s,0.00 MiB,0.00 MiB,4,0,SKIP,SKIP,SKIP
|
||||||
pool/max_real_asymmetric_padding,PASS,-,0.00 MiB,0.00 MiB,1,0,0.010444 ms,78.034470 mW,814992.000000 pJ
|
reduce_mean/channel_axis_nchw,PASS,0.063 s,0.03 MiB,0.02 MiB,4,0,SKIP,SKIP,SKIP
|
||||||
pool/max_same_upper,PASS,-,0.00 MiB,0.00 MiB,1,0,0.008010 ms,78.035955 mW,625068.000000 pJ
|
reduce_mean/keepdims_0,PASS,0.064 s,0.00 MiB,0.00 MiB,5,0,SKIP,SKIP,SKIP
|
||||||
pool/max_stride2_multichannel,PASS,-,0.00 MiB,0.00 MiB,1,0,0.015987 ms,78.018015 mW,1247274.000000 pJ
|
reduce_mean/large_dimension_1024,PASS,0.066 s,0.01 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/4d_spatial,PASS,-,0.00 MiB,0.00 MiB,3,0,0.000321 ms,92.448598 mW,29676.000000 pJ
|
reduce_mean/legacy_axes_1_2_keepdims_1,PASS,0.069 s,0.00 MiB,0.00 MiB,2,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/4d_spatial_keepdims_0,PASS,-,0.00 MiB,0.00 MiB,4,0,0.000655 ms,94.352672 mW,61801.000000 pJ
|
reduce_mean/legacy_axis1_keepdims_0,PASS,0.067 s,0.00 MiB,0.00 MiB,9,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/after_conv,PASS,-,0.00 MiB,0.00 MiB,5,3,0.005342 ms,106.951089 mW,571332.720000 pJ
|
reduce_mean/legacy_axis1_keepdims_1,PASS,0.057 s,0.00 MiB,0.00 MiB,8,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/all_axes_keepdims_0,PASS,-,0.00 MiB,0.00 MiB,2,0,0.000391 ms,79.237852 mW,30982.000000 pJ
|
reduce_mean/legacy_empty_axes_noop,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/all_axes_keepdims_1,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
reduce_mean/legacy_nchw_spatial,PASS,0.059 s,0.00 MiB,0.00 MiB,3,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/basic,PASS,-,0.00 MiB,0.00 MiB,4,0,0.000373 ms,93.514745 mW,34881.000000 pJ
|
reduce_mean/legacy_negative_axis,PASS,0.052 s,0.00 MiB,0.00 MiB,6,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/channel_axis_nchw,PASS,-,0.03 MiB,0.02 MiB,4,0,0.164926 ms,93.596631 mW,15436518.000000 pJ
|
reduce_mean/legacy_reduce_all_keepdims_1,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/keepdims_0,PASS,-,0.00 MiB,0.00 MiB,5,0,0.000748 ms,91.401070 mW,68368.000000 pJ
|
reduce_mean/negative_axis,PASS,0.055 s,0.00 MiB,0.00 MiB,6,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/large_dimension_1024,PASS,-,0.01 MiB,0.00 MiB,1,0,0.002785 ms,78.017235 mW,217278.000000 pJ
|
relu/4d,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/legacy_axes_1_2_keepdims_1,PASS,-,0.00 MiB,0.00 MiB,2,0,0.000271 ms,79.354244 mW,21505.000000 pJ
|
relu/after_conv,PASS,0.062 s,0.00 MiB,0.00 MiB,4,3,SKIP,SKIP,SKIP
|
||||||
reduce_mean/legacy_axis1_keepdims_0,PASS,-,0.00 MiB,0.00 MiB,9,0,0.001986 ms,92.501511 mW,183708.000000 pJ
|
relu/after_gemm,PASS,0.062 s,0.01 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
reduce_mean/legacy_axis1_keepdims_1,PASS,-,0.00 MiB,0.00 MiB,8,0,0.001373 ms,94.559359 mW,129830.000000 pJ
|
relu/basic,PASS,0.062 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/legacy_empty_axes_noop,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
reshape/4d_to_2d_flatten,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/legacy_nchw_spatial,PASS,-,0.00 MiB,0.00 MiB,3,0,0.000321 ms,92.448598 mW,29676.000000 pJ
|
reshape/infer_dim_minus_one,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/legacy_negative_axis,PASS,-,0.00 MiB,0.00 MiB,6,0,0.000553 ms,93.520796 mW,51717.000000 pJ
|
reshape/same_rank,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/legacy_reduce_all_keepdims_1,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
reshape/zero_copies_input_dim,PASS,0.077 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reduce_mean/negative_axis,PASS,-,0.00 MiB,0.00 MiB,6,0,0.000553 ms,93.520796 mW,51717.000000 pJ
|
resize/height_only,PASS,0.059 s,0.00 MiB,0.00 MiB,4,0,SKIP,SKIP,SKIP
|
||||||
relu/4d,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000521 ms,78.184261 mW,40734.000000 pJ
|
resize/nearest_2x,PASS,0.066 s,0.00 MiB,0.00 MiB,4,0,SKIP,SKIP,SKIP
|
||||||
relu/after_conv,PASS,-,0.00 MiB,0.00 MiB,4,3,0.005352 ms,107.891951 mW,577437.720000 pJ
|
resize/nearest_downsample,PASS,0.062 s,0.00 MiB,0.00 MiB,2,0,SKIP,SKIP,SKIP
|
||||||
relu/after_gemm,PASS,-,0.01 MiB,0.01 MiB,5,4,0.007513 ms,105.158653 mW,790056.960000 pJ
|
resize/non_uniform,PASS,0.069 s,0.00 MiB,0.00 MiB,6,0,SKIP,SKIP,SKIP
|
||||||
relu/basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
resize/width_only,PASS,0.055 s,0.00 MiB,0.00 MiB,2,0,SKIP,SKIP,SKIP
|
||||||
reshape/4d_to_2d_flatten,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000258 ms,78.279070 mW,20196.000000 pJ
|
resize/with_sizes,PASS,0.060 s,0.00 MiB,0.00 MiB,3,0,SKIP,SKIP,SKIP
|
||||||
reshape/infer_dim_minus_one,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000162 ms,78.296296 mW,12684.000000 pJ
|
sigmoid/4d,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
reshape/same_rank,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000162 ms,78.296296 mW,12684.000000 pJ
|
sigmoid/after_gemm,PASS,0.059 s,0.01 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
reshape/zero_copies_input_dim,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000162 ms,78.296296 mW,12684.000000 pJ
|
sigmoid/basic,PASS,0.053 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
resize/height_only,PASS,-,0.00 MiB,0.00 MiB,4,0,0.000693 ms,93.554113 mW,64833.000000 pJ
|
slice/2d_basic,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
resize/nearest_2x,PASS,-,0.00 MiB,0.00 MiB,4,0,0.001173 ms,93.572890 mW,109761.000000 pJ
|
slice/after_conv,PASS,0.070 s,0.00 MiB,0.01 MiB,7,6,SKIP,SKIP,SKIP
|
||||||
resize/nearest_downsample,PASS,-,0.00 MiB,0.00 MiB,2,0,0.000427 ms,79.449649 mW,33925.000000 pJ
|
slice/default_axes,PASS,0.066 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
resize/non_uniform,PASS,-,0.00 MiB,0.00 MiB,6,0,0.001753 ms,93.575014 mW,164037.000000 pJ
|
slice/large_channel_1024,PASS,0.064 s,0.01 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
resize/width_only,PASS,-,0.00 MiB,0.00 MiB,2,0,0.000667 ms,79.503748 mW,53029.000000 pJ
|
slice/nchw_spatial_crop,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
resize/with_sizes,PASS,-,0.00 MiB,0.00 MiB,3,0,0.000797 ms,92.542033 mW,73756.000000 pJ
|
slice/negative_axis,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
sigmoid/4d,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000521 ms,78.184261 mW,40734.000000 pJ
|
slice/negative_indices,PASS,0.053 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
sigmoid/after_gemm,PASS,-,0.01 MiB,0.01 MiB,5,4,0.007513 ms,105.158653 mW,790056.960000 pJ
|
slice/step2,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
sigmoid/basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000221 ms,78.217195 mW,17286.000000 pJ
|
softmax/3d_last_axis,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
slice/2d_basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000242 ms,78.297521 mW,18948.000000 pJ
|
softmax/basic,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
slice/after_conv,PASS,-,0.00 MiB,0.01 MiB,7,6,0.011296 ms,118.190765 mW,1335082.880000 pJ
|
softmax/channel_axis,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
slice/default_axes,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000242 ms,78.297521 mW,18948.000000 pJ
|
softmax/large_dimension_1024,PASS,0.061 s,0.01 MiB,0.01 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
slice/large_channel_1024,PASS,-,0.01 MiB,0.00 MiB,1,0,0.002832 ms,78.144068 mW,221304.000000 pJ
|
softmax/negative_axis,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
slice/nchw_spatial_crop,PASS,-,0.00 MiB,0.00 MiB,1,0,0.001302 ms,78.239631 mW,101868.000000 pJ
|
split/basic,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
slice/negative_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000562 ms,78.298932 mW,44004.000000 pJ
|
split/equal_three_way,PASS,0.063 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
slice/negative_indices,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000322 ms,78.298137 mW,25212.000000 pJ
|
split/negative_axis,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
slice/step2,PASS,-,0.00 MiB,0.00 MiB,1,0,0.002042 ms,78.293830 mW,159876.000000 pJ
|
split/uneven_channel_axis_4d,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
softmax/3d_last_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
sub/after_gemm,PASS,0.064 s,0.01 MiB,0.01 MiB,5,4,SKIP,SKIP,SKIP
|
||||||
softmax/basic,PASS,-,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
sub/basic,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
softmax/channel_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
sub/broadcast_row,PASS,0.064 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
softmax/large_dimension_1024,PASS,-,0.01 MiB,0.01 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
sub/channel_broadcast_1024,PASS,0.063 s,0.02 MiB,0.01 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
softmax/negative_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED
|
sub/constant_lhs_broadcast,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
split/basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000403 ms,78.297767 mW,31554.000000 pJ
|
sub/leading_dimension_broadcast,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,SKIP,SKIP,SKIP
|
||||||
split/equal_three_way,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000564 ms,78.297872 mW,44160.000000 pJ
|
|
||||||
split/negative_axis,PASS,-,0.00 MiB,0.00 MiB,1,0,0.001083 ms,78.288089 mW,84786.000000 pJ
|
|
||||||
split/uneven_channel_axis_4d,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000242 ms,78.297521 mW,18948.000000 pJ
|
|
||||||
sub/after_gemm,PASS,-,0.01 MiB,0.01 MiB,5,4,0.007784 ms,104.703618 mW,815012.960000 pJ
|
|
||||||
sub/basic,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
|
||||||
sub/broadcast_row,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
|
||||||
sub/channel_broadcast_1024,PASS,-,0.02 MiB,0.01 MiB,1,0,0.006913 ms,78.118038 mW,540030.000000 pJ
|
|
||||||
sub/constant_lhs_broadcast,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000322 ms,78.223602 mW,25188.000000 pJ
|
|
||||||
sub/leading_dimension_broadcast,PASS,-,0.00 MiB,0.00 MiB,1,0,0.000323 ms,78.222910 mW,25266.000000 pJ
|
|
||||||
|
|||||||
|
@@ -1,182 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Save exact attention-tap arrays and quantify the MatMul error sources."""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import hashlib
|
|
||||||
import json
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import onnx
|
|
||||||
from onnx import numpy_helper
|
|
||||||
|
|
||||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
||||||
sys.path.insert(0, str(REPO_ROOT / "validation"))
|
|
||||||
|
|
||||||
from raptor_validation.onnx_utils import onnx_io # noqa: E402
|
|
||||||
from raptor_validation.validate_one import ( # noqa: E402
|
|
||||||
parse_pim_simulator_outputs,
|
|
||||||
sanitize_output_name,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
TAP_NAMES = {
|
|
||||||
"v": "/model.10/m/m.0/attn/Split_output_2",
|
|
||||||
"raw": "/model.10/m/m.0/attn/MatMul_output_0",
|
|
||||||
"scaled": "/model.10/m/m.0/attn/Mul_output_0",
|
|
||||||
"rhs": "/model.10/m/m.0/attn/Transpose_1_output_0",
|
|
||||||
"c": "/model.10/m/m.0/attn/MatMul_1_output_0",
|
|
||||||
}
|
|
||||||
ABSOLUTE_TOLERANCE = 1e-3
|
|
||||||
RELATIVE_TOLERANCE = 1e-5
|
|
||||||
|
|
||||||
|
|
||||||
def sha256(path):
|
|
||||||
digest = hashlib.sha256()
|
|
||||||
with Path(path).open("rb") as stream:
|
|
||||||
for block in iter(lambda: stream.read(1 << 20), b""):
|
|
||||||
digest.update(block)
|
|
||||||
return digest.hexdigest()
|
|
||||||
|
|
||||||
|
|
||||||
def metric(actual, expected):
|
|
||||||
difference = np.abs(actual.astype(np.float64) - expected.astype(np.float64))
|
|
||||||
allowed = ABSOLUTE_TOLERANCE + RELATIVE_TOLERANCE * np.abs(expected.astype(np.float64))
|
|
||||||
return {
|
|
||||||
"max_abs": float(np.max(difference)),
|
|
||||||
"mean_abs": float(np.mean(difference)),
|
|
||||||
"rms": float(np.sqrt(np.mean(np.square(difference)))),
|
|
||||||
"elements_over_validator_limit": int(np.count_nonzero(difference > allowed)),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def f32_matmul(lhs, rhs):
|
|
||||||
return np.matmul(lhs.astype(np.float32), rhs.astype(np.float32)).astype(np.float32)
|
|
||||||
|
|
||||||
|
|
||||||
def f64_matmul(lhs, rhs):
|
|
||||||
return np.matmul(lhs.astype(np.float64), rhs.astype(np.float64)).astype(np.float64)
|
|
||||||
|
|
||||||
|
|
||||||
def load_constant(model, output_name):
|
|
||||||
for initializer in model.graph.initializer:
|
|
||||||
if initializer.name == output_name:
|
|
||||||
return float(numpy_helper.to_array(initializer).reshape(-1)[0])
|
|
||||||
for node in model.graph.node:
|
|
||||||
if output_name not in node.output:
|
|
||||||
continue
|
|
||||||
for attribute in node.attribute:
|
|
||||||
if attribute.name == "value" and attribute.HasField("t"):
|
|
||||||
return float(numpy_helper.to_array(attribute.t).reshape(-1)[0])
|
|
||||||
raise ValueError(f"could not find ONNX Constant producing {output_name}")
|
|
||||||
|
|
||||||
|
|
||||||
def load_arrays(workspace, model_path):
|
|
||||||
model = onnx.load(model_path)
|
|
||||||
descriptors = onnx_io(model_path)
|
|
||||||
output_descriptors = {name: (index, dtype, shape) for index, name, dtype, shape in descriptors[1]}
|
|
||||||
missing = sorted(set(TAP_NAMES.values()) - set(output_descriptors))
|
|
||||||
if missing:
|
|
||||||
raise ValueError("tap model is missing outputs: " + ", ".join(missing))
|
|
||||||
|
|
||||||
sim_arrays = parse_pim_simulator_outputs(
|
|
||||||
workspace / "simulation" / "out.bin", descriptors[1]
|
|
||||||
)
|
|
||||||
reference = {}
|
|
||||||
simulated = {}
|
|
||||||
input_files = {}
|
|
||||||
for key, name in TAP_NAMES.items():
|
|
||||||
index, _dtype, shape = output_descriptors[name]
|
|
||||||
csv_path = workspace / "outputs" / f"output{index}_{sanitize_output_name(name)}.csv"
|
|
||||||
reference[key] = np.loadtxt(csv_path, delimiter=",", dtype=np.float32).reshape(shape)
|
|
||||||
simulated[key] = np.asarray(sim_arrays[index], dtype=np.float32).reshape(shape)
|
|
||||||
input_files[key] = csv_path
|
|
||||||
return reference, simulated, input_files
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
|
||||||
parser.add_argument("--workspace", type=Path, required=True,
|
|
||||||
help="validator workspace containing inputs, outputs, and simulation")
|
|
||||||
parser.add_argument("--model", type=Path, required=True, help="five-output ONNX tap model")
|
|
||||||
parser.add_argument("--output-dir", type=Path, required=True,
|
|
||||||
help="directory for arrays.npz, metadata.json, and decomposition.json")
|
|
||||||
args = parser.parse_args()
|
|
||||||
args.output_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
model = onnx.load(args.model)
|
|
||||||
reference, simulated, source_files = load_arrays(args.workspace, args.model)
|
|
||||||
scale = np.float32(load_constant(model, "/model.10/m/m.0/attn/Constant_1_output_0"))
|
|
||||||
ref_v, ref_raw, ref_scaled, ref_rhs, ref_c = (reference[key] for key in ("v", "raw", "scaled", "rhs", "c"))
|
|
||||||
sim_v, sim_raw, sim_scaled, sim_rhs, sim_c = (simulated[key] for key in ("v", "raw", "scaled", "rhs", "c"))
|
|
||||||
|
|
||||||
ref_score_transpose = np.swapaxes(ref_scaled, -1, -2)
|
|
||||||
sim_score_transpose = np.swapaxes(sim_scaled, -1, -2)
|
|
||||||
ref_ss_f32 = f32_matmul(ref_v, ref_rhs)
|
|
||||||
sim_ss_f32 = f32_matmul(sim_v, sim_rhs)
|
|
||||||
ref_ss_f64 = f64_matmul(ref_v, ref_rhs)
|
|
||||||
sim_ss_f64 = f64_matmul(sim_v, sim_rhs)
|
|
||||||
ref_split_f32 = (f32_matmul(ref_v, np.swapaxes(ref_raw, -1, -2)) * scale).astype(np.float32)
|
|
||||||
sim_split_f32 = (f32_matmul(sim_v, np.swapaxes(sim_raw, -1, -2)) * scale).astype(np.float32)
|
|
||||||
ref_split_f64 = f64_matmul(ref_v, np.swapaxes(ref_raw, -1, -2)) * np.float64(scale)
|
|
||||||
sim_split_f64 = f64_matmul(sim_v, np.swapaxes(sim_raw, -1, -2)) * np.float64(scale)
|
|
||||||
|
|
||||||
arrays = {
|
|
||||||
**{f"ref_{key}": value for key, value in reference.items()},
|
|
||||||
**{f"sim_{key}": value for key, value in simulated.items()},
|
|
||||||
"ref_ss_f32": ref_ss_f32,
|
|
||||||
"sim_ss_f32": sim_ss_f32,
|
|
||||||
"ref_ss_f64": ref_ss_f64,
|
|
||||||
"sim_ss_f64": sim_ss_f64,
|
|
||||||
"ref_split_f32": ref_split_f32,
|
|
||||||
"sim_split_f32": sim_split_f32,
|
|
||||||
"ref_split_f64": ref_split_f64,
|
|
||||||
"sim_split_f64": sim_split_f64,
|
|
||||||
}
|
|
||||||
arrays_path = args.output_dir / "arrays.npz"
|
|
||||||
np.savez_compressed(arrays_path, **arrays)
|
|
||||||
|
|
||||||
metrics = {
|
|
||||||
"validator_policy": {
|
|
||||||
"absolute_tolerance": ABSOLUTE_TOLERANCE,
|
|
||||||
"relative_tolerance": RELATIVE_TOLERANCE,
|
|
||||||
},
|
|
||||||
"scale": float(scale),
|
|
||||||
"shape": list(ref_c.shape),
|
|
||||||
"tap_differences": {key: metric(simulated[key], reference[key]) for key in TAP_NAMES},
|
|
||||||
"rhs_transpose_consistency": metric(ref_rhs, ref_score_transpose),
|
|
||||||
"sim_rhs_transpose_consistency": metric(sim_rhs, sim_score_transpose),
|
|
||||||
"c_sim_vs_ss_f32": metric(sim_c, ref_ss_f32),
|
|
||||||
"c_ref_vs_ss_f32": metric(ref_c, ref_ss_f32),
|
|
||||||
"c_sim_vs_simulated_inputs_ss_f32": metric(sim_c, sim_ss_f32),
|
|
||||||
"v_drift_only": metric(f32_matmul(sim_v, ref_rhs), ref_ss_f32),
|
|
||||||
"rhs_drift_only": metric(f32_matmul(ref_v, sim_rhs), ref_ss_f32),
|
|
||||||
"joint_input_drift": metric(sim_ss_f32, ref_ss_f32),
|
|
||||||
"scale_reassociation_reference": metric(ref_split_f32, ref_ss_f32),
|
|
||||||
"scale_reassociation_simulated": metric(sim_split_f32, sim_ss_f32),
|
|
||||||
"reference_accumulation_f32_vs_f64": metric(ref_ss_f32, ref_ss_f64),
|
|
||||||
"simulated_accumulation_f32_vs_f64": metric(sim_ss_f32, sim_ss_f64),
|
|
||||||
"split_accumulation_reference_f32_vs_f64": metric(ref_split_f32, ref_split_f64),
|
|
||||||
"split_accumulation_simulated_f32_vs_f64": metric(sim_split_f32, sim_split_f64),
|
|
||||||
}
|
|
||||||
decomposition_path = args.output_dir / "decomposition.json"
|
|
||||||
decomposition_path.write_text(json.dumps(metrics, indent=2) + "\n", encoding="utf-8")
|
|
||||||
|
|
||||||
metadata = {
|
|
||||||
"model": str(args.model),
|
|
||||||
"model_sha256": sha256(args.model),
|
|
||||||
"workspace": str(args.workspace),
|
|
||||||
"arrays_sha256": sha256(arrays_path),
|
|
||||||
"source_sha256": {key: sha256(path) for key, path in source_files.items()},
|
|
||||||
"simulator_output_sha256": sha256(args.workspace / "simulation" / "out.bin"),
|
|
||||||
"input_sha256": sha256(args.workspace / "inputs" / "in0.csv"),
|
|
||||||
"outputs": TAP_NAMES,
|
|
||||||
"arrays": {key: {"dtype": str(value.dtype), "shape": list(value.shape)} for key, value in arrays.items()},
|
|
||||||
}
|
|
||||||
(args.output_dir / "metadata.json").write_text(json.dumps(metadata, indent=2) + "\n", encoding="utf-8")
|
|
||||||
print(json.dumps(metrics, indent=2))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user