restore unwanted changes
Validate Operations / validate-operations (push) Waiting to run

This commit is contained in:
NiccoloN
2026-08-06 14:52:55 +02:00
parent 42c236b6a5
commit 4acd3b0c81
15 changed files with 172 additions and 1929 deletions
@@ -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
@@ -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
-63
View File
@@ -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
-2
View File
@@ -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
@@ -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 model raptor_latency_ms pimcomp_latency_ms raptor_energy_pj pimcomp_energy_pj faster_compiler speedup
2 vgg8 1.521060 1.465778 7.985074 486309111.040001 477298145.040001 1597904071.120000 raptor 5.25 5.45
3 resnet18 33.552733 28.099952 58.853613 58.853733 9702508727.119982 8781611766.119984 13983148468.119974 13983168748.119974 raptor 1.75 2.09
4 resnet34 45.781486 91.607980 14962940227.679951 22722922369.680016 raptor 2.00
5 googlenet 13.371204 62.923463 6117835798.919991 14547526780.240000 raptor 4.71
+168 -177
View File
@@ -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 Operation Result Compile Host mem Cores mem Cores Xbars Latency Power Energy
2 add/after_gemm PASS - 0.063 s 0.01 MiB 0.01 MiB 5 4 0.007784 ms SKIP 104.703618 mW SKIP 815012.960000 pJ SKIP
3 add/basic PASS - 0.057 s 0.00 MiB 0.00 MiB 1 0 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
4 add/broadcast_row PASS - 0.057 s 0.00 MiB 0.00 MiB 1 0 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
5 add/channel_broadcast_1024 PASS - 0.061 s 0.02 MiB 0.01 MiB 1 0 0.006913 ms SKIP 78.118038 mW SKIP 540030.000000 pJ SKIP
6 add/leading_dimension_broadcast PASS - 0.057 s 0.00 MiB 0.00 MiB 1 0 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
7 concat/channel_axis PASS - 0.069 s 0.00 MiB 0.00 MiB 1 0 0.000457 ms SKIP 78.157549 mW SKIP 35718.000000 pJ SKIP
8 concat/negative_axis PASS - 0.061 s 0.00 MiB 0.00 MiB 1 0 0.001043 ms SKIP 78.092042 mW SKIP 81450.000000 pJ SKIP
9 concat/three_inputs_channel_axis PASS - 0.058 s 0.00 MiB 0.00 MiB 1 0 0.000644 ms SKIP 78.149068 mW SKIP 50328.000000 pJ SKIP
10 conv/batch_2 PASS - 0.066 s 0.00 MiB 0.00 MiB 2 2 0.013694 ms SKIP 82.623885 mW SKIP 1131451.480000 pJ SKIP
11 conv/batch_4_pointwise PASS - 0.065 s 0.00 MiB 0.01 MiB 5 4 0.003932 ms SKIP 116.078576 mW SKIP 456420.960000 pJ SKIP
12 conv/conv_1x3x224x224_w64x3x7x7_b64 conv/depthwise_1024_channels PASS - 0.083 s 24.14 MiB 0.19 MiB 61.87 MiB 0.38 MiB 168 129 169 128 38.414551 ms SKIP 185.256473 mW SKIP 7116544212.120002 pJ SKIP
13 conv/depthwise_1024_channels conv/depthwise_grouped PASS - 0.071 s 0.19 MiB 0.01 MiB 0.38 MiB 0.00 MiB 129 5 128 4 0.220751 ms SKIP 178.454307 mW SKIP 39393966.720000 pJ SKIP
14 conv/depthwise_grouped conv/dilated_3x3 PASS - 0.068 s 0.01 MiB 0.00 MiB 0.01 MiB 5 10 4 9 0.006234 ms SKIP 107.776541 mW SKIP 671878.960000 pJ SKIP
15 conv/dilated_3x3 conv/dynamic PASS - 0.065 s 0.01 MiB 0.00 MiB 0.01 MiB 0.00 MiB 10 5 9 0 0.008713 ms SKIP 118.767263 mW SKIP 1034819.160000 pJ SKIP
16 conv/dynamic conv/explicit_padding PASS - 0.062 s 0.00 MiB 0.01 MiB 0.00 MiB 0.02 MiB 5 17 0 16 0.001835 ms SKIP 92.281199 mW SKIP 169336.000000 pJ SKIP
17 conv/explicit_padding conv/grouped_many_groups PASS - 0.442 s 0.01 MiB 0.05 MiB 0.02 MiB 0.09 MiB 17 65 16 64 0.010007 ms SKIP 145.338047 mW SKIP 1454397.840000 pJ SKIP
18 conv/grouped_many_groups conv/grouped_two_groups PASS - 0.060 s 0.05 MiB 0.00 MiB 0.09 MiB 0.00 MiB 65 3 64 2 0.181897 ms SKIP 142.207471 mW SKIP 25867112.360000 pJ SKIP
19 conv/grouped_two_groups conv/huge_pointwise_1024 PASS - 0.156 s 0.00 MiB 0.01 MiB 0.00 MiB 0.11 MiB 3 73 2 64 0.005361 ms SKIP 101.457653 mW SKIP 543914.480000 pJ SKIP
20 conv/huge_pointwise_1024 conv/huge_pointwise_1024_dynamic PASS - 0.079 s 0.01 MiB 8.04 MiB 0.11 MiB 12.61 MiB 73 168 64 0 0.015615 ms SKIP 249.545140 mW SKIP 3896647.360000 pJ SKIP
21 conv/huge_pointwise_1024_dynamic conv/kernel_3x3 PASS - 0.062 s 8.04 MiB 0.01 MiB 12.61 MiB 0.01 MiB 168 10 0 9 2.627964 ms SKIP 169.518697 mW SKIP 445489032.000000 pJ SKIP
22 conv/kernel_3x3 conv/kernel_equals_input_spatial PASS - 0.064 s 0.01 MiB 0.00 MiB 0.01 MiB 0.00 MiB 10 2 9 2 0.007186 ms SKIP 123.801859 mW SKIP 889640.160000 pJ SKIP
23 conv/kernel_equals_input_spatial conv/large_input_channels_1x1 PASS - 0.089 s 0.00 MiB 0.01 MiB 0.00 MiB 0.02 MiB 2 9 2 8 0.004639 ms SKIP 89.607562 mW SKIP 415689.480000 pJ SKIP
24 conv/large_input_channels_1x1 conv/large_output_channels_1x1 PASS - 0.098 s 0.01 MiB 0.02 MiB 9 17 8 0.007648 ms SKIP 117.824519 mW SKIP 901121.920000 pJ SKIP
25 conv/large_output_channels_1x1 conv/large_spatial PASS - 0.069 s 0.01 MiB 0.02 MiB 0.04 MiB 17 37 8 36 0.008871 ms SKIP 128.442782 mW SKIP 1139415.920000 pJ SKIP
26 conv/large_spatial conv/multi_channel PASS - 0.066 s 0.01 MiB 0.00 MiB 0.04 MiB 0.00 MiB 37 4 36 3 0.017018 ms SKIP 172.073372 mW SKIP 2928344.640000 pJ SKIP
27 conv/multi_channel conv/non_square_kernel_1x3 PASS - 0.061 s 0.00 MiB 0.00 MiB 4 3 3 2 0.006482 ms SKIP 105.683542 mW SKIP 685040.720000 pJ SKIP
28 conv/non_square_kernel_1x3 conv/non_square_kernel_3x1 PASS - 0.064 s 0.00 MiB 0.00 MiB 3 2 0.006842 ms SKIP 99.349968 mW SKIP 679752.480000 pJ SKIP
29 conv/non_square_kernel_3x1 conv/non_uniform_stride PASS - 0.062 s 0.00 MiB 0.00 MiB 3 4 2 3 0.013484 ms SKIP 95.889683 mW SKIP 1292976.480000 pJ SKIP
30 conv/non_uniform_stride conv/pointwise_1x1 PASS - 0.059 s 0.00 MiB 0.00 MiB 4 1 3 1 0.007601 ms SKIP 104.048772 mW SKIP 790874.720000 pJ SKIP
31 conv/output_channel_grouping_minimal conv/pointwise_tiled_chain PASS - 0.604 s 0.10 MiB 0.01 MiB 0.34 MiB 0.04 MiB 131 20 128 80 0.258453 ms SKIP 170.730913 mW SKIP 44125916.720000 pJ SKIP
32 conv/pointwise_1x1 conv/real_asymmetric_padding PASS - 0.060 s 0.00 MiB 0.01 MiB 0.00 MiB 0.03 MiB 1 29 1 28 0.012303 ms SKIP 80.244188 mW SKIP 987244.240000 pJ SKIP
33 conv/pointwise_tiled_chain conv/relu_conv_store PASS - 0.091 s 0.01 MiB 0.16 MiB 0.04 MiB 0.67 MiB 20 168 80 184 0.041886 ms SKIP 153.880896 mW SKIP 6445455.200000 pJ SKIP
34 conv/real_asymmetric_padding conv/same_lower_3x3 PASS - 0.078 s 0.01 MiB 0.03 MiB 0.02 MiB 29 26 28 25 0.014457 ms SKIP 153.669968 mW SKIP 2221606.720000 pJ SKIP
35 conv/relu_conv_store conv/same_padding_3x3 PASS - 0.070 s 0.16 MiB 0.01 MiB 0.67 MiB 0.02 MiB 168 26 184 25 0.562898 ms SKIP 183.084489 mW SKIP 103057892.800000 pJ SKIP
36 conv/same_lower_3x3 conv/simple PASS - 0.064 s 0.01 MiB 0.00 MiB 0.02 MiB 0.00 MiB 26 1 25 1 0.013331 ms SKIP 166.154752 mW SKIP 2215009.000000 pJ SKIP
37 conv/same_padding_3x3 conv/stride_2 PASS - 0.064 s 0.01 MiB 0.02 MiB 0.00 MiB 26 5 25 4 0.013331 ms SKIP 166.154752 mW SKIP 2215009.000000 pJ SKIP
38 conv/simple conv/with_bias_3x3 PASS - 0.067 s 0.00 MiB 0.00 MiB 0.01 MiB 1 4 1 3 0.004301 ms SKIP 83.833583 mW SKIP 360568.240000 pJ SKIP
39 conv/strategy_depthwise_16 conv/with_constant PASS - 0.070 s 0.06 MiB 0.00 MiB 0.35 MiB 0.00 MiB 168 1 168 1 0.335115 ms SKIP 197.936467 mW SKIP 66331479.080000 pJ SKIP
40 conv/strategy_input_k_tiled conv/without_kernel_shape_attr PASS - 0.069 s 0.08 MiB 0.01 MiB 0.27 MiB 0.01 MiB 109 10 108 9 0.353736 ms SKIP 170.812713 mW SKIP 60422605.920000 pJ SKIP
41 conv/strategy_output_channel_tiled conv/yolo11n_depthwise_head PASS - 1.482 s 0.03 MiB 8.66 MiB 0.16 MiB 34.24 MiB 74 168 72 255 0.091463 ms SKIP 155.743189 mW SKIP 14244739.280000 pJ SKIP
42 conv/strategy_streamed_packed conv/yolo11n_heavy PASS - 0.431 s 3.34 MiB 4.82 MiB 7.89 MiB 19.10 MiB 168 161 168 800 9.353833 ms SKIP 179.858301 mW SKIP 1682364509.560000 pJ SKIP
43 conv/strategy_streamed_patch conv/yolo11n_stem PASS - 0.783 s 0.34 MiB 12.86 MiB 1.32 MiB 37.59 MiB 168 168 488 1.904655 ms SKIP 181.910449 mW SKIP 346476645.640000 pJ SKIP
44 conv/strategy_tiled_2d div/after_gemm PASS - 0.072 s 0.11 MiB 0.01 MiB 0.44 MiB 0.01 MiB 168 5 168 4 0.415594 ms SKIP 182.127047 mW SKIP 75690907.840000 pJ SKIP
45 conv/stride_2 div/basic PASS - 0.061 s 0.01 MiB 0.00 MiB 0.00 MiB 5 1 4 0 0.005237 ms SKIP 110.780019 mW SKIP 580154.960000 pJ SKIP
46 conv/with_bias_3x3 div/channel_broadcast_1024 PASS - 0.066 s 0.00 MiB 0.02 MiB 0.01 MiB 4 1 3 0 0.007452 ms SKIP 104.162738 mW SKIP 776220.720000 pJ SKIP
47 conv/with_constant div/leading_dimension_broadcast PASS - 0.059 s 0.00 MiB 0.00 MiB 1 1 0 0.006622 ms SKIP 81.738182 mW SKIP 541270.240000 pJ SKIP
48 conv/without_kernel_shape_attr div/runtime_scalar_rhs PASS - 0.056 s 0.01 MiB 0.02 MiB 0.01 MiB 10 1 9 0 0.007186 ms SKIP 123.801859 mW SKIP 889640.160000 pJ SKIP
49 conv/yolo11n_depthwise_head div/scalar_constant PASS - 0.073 s 8.66 MiB 0.00 MiB 34.24 MiB 0.00 MiB 168 1 255 0 42.701404 ms SKIP 200.519161 mW SKIP 8562449708.000010 pJ SKIP
50 conv/yolo11n_heavy gather/3d_input_axis1 PASS - 0.060 s 4.82 MiB 0.00 MiB 19.10 MiB 0.00 MiB 161 1 800 0 8.535404 ms SKIP 350.863768 mW SKIP 2994764012.000010 pJ SKIP
51 conv/yolo11n_stem gather/axis0_matrix_indices PASS - 0.056 s 12.86 MiB 0.00 MiB 37.59 MiB 0.00 MiB 168 1 488 0 14.239985 ms SKIP 301.233376 mW SKIP 4289558753.000010 pJ SKIP
52 div/after_gemm gather/axis1 PASS - 0.058 s 0.01 MiB 0.00 MiB 0.01 MiB 0.00 MiB 5 1 4 0 0.007784 ms SKIP 104.703618 mW SKIP 815012.960000 pJ SKIP
53 div/basic gather/negative_axis PASS - 0.058 s 0.00 MiB 0.00 MiB 1 0 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
54 div/channel_broadcast_1024 gather/negative_indices PASS - 0.063 s 0.02 MiB 0.00 MiB 0.01 MiB 0.00 MiB 1 0 0.006913 ms SKIP 78.118038 mW SKIP 540030.000000 pJ SKIP
55 div/leading_dimension_broadcast gemm/alpha_beta PASS - 0.067 s 0.00 MiB 0.01 MiB 0.00 MiB 0.01 MiB 1 5 0 4 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
56 div/runtime_scalar_rhs gemm/bias_rank2_broadcast PASS - 0.060 s 0.02 MiB 0.00 MiB 0.01 MiB 1 5 0 4 0.006913 ms SKIP 78.118038 mW SKIP 540030.000000 pJ SKIP
57 div/scalar_constant gemm/dynamic PASS - 0.064 s 0.00 MiB 0.00 MiB 1 5 0 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
58 gather/3d_input_axis1 gemm/dynamic_alpha PASS - 0.062 s 0.00 MiB 0.00 MiB 1 5 0 0.000589 ms SKIP 78.081494 mW SKIP 45990.000000 pJ SKIP
59 gather/axis0_matrix_indices gemm/dynamic_beta PASS - 0.060 s 0.00 MiB 0.00 MiB 1 5 0 0.000697 ms SKIP 78.068867 mW SKIP 54414.000000 pJ SKIP
60 gather/axis1 gemm/dynamic_bias PASS - 0.058 s 0.00 MiB 0.00 MiB 1 5 0 0.000801 ms SKIP 78.059925 mW SKIP 62526.000000 pJ SKIP
61 gather/negative_axis gemm/dynamic_bias_alpha_beta PASS - 0.067 s 0.00 MiB 0.00 MiB 1 5 0 0.001437 ms SKIP 78.033403 mW SKIP 112134.000000 pJ SKIP
62 gather/negative_indices gemm/dynamic_transB PASS - 0.062 s 0.00 MiB 0.00 MiB 1 5 0 0.000376 ms SKIP 78.127660 mW SKIP 29376.000000 pJ SKIP
63 gemm/alpha_beta gemm/huge_1024 PASS - 0.147 s 0.01 MiB 0.01 MiB 0.10 MiB 5 73 4 64 0.007456 ms SKIP 105.272125 mW SKIP 784908.960000 pJ SKIP
64 gemm/bias_rank2_broadcast gemm/large PASS - 0.068 s 0.00 MiB 0.02 MiB 0.01 MiB 0.03 MiB 5 17 4 16 0.007072 ms SKIP 105.979208 mW SKIP 749484.960000 pJ SKIP
65 gemm/dynamic gemm/large_k_small_n PASS - 0.095 s 0.00 MiB 0.01 MiB 0.00 MiB 0.01 MiB 5 9 0 8 0.002421 ms SKIP 91.480793 mW SKIP 221475.000000 pJ SKIP
66 gemm/dynamic_alpha gemm/non_square PASS - 0.063 s 0.00 MiB 0.00 MiB 0.01 MiB 5 0 4 0.003262 ms SKIP 91.415696 mW SKIP 298198.000000 pJ SKIP
67 gemm/dynamic_beta gemm/scalar_bias PASS - 0.060 s 0.00 MiB 0.00 MiB 0.01 MiB 5 0 4 0.004365 ms SKIP 91.316151 mW SKIP 398595.000000 pJ SKIP
68 gemm/dynamic_bias gemm/simple PASS - 0.072 s 0.00 MiB 0.03 MiB 0.00 MiB 0.08 MiB 5 42 0 40 0.002665 ms SKIP 91.445779 mW SKIP 243703.000000 pJ SKIP
69 gemm/dynamic_bias_alpha_beta gemm/small PASS - 0.065 s 0.00 MiB 0.00 MiB 5 2 0 2 0.005629 ms SKIP 91.279268 mW SKIP 513811.000000 pJ SKIP
70 gemm/dynamic_transB gemm/small_k_large_n PASS - 0.097 s 0.00 MiB 0.01 MiB 0.00 MiB 0.02 MiB 5 17 0 8 0.001301 ms SKIP 91.378171 mW SKIP 118883.000000 pJ SKIP
71 gemm/huge_1024 gemm/transA PASS - 0.064 s 0.01 MiB 0.00 MiB 0.10 MiB 0.01 MiB 73 5 64 4 0.017522 ms SKIP 215.037402 mW SKIP 3767885.360000 pJ SKIP
72 gemm/large gemm/transA_transB PASS - 0.069 s 0.02 MiB 0.00 MiB 0.03 MiB 0.01 MiB 17 5 16 4 0.011229 ms SKIP 140.152181 mW SKIP 1573768.840000 pJ SKIP
73 gemm/large_k_small_n gemm/transB PASS - 0.062 s 0.01 MiB 0.00 MiB 0.01 MiB 9 5 8 4 0.004748 ms SKIP 133.481449 mW SKIP 633769.920000 pJ SKIP
74 gemm/non_square gemm/transB_with_bias PASS - 0.055 s 0.00 MiB 0.01 MiB 0.01 MiB 5 4 0.003527 ms SKIP 118.958310 mW SKIP 419565.960000 pJ SKIP
75 gemm/scalar_bias gemm/with_bias PASS - 0.067 s 0.00 MiB 0.01 MiB 0.01 MiB 5 4 0.007072 ms SKIP 105.979208 mW SKIP 749484.960000 pJ SKIP
76 gemm/simple gemv/constant PASS - 0.064 s 0.03 MiB 0.00 MiB 0.08 MiB 0.00 MiB 42 0 40 0 0.021640 ms SKIP 151.774196 mW SKIP 3284393.600000 pJ SKIP
77 gemm/small gemv/simple PASS - 0.069 s 0.00 MiB 0.00 MiB 0.01 MiB 2 6 2 4 0.004420 ms SKIP 90.144000 mW SKIP 398436.480000 pJ SKIP
78 gemm/small_k_large_n gemv/with_heterogeneous_constant PASS - 0.066 s 0.01 MiB 0.00 MiB 0.02 MiB 0.01 MiB 17 6 8 4 0.007962 ms SKIP 131.005014 mW SKIP 1043061.920000 pJ SKIP
79 gemm/transA gemv/with_homogeneous_constant PASS - 0.070 s 0.00 MiB 0.01 MiB 5 6 4 0.005762 ms SKIP 109.140743 mW SKIP 628868.960000 pJ SKIP
80 gemm/transA_transB gemv/with_scalar_constant PASS - 0.070 s 0.00 MiB 0.01 MiB 5 6 4 0.005762 ms SKIP 109.140743 mW SKIP 628868.960000 pJ SKIP
81 gemm/transB matmul/basic PASS - 0.062 s 0.00 MiB 0.01 MiB 0.00 MiB 5 2 4 2 0.003527 ms SKIP 118.958310 mW SKIP 419565.960000 pJ SKIP
82 gemm/transB_with_bias matmul/batched_3d PASS - 0.066 s 0.01 MiB 0.00 MiB 0.01 MiB 5 4 0.005046 ms SKIP 110.546762 mW SKIP 557818.960000 pJ SKIP
83 gemm/with_bias matmul/batched_3d_dynamic PASS - 0.057 s 0.01 MiB 0.00 MiB 0.01 MiB 0.00 MiB 5 4 4 0 0.005562 ms SKIP 108.767882 mW SKIP 604966.960000 pJ SKIP
84 gemv/constant matmul/batched_left_constant PASS - 0.070 s 0.00 MiB 0.00 MiB 0.02 MiB 0 9 0 8 0.000000 ms SKIP 2.000000 mW SKIP 0.000000 pJ SKIP
85 gemv/simple matmul/batched_lhs_broadcast PASS - 0.063 s 0.00 MiB 0.01 MiB 6 5 4 0.005160 ms SKIP 111.150380 mW SKIP 573535.960000 pJ SKIP
86 gemv/with_heterogeneous_constant matmul/batched_rhs_broadcast PASS - 0.062 s 0.00 MiB 0.01 MiB 6 5 4 0.005549 ms SKIP 109.816536 mW SKIP 609371.960000 pJ SKIP
87 gemv/with_homogeneous_constant matmul/dynamic PASS - 0.060 s 0.00 MiB 0.01 MiB 0.00 MiB 6 5 4 0 0.005549 ms SKIP 109.816536 mW SKIP 609371.960000 pJ SKIP
88 gemv/with_scalar_constant matmul/huge_1024 PASS - 0.145 s 0.00 MiB 0.01 MiB 0.01 MiB 0.10 MiB 6 73 4 64 0.005549 ms SKIP 109.816536 mW SKIP 609371.960000 pJ SKIP
89 matmul/basic matmul/left_constant PASS - 0.051 s 0.00 MiB 0.00 MiB 0.01 MiB 2 5 2 4 0.004420 ms SKIP 90.144000 mW SKIP 398436.480000 pJ SKIP
90 matmul/batched_3d matmul/matrix_vector PASS - 0.095 s 0.00 MiB 0.52 MiB 0.01 MiB 0.78 MiB 5 168 4 173 0.005958 ms SKIP 108.588949 mW SKIP 646972.960000 pJ SKIP
91 matmul/batched_3d_dynamic matmul/vector_matrix PASS - 0.087 s 0.00 MiB 0.01 MiB 0.00 MiB 0.01 MiB 4 9 0 8 0.001822 ms SKIP 92.192645 mW SKIP 167975.000000 pJ SKIP
92 matmul/batched_left_constant matmul/yolo_attention PASS - 0.385 s 0.00 MiB 1.02 MiB 0.02 MiB 43.44 MiB 9 168 8 0 0.008822 ms SKIP 114.385164 mW SKIP 1009105.920000 pJ SKIP
93 matmul/batched_lhs_broadcast mul/after_conv PASS - 0.055 s 0.00 MiB 0.01 MiB 0.00 MiB 5 4 4 3 0.005681 ms SKIP 109.389361 mW SKIP 621440.960000 pJ SKIP
94 matmul/batched_rhs_broadcast mul/basic PASS - 0.055 s 0.00 MiB 0.01 MiB 0.00 MiB 5 1 4 0 0.005958 ms SKIP 108.588949 mW SKIP 646972.960000 pJ SKIP
95 matmul/dynamic mul/channel_broadcast_1024 PASS - 0.058 s 0.00 MiB 0.02 MiB 0.00 MiB 0.01 MiB 5 1 0 0.001621 ms SKIP 91.421962 mW SKIP 148195.000000 pJ SKIP
96 matmul/huge_1024 mul/leading_dimension_broadcast PASS - 0.059 s 0.01 MiB 0.00 MiB 0.10 MiB 0.00 MiB 73 1 64 0 0.017522 ms SKIP 215.037402 mW SKIP 3767885.360000 pJ SKIP
97 matmul/left_constant mul/scalar_constant PASS - 0.056 s 0.00 MiB 0.01 MiB 0.00 MiB 5 1 4 0 0.005853 ms SKIP 108.861944 mW SKIP 637168.960000 pJ SKIP
98 matmul/matrix_vector pool/avg_basic PASS - 0.063 s 0.52 MiB 0.00 MiB 0.78 MiB 0.00 MiB 168 1 173 0 0.384660 ms SKIP 202.131271 mW SKIP 77751814.880000 pJ SKIP
99 matmul/vector_matrix pool/avg_ceil_mode PASS - 0.063 s 0.01 MiB 0.00 MiB 0.01 MiB 0.00 MiB 9 1 8 0 0.007409 ms SKIP 118.680243 mW SKIP 879301.920000 pJ SKIP
100 matmul/yolo_attention pool/avg_explicit_padding PASS - 0.061 s 1.02 MiB 0.00 MiB 43.44 MiB 0.00 MiB 168 1 0 8.151445 ms SKIP 170.003707 mW SKIP 1385775865.000000 pJ SKIP
101 mul/after_conv pool/avg_include_pad PASS - 0.049 s 0.00 MiB 0.00 MiB 4 1 3 0 0.005453 ms SKIP 107.639046 mW SKIP 586955.720000 pJ SKIP
102 mul/after_conv_scalar_constant pool/avg_large_channels PASS - 0.059 s 0.00 MiB 0.04 MiB 0.00 MiB 0.02 MiB 4 1 3 0 0.005453 ms SKIP 107.639046 mW SKIP 586955.720000 pJ SKIP
103 mul/basic pool/avg_non_uniform_stride PASS - 0.066 s 0.00 MiB 0.00 MiB 1 0 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
104 mul/channel_broadcast_1024 pool/avg_real_asymmetric_padding PASS - 0.055 s 0.02 MiB 0.00 MiB 0.01 MiB 0.00 MiB 1 0 0.006913 ms SKIP 78.118038 mW SKIP 540030.000000 pJ SKIP
105 mul/leading_dimension_broadcast pool/max_after_conv PASS - 0.069 s 0.00 MiB 0.00 MiB 1 5 0 4 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
106 mul/scalar_constant pool/max_basic PASS - 0.064 s 0.00 MiB 0.00 MiB 1 0 0.000323 ms SKIP 78.222910 mW SKIP 25266.000000 pJ SKIP
107 pool/avg_basic pool/max_ceil_mode PASS - 0.058 s 0.00 MiB 0.00 MiB 1 0 0.011939 ms SKIP 78.022112 mW SKIP 931506.000000 pJ SKIP
108 pool/avg_ceil_mode pool/max_global_style_kernel_equals_input PASS - 0.063 s 0.00 MiB 0.00 MiB 1 0 0.004359 ms SKIP 78.033035 mW SKIP 340146.000000 pJ SKIP
109 pool/avg_explicit_padding pool/max_non_square_kernel PASS - 0.067 s 0.00 MiB 0.00 MiB 1 0 0.008822 ms SKIP 78.027205 mW SKIP 688356.000000 pJ SKIP
110 pool/avg_include_pad pool/max_real_asymmetric_padding PASS - 0.063 s 0.00 MiB 0.00 MiB 1 0 0.008506 ms SKIP 78.016929 mW SKIP 663612.000000 pJ SKIP
111 pool/avg_large_channels pool/max_same_upper PASS - 0.061 s 0.04 MiB 0.00 MiB 0.02 MiB 0.00 MiB 1 0 0.235874 ms SKIP 78.004172 mW SKIP 18399156.000000 pJ SKIP
112 pool/avg_non_uniform_stride pool/max_stride2_multichannel PASS - 0.076 s 0.00 MiB 0.00 MiB 1 0 0.014513 ms SKIP 78.016537 mW SKIP 1132254.000000 pJ SKIP
113 pool/avg_real_asymmetric_padding reduce_mean/4d_spatial PASS - 0.058 s 0.00 MiB 0.00 MiB 1 3 0 0.025206 ms SKIP 78.024756 mW SKIP 1966692.000000 pJ SKIP
114 pool/max_after_conv reduce_mean/4d_spatial_keepdims_0 PASS - 0.068 s 0.00 MiB 0.00 MiB 5 4 4 0 0.012215 ms SKIP 99.115019 mW SKIP 1210689.960000 pJ SKIP
115 pool/max_basic reduce_mean/after_conv PASS - 0.067 s 0.00 MiB 0.00 MiB 1 5 0 3 0.004160 ms SKIP 78.063462 mW SKIP 324744.000000 pJ SKIP
116 pool/max_ceil_mode reduce_mean/all_axes_keepdims_0 PASS - 0.057 s 0.00 MiB 0.00 MiB 1 2 0 0.001940 ms SKIP 78.074227 mW SKIP 151464.000000 pJ SKIP
117 pool/max_global_style_kernel_equals_input reduce_mean/all_axes_keepdims_1 PASS - 0.053 s 0.00 MiB 0.00 MiB 1 0 0.008443 ms SKIP 78.008528 mW SKIP 658626.000000 pJ SKIP
118 pool/max_non_square_kernel reduce_mean/basic PASS - 0.058 s 0.00 MiB 0.00 MiB 1 4 0 0.013626 ms SKIP 78.017613 mW SKIP 1063068.000000 pJ SKIP
119 pool/max_real_asymmetric_padding reduce_mean/channel_axis_nchw PASS - 0.063 s 0.00 MiB 0.03 MiB 0.00 MiB 0.02 MiB 1 4 0 0.010444 ms SKIP 78.034470 mW SKIP 814992.000000 pJ SKIP
120 pool/max_same_upper reduce_mean/keepdims_0 PASS - 0.064 s 0.00 MiB 0.00 MiB 1 5 0 0.008010 ms SKIP 78.035955 mW SKIP 625068.000000 pJ SKIP
121 pool/max_stride2_multichannel reduce_mean/large_dimension_1024 PASS - 0.066 s 0.00 MiB 0.01 MiB 0.00 MiB 1 0 0.015987 ms SKIP 78.018015 mW SKIP 1247274.000000 pJ SKIP
122 reduce_mean/4d_spatial reduce_mean/legacy_axes_1_2_keepdims_1 PASS - 0.069 s 0.00 MiB 0.00 MiB 3 2 0 0.000321 ms SKIP 92.448598 mW SKIP 29676.000000 pJ SKIP
123 reduce_mean/4d_spatial_keepdims_0 reduce_mean/legacy_axis1_keepdims_0 PASS - 0.067 s 0.00 MiB 0.00 MiB 4 9 0 0.000655 ms SKIP 94.352672 mW SKIP 61801.000000 pJ SKIP
124 reduce_mean/after_conv reduce_mean/legacy_axis1_keepdims_1 PASS - 0.057 s 0.00 MiB 0.00 MiB 5 8 3 0 0.005342 ms SKIP 106.951089 mW SKIP 571332.720000 pJ SKIP
125 reduce_mean/all_axes_keepdims_0 reduce_mean/legacy_empty_axes_noop PASS - 0.058 s 0.00 MiB 0.00 MiB 2 1 0 0.000391 ms SKIP 79.237852 mW SKIP 30982.000000 pJ SKIP
126 reduce_mean/all_axes_keepdims_1 reduce_mean/legacy_nchw_spatial PASS - 0.059 s 0.00 MiB 0.00 MiB 1 3 0 0.000221 ms SKIP 78.217195 mW SKIP 17286.000000 pJ SKIP
127 reduce_mean/basic reduce_mean/legacy_negative_axis PASS - 0.052 s 0.00 MiB 0.00 MiB 4 6 0 0.000373 ms SKIP 93.514745 mW SKIP 34881.000000 pJ SKIP
128 reduce_mean/channel_axis_nchw reduce_mean/legacy_reduce_all_keepdims_1 PASS - 0.057 s 0.03 MiB 0.00 MiB 0.02 MiB 0.00 MiB 4 1 0 0.164926 ms SKIP 93.596631 mW SKIP 15436518.000000 pJ SKIP
129 reduce_mean/keepdims_0 reduce_mean/negative_axis PASS - 0.055 s 0.00 MiB 0.00 MiB 5 6 0 0.000748 ms SKIP 91.401070 mW SKIP 68368.000000 pJ SKIP
130 reduce_mean/large_dimension_1024 relu/4d PASS - 0.059 s 0.01 MiB 0.00 MiB 0.00 MiB 1 0 0.002785 ms SKIP 78.017235 mW SKIP 217278.000000 pJ SKIP
131 reduce_mean/legacy_axes_1_2_keepdims_1 relu/after_conv PASS - 0.062 s 0.00 MiB 0.00 MiB 2 4 0 3 0.000271 ms SKIP 79.354244 mW SKIP 21505.000000 pJ SKIP
132 reduce_mean/legacy_axis1_keepdims_0 relu/after_gemm PASS - 0.062 s 0.00 MiB 0.01 MiB 0.00 MiB 0.01 MiB 9 5 0 4 0.001986 ms SKIP 92.501511 mW SKIP 183708.000000 pJ SKIP
133 reduce_mean/legacy_axis1_keepdims_1 relu/basic PASS - 0.062 s 0.00 MiB 0.00 MiB 8 1 0 0.001373 ms SKIP 94.559359 mW SKIP 129830.000000 pJ SKIP
134 reduce_mean/legacy_empty_axes_noop reshape/4d_to_2d_flatten PASS - 0.059 s 0.00 MiB 0.00 MiB 1 0 0.000221 ms SKIP 78.217195 mW SKIP 17286.000000 pJ SKIP
135 reduce_mean/legacy_nchw_spatial reshape/infer_dim_minus_one PASS - 0.059 s 0.00 MiB 0.00 MiB 3 1 0 0.000321 ms SKIP 92.448598 mW SKIP 29676.000000 pJ SKIP
136 reduce_mean/legacy_negative_axis reshape/same_rank PASS - 0.056 s 0.00 MiB 0.00 MiB 6 1 0 0.000553 ms SKIP 93.520796 mW SKIP 51717.000000 pJ SKIP
137 reduce_mean/legacy_reduce_all_keepdims_1 reshape/zero_copies_input_dim PASS - 0.077 s 0.00 MiB 0.00 MiB 1 0 0.000221 ms SKIP 78.217195 mW SKIP 17286.000000 pJ SKIP
138 reduce_mean/negative_axis resize/height_only PASS - 0.059 s 0.00 MiB 0.00 MiB 6 4 0 0.000553 ms SKIP 93.520796 mW SKIP 51717.000000 pJ SKIP
139 relu/4d resize/nearest_2x PASS - 0.066 s 0.00 MiB 0.00 MiB 1 4 0 0.000521 ms SKIP 78.184261 mW SKIP 40734.000000 pJ SKIP
140 relu/after_conv resize/nearest_downsample PASS - 0.062 s 0.00 MiB 0.00 MiB 4 2 3 0 0.005352 ms SKIP 107.891951 mW SKIP 577437.720000 pJ SKIP
141 relu/after_gemm resize/non_uniform PASS - 0.069 s 0.01 MiB 0.00 MiB 0.01 MiB 0.00 MiB 5 6 4 0 0.007513 ms SKIP 105.158653 mW SKIP 790056.960000 pJ SKIP
142 relu/basic resize/width_only PASS - 0.055 s 0.00 MiB 0.00 MiB 1 2 0 0.000221 ms SKIP 78.217195 mW SKIP 17286.000000 pJ SKIP
143 reshape/4d_to_2d_flatten resize/with_sizes PASS - 0.060 s 0.00 MiB 0.00 MiB 1 3 0 0.000258 ms SKIP 78.279070 mW SKIP 20196.000000 pJ SKIP
144 reshape/infer_dim_minus_one sigmoid/4d PASS - 0.060 s 0.00 MiB 0.00 MiB 1 0 0.000162 ms SKIP 78.296296 mW SKIP 12684.000000 pJ SKIP
145 reshape/same_rank sigmoid/after_gemm PASS - 0.059 s 0.00 MiB 0.01 MiB 0.00 MiB 0.01 MiB 1 5 0 4 0.000162 ms SKIP 78.296296 mW SKIP 12684.000000 pJ SKIP
146 reshape/zero_copies_input_dim sigmoid/basic PASS - 0.053 s 0.00 MiB 0.00 MiB 1 0 0.000162 ms SKIP 78.296296 mW SKIP 12684.000000 pJ SKIP
147 resize/height_only slice/2d_basic PASS - 0.058 s 0.00 MiB 0.00 MiB 4 1 0 0.000693 ms SKIP 93.554113 mW SKIP 64833.000000 pJ SKIP
148 resize/nearest_2x slice/after_conv PASS - 0.070 s 0.00 MiB 0.00 MiB 0.01 MiB 4 7 0 6 0.001173 ms SKIP 93.572890 mW SKIP 109761.000000 pJ SKIP
149 resize/nearest_downsample slice/default_axes PASS - 0.066 s 0.00 MiB 0.00 MiB 2 1 0 0.000427 ms SKIP 79.449649 mW SKIP 33925.000000 pJ SKIP
150 resize/non_uniform slice/large_channel_1024 PASS - 0.064 s 0.00 MiB 0.01 MiB 0.00 MiB 6 1 0 0.001753 ms SKIP 93.575014 mW SKIP 164037.000000 pJ SKIP
151 resize/width_only slice/nchw_spatial_crop PASS - 0.055 s 0.00 MiB 0.00 MiB 2 1 0 0.000667 ms SKIP 79.503748 mW SKIP 53029.000000 pJ SKIP
152 resize/with_sizes slice/negative_axis PASS - 0.060 s 0.00 MiB 0.00 MiB 3 1 0 0.000797 ms SKIP 92.542033 mW SKIP 73756.000000 pJ SKIP
153 sigmoid/4d slice/negative_indices PASS - 0.053 s 0.00 MiB 0.00 MiB 1 0 0.000521 ms SKIP 78.184261 mW SKIP 40734.000000 pJ SKIP
154 sigmoid/after_gemm slice/step2 PASS - 0.058 s 0.01 MiB 0.00 MiB 0.01 MiB 0.00 MiB 5 1 4 0 0.007513 ms SKIP 105.158653 mW SKIP 790056.960000 pJ SKIP
155 sigmoid/basic softmax/3d_last_axis PASS - 0.050 s 0.00 MiB 0.00 MiB 1 0 0.000221 ms SKIP 78.217195 mW SKIP 17286.000000 pJ SKIP
156 slice/2d_basic softmax/basic PASS - 0.061 s 0.00 MiB 0.00 MiB 1 0 0.000242 ms SKIP 78.297521 mW SKIP 18948.000000 pJ SKIP
157 slice/after_conv softmax/channel_axis PASS - 0.058 s 0.00 MiB 0.01 MiB 0.00 MiB 7 1 6 0 0.011296 ms SKIP 118.190765 mW SKIP 1335082.880000 pJ SKIP
158 slice/default_axes softmax/large_dimension_1024 PASS - 0.061 s 0.00 MiB 0.01 MiB 0.00 MiB 0.01 MiB 1 0 0.000242 ms SKIP 78.297521 mW SKIP 18948.000000 pJ SKIP
159 slice/large_channel_1024 softmax/negative_axis PASS - 0.058 s 0.01 MiB 0.00 MiB 0.00 MiB 1 0 0.002832 ms SKIP 78.144068 mW SKIP 221304.000000 pJ SKIP
160 slice/nchw_spatial_crop split/basic PASS - 0.059 s 0.00 MiB 0.00 MiB 1 0 0.001302 ms SKIP 78.239631 mW SKIP 101868.000000 pJ SKIP
161 slice/negative_axis split/equal_three_way PASS - 0.063 s 0.00 MiB 0.00 MiB 1 0 0.000562 ms SKIP 78.298932 mW SKIP 44004.000000 pJ SKIP
162 slice/negative_indices split/negative_axis PASS - 0.059 s 0.00 MiB 0.00 MiB 1 0 0.000322 ms SKIP 78.298137 mW SKIP 25212.000000 pJ SKIP
163 slice/step2 split/uneven_channel_axis_4d PASS - 0.061 s 0.00 MiB 0.00 MiB 1 0 0.002042 ms SKIP 78.293830 mW SKIP 159876.000000 pJ SKIP
164 softmax/3d_last_axis sub/after_gemm PASS - 0.064 s 0.00 MiB 0.01 MiB 0.00 MiB 0.01 MiB 1 5 0 4 UNSUPPORTED SKIP UNSUPPORTED SKIP UNSUPPORTED SKIP
165 softmax/basic sub/basic PASS - 0.054 s 0.00 MiB 0.00 MiB 1 0 UNSUPPORTED SKIP UNSUPPORTED SKIP UNSUPPORTED SKIP
166 softmax/channel_axis sub/broadcast_row PASS - 0.064 s 0.00 MiB 0.00 MiB 1 0 UNSUPPORTED SKIP UNSUPPORTED SKIP UNSUPPORTED SKIP
167 softmax/large_dimension_1024 sub/channel_broadcast_1024 PASS - 0.063 s 0.01 MiB 0.02 MiB 0.01 MiB 1 0 UNSUPPORTED SKIP UNSUPPORTED SKIP UNSUPPORTED SKIP
168 softmax/negative_axis sub/constant_lhs_broadcast PASS - 0.054 s 0.00 MiB 0.00 MiB 1 0 UNSUPPORTED SKIP UNSUPPORTED SKIP UNSUPPORTED SKIP
169 split/basic sub/leading_dimension_broadcast PASS - 0.054 s 0.00 MiB 0.00 MiB 1 0 0.000403 ms SKIP 78.297767 mW SKIP 31554.000000 pJ 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()