diff --git a/.agents/invariants/PIMSIM_NN_ORACLE_INVARIANT.md b/.agents/invariants/PIMSIM_NN_ORACLE_INVARIANT.md new file mode 100644 index 0000000..575f929 --- /dev/null +++ b/.agents/invariants/PIMSIM_NN_ORACLE_INVARIANT.md @@ -0,0 +1,22 @@ +# pimsim-nn Oracle Invariant + +`backend-simulators/pim/pimsim-nn` is the performance oracle. Its simulation +behavior defines the hardware model used for Raptor/PIMCOMP comparisons. + +## Required invariant + +- Do not add instruction or operator support to pimsim-nn. +- Changes to pimsim-nn must preserve simulation behavior exactly. Acceptable + changes are limited to behavior-neutral maintenance proven not to alter + simulated timing, scheduling, power, energy, or supported input programs. +- Unsupported pimsim-nn operations must remain unsupported; do not approximate + their timing or map them onto another operation. +- Adapt compiler inputs to the oracle instead. For YOLO, use + `validation/networks/pimcomp_models/yolo11n/yolo11n-pimsim-nn.onnx`, the + dedicated pimsim-ready performance artifact with Softmax operations removed. + Use `validation/networks/yolo11n/depth_51/yolo11n_depth_51.onnx` for YOLO + functional validation; removing Softmax changes the model's numerical + behavior, so the pimsim-ready artifact is not a correctness reference. + +Any proposed pimsim-nn behavior change requires explicit user authorization and +must not be introduced as part of a compiler optimization. diff --git a/.agents/invariants/PIPELINE_SCHEDULING_INVARIANT.md b/.agents/invariants/PIPELINE_SCHEDULING_INVARIANT.md new file mode 100644 index 0000000..a462af1 --- /dev/null +++ b/.agents/invariants/PIPELINE_SCHEDULING_INVARIANT.md @@ -0,0 +1,53 @@ +# Pipeline Scheduling Invariant + +## Scope + +This invariant applies to pipeline stage partitioning, physical-core +assignment, scheduled materialization, deferred transfers, and pipeline +synchronization. + +## Invariant + +A scheduled compute operation and all of its lanes belong to exactly one +pipeline stage. An operation may consume results produced in its own stage or +the immediately preceding stage only. Therefore every compute-graph edge from +stage `S` targets stage `S` or `S + 1`; backward edges and dependencies that +skip a stage are invalid. + +Dynamic function inputs are stage-zero sources. Any operation that directly +consumes one must belong to stage 0. A later stage may consume that data only +through an explicit result forwarded by the preceding stage. + +Each logical core belongs to exactly one stage capacity range before physical +placement. Those ranges cover every core but may have different sizes when the +initial partitioner predicts a lower maximum stage interval. Physical placement +may map a stage to arbitrary core IDs using the injected target topology. +Synchronization and deferred transfers consume the explicit stage identity; +they must not infer it from a physical core number after placement. + +## Ownership + +Logical PEFT remains pipeline-agnostic. Stage partitioning is the first phase +of pipeline scheduling and owns this invariant. It must construct a valid +operation-level partition before physical-core packing. Operations split for +physical capacity retain one shared stage identity. Repacking may move work +only within its assigned stage. Deferred-transfer planning and +synchronization consume the verified stage assignment; they must not repair +or reinterpret it. + +## Verification + +Before scheduled materialization, verify that: + +- every compute instance has one valid physical core and stage; +- all lanes of one compute operation have the same stage; +- every direct dynamic-function-input consumer belongs to stage 0; +- every compute-graph edge stays within a stage or advances exactly one stage; +- every stage-local resident-weight set fits its assigned physical core; and +- stage capacities cover all logical cores exactly once; and +- physical placement is a permutation of all target cores. + +Pipeline scheduling tests must include an uneven physical-core layout and a +graph with a long-lived dependency that would cross multiple naive stage +cuts. End-to-end validation must preserve functional results and exercise the +existing synchronization lowering without simulator changes. diff --git a/AGENTS.md b/AGENTS.md index 7fc40a0..7c373e2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,6 +6,8 @@ Before modifying the relevant subsystem, read: * `.agents/invariants/GRAPH_COMPUTE_BATCH_INVARIANT.md` * `.agents/invariants/PERFORMANCE_OPTIMIZATION_INVARIANT.md` +* `.agents/invariants/PIMSIM_NN_ORACLE_INVARIANT.md` +* `.agents/invariants/PIPELINE_SCHEDULING_INVARIANT.md` * `.agents/invariants/SPATIAL_TARGET_GENERALITY_INVARIANT.md` * Build commands: * `cmake --build ./build_release` diff --git a/src/PIM/Compiler/PimCodeGen.cpp b/src/PIM/Compiler/PimCodeGen.cpp index 1312fa9..002dd4e 100644 --- a/src/PIM/Compiler/PimCodeGen.cpp +++ b/src/PIM/Compiler/PimCodeGen.cpp @@ -544,11 +544,23 @@ void PimCodeGen::setupRdRs1(size_t rdAddress, size_t rdOffset, size_t rs1Address genSetRegisterImmediateUnsigned(1, pim::checkedAddOrCrash(rs1Address, rs1Offset, "rs1 address")); } -void PimCodeGen::setupRdRs1Rs2( +std::array PimCodeGen::setupRdRs1Rs2( size_t rdAddress, size_t rdOffset, size_t rs1Address, size_t rs1Offset, size_t rs2Address, size_t rs2Offset) const { - genSetRegisterImmediateUnsigned(0, pim::checkedAddOrCrash(rdAddress, rdOffset, "rd address")); - genSetRegisterImmediateUnsigned(1, pim::checkedAddOrCrash(rs1Address, rs1Offset, "rs1 address")); - genSetRegisterImmediateUnsigned(2, pim::checkedAddOrCrash(rs2Address, rs2Offset, "rs2 address")); + size_t rd = pim::checkedAddOrCrash(rdAddress, rdOffset, "rd address"); + size_t rs1 = pim::checkedAddOrCrash(rs1Address, rs1Offset, "rs1 address"); + size_t rs2 = pim::checkedAddOrCrash(rs2Address, rs2Offset, "rs2 address"); + genSetRegisterImmediateUnsigned(0, rd); + uint8_t rs1Register = 0; + if (rd != rs1) { + genSetRegisterImmediateUnsigned(1, rs1); + rs1Register = 1; + } + if (rd == rs2) + return {0, rs1Register, 0}; + if (rs1 == rs2) + return {0, rs1Register, rs1Register}; + genSetRegisterImmediateUnsigned(2, rs2); + return {0, rs1Register, 2}; } void PimCodeGen::emitMemCopyOp(pim_binary::Opcode opcode, @@ -664,13 +676,13 @@ void PimCodeGen::codeGenVMVOp(pim::PimVMVOp vmvOp, const StaticValueKnowledge& k auto sourceType = cast(vmvOp.getSource().getType()); int32_t bitwidth = getVectorElementBitwidthOrCrash(sourceType); ensureVectorBitwidth(bitwidth, bitwidth); - setupRdRs1Rs2(addressOf(vmvOp.getTarget(), knowledge), *targetOffset, - addressOf(vmvOp.getSource(), knowledge), *sourceOffset, 0, *sourceStride); + auto registers = setupRdRs1Rs2(addressOf(vmvOp.getTarget(), knowledge), *targetOffset, + addressOf(vmvOp.getSource(), knowledge), *sourceOffset, 0, *sourceStride); pim_binary::InstructionRecord instruction; instruction.opcode = pim_binary::Opcode::vmv; - instruction.rd = 0; - instruction.r1 = 1; - instruction.r2OrImm = 2; + instruction.rd = registers[0]; + instruction.r1 = registers[1]; + instruction.r2OrImm = registers[2]; instruction.generic3 = vmvOp.getLength(); emitInstruction(instruction); } @@ -780,12 +792,13 @@ void PimCodeGen::emitBinaryVectorOp(pim_binary::Opcode opcode, auto inputType = cast(lhs.getType()); ensureVectorBitwidth(getVectorElementBitwidthOrCrash(inputType), getVectorElementBitwidthOrCrash(cast(output.getType()))); - setupRdRs1Rs2(addressOf(output, knowledge), 0, addressOf(lhs, knowledge), 0, addressOf(rhs, knowledge), 0); + auto registers = setupRdRs1Rs2( + addressOf(output, knowledge), 0, addressOf(lhs, knowledge), 0, addressOf(rhs, knowledge), 0); pim_binary::InstructionRecord instruction; instruction.opcode = opcode; - instruction.rd = 0; - instruction.r1 = 1; - instruction.r2OrImm = 2; + instruction.rd = registers[0]; + instruction.r1 = registers[1]; + instruction.r2OrImm = registers[2]; instruction.generic3 = getVectorElementCountOrCrash(inputType); emitInstruction(instruction); } diff --git a/src/PIM/Compiler/PimCodeGen.hpp b/src/PIM/Compiler/PimCodeGen.hpp index aab3338..2186a2f 100644 --- a/src/PIM/Compiler/PimCodeGen.hpp +++ b/src/PIM/Compiler/PimCodeGen.hpp @@ -176,7 +176,7 @@ class PimCodeGen { void genSetRegisterImmediateUnsigned(size_t registerNumber, size_t immediate) const; void setupRd(size_t rdAddress, size_t rdOffset) const; void setupRdRs1(size_t rdAddress, size_t rdOffset, size_t rs1Address, size_t rs1Offset) const; - void setupRdRs1Rs2( + std::array setupRdRs1Rs2( size_t rdAddress, size_t rdOffset, size_t rs1Address, size_t rs1Offset, size_t rs2Address, size_t rs2Offset) const; void emitMemCopyOp(pim_binary::Opcode opcode, diff --git a/src/PIM/Compiler/PimCompilerOptions.cpp b/src/PIM/Compiler/PimCompilerOptions.cpp index 0a10796..aaf67c7 100644 --- a/src/PIM/Compiler/PimCompilerOptions.cpp +++ b/src/PIM/Compiler/PimCompilerOptions.cpp @@ -140,8 +140,8 @@ void verifyExplicitPimCoreCount() { void verifyPimPipelineStages() { if (pipelineStages.getValue() == 0) llvm::report_fatal_error("PIM compilation requires --pipeline to be positive"); - if (static_cast(coresCount.getValue()) % pipelineStages.getValue() != 0) - llvm::report_fatal_error("PIM compilation requires --core-count to be divisible by --pipeline"); + if (static_cast(coresCount.getValue()) < pipelineStages.getValue()) + llvm::report_fatal_error("PIM compilation requires --pipeline not to exceed --core-count"); if (crossbarCountInCore.getValue() > std::numeric_limits::max() / pipelineStages.getValue()) llvm::report_fatal_error("PIM compilation --crossbar-count * --pipeline overflows"); diff --git a/src/PIM/Conversion/ONNXToSpatial/Patterns/Math/ReduceMean.cpp b/src/PIM/Conversion/ONNXToSpatial/Patterns/Math/ReduceMean.cpp index 359c1d3..04a384a 100644 --- a/src/PIM/Conversion/ONNXToSpatial/Patterns/Math/ReduceMean.cpp +++ b/src/PIM/Conversion/ONNXToSpatial/Patterns/Math/ReduceMean.cpp @@ -370,6 +370,14 @@ struct ReduceMeanToSpatialCompute : OpConversionPattern { Location loc = reduceMeanOp.getLoc(); RankedTensorType leafType = getAllOnesType(inputType, resultType.getElementType()); RankedTensorType keepdimsType = getKeepdimsType(inputType, resultType.getElementType(), reducedAxes); + if (semantics->keepdims != 0 && inputType.getRank() == 4 + && inputType.getDimSize(0) == 1 && semantics->axes == ArrayRef({2, 3}) + && resultType == keepdimsType) { + auto plan = spatial::SpatGlobalAveragePoolPlanOp::create( + rewriter, loc, resultType, adaptor.getData(), spatial::getNCHWLayout(rewriter.getContext())); + rewriter.replaceOp(reduceMeanOp, plan.getResult()); + return success(); + } int64_t laneCount = 1; for (auto [dim, isReduced] : llvm::zip_equal(keepdimsType.getShape(), reducedAxes)) { if (isReduced) diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredCommunicationRealization.cpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredCommunicationRealization.cpp index ee60db8..350aeaf 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredCommunicationRealization.cpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredCommunicationRealization.cpp @@ -34,7 +34,9 @@ static LogicalResult verifyNoEscapingRegionValues(Operation* owner, StringRef ph << escapingUser->getName() << " at " << escapingUser->getLoc(); } -static LogicalResult placeLogicalProcessorsOnPhysicalCores(DeferredTransferPlan& plan, const SchedulingTarget& target) { +static LogicalResult placeLogicalProcessorsOnPhysicalCores( + DeferredTransferPlan& plan, const SchedulingTarget& target, + size_t pipelineStages) { std::vector logicalTrafficFlits(target.processorCount * target.processorCount, 0); for (const std::unique_ptr& exchange : plan.exchanges) for (const ExternalTransferFamily& transfer : exchange->external) { @@ -55,8 +57,15 @@ static LogicalResult placeLogicalProcessorsOnPhysicalCores(DeferredTransferPlan& } } + std::vector placementGroups; + if (pipelineStages > 1) { + if (plan.processorStages.size() != target.processorCount) + return failure(); + placementGroups = plan.processorStages; + } std::vector physicalCoreForLogicalProcessor = - mapLogicalProcessorsToPhysicalCores(logicalTrafficFlits, target); + mapLogicalProcessorsToPhysicalCores( + logicalTrafficFlits, target, placementGroups); auto getPhysicalCore = [&](int64_t logicalProcessor) { assert(logicalProcessor >= 0 && static_cast(logicalProcessor) < physicalCoreForLogicalProcessor.size() && "logical processor is outside the scheduling target"); @@ -218,7 +227,8 @@ LogicalResult realizeDeferredCommunication(func::FuncOp funcOp, funcOp, materialization, pipelineStages, target.processorCount); if (failed(transfers)) return funcOp.emitOpError("phase 2 failed to build symbolic transfer families"); - if (failed(placeLogicalProcessorsOnPhysicalCores(*transfers, target))) + if (failed(placeLogicalProcessorsOnPhysicalCores( + *transfers, target, pipelineStages))) return failure(); if (transfers->pipelineHostBufferBytes != 0) { auto bytes = pim::checkedCast( diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredTransferPlanning.cpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredTransferPlanning.cpp index e855295..99cc7d2 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredTransferPlanning.cpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredTransferPlanning.cpp @@ -32,9 +32,11 @@ static LogicalResult collectScheduledOperations( DeferredTransferPlan &plan, size_t pipelineStageCount, size_t processorCount) { - if (pipelineStageCount == 0 || processorCount % pipelineStageCount != 0) + if (pipelineStageCount == 0 + || (pipelineStageCount > 1 + && materialization.processorStages.size() != processorCount)) return failure(); - size_t stageSize = processorCount / pipelineStageCount; + plan.processorStages = materialization.processorStages; unsigned nextStream = 0; for (const ScheduledMaterializationRecord &record : materialization.materializedSchedules) { @@ -56,8 +58,12 @@ static LogicalResult collectScheduledOperations( if (core >= processorCount) return op.emitOpError("phase 2 scheduled core is outside the target"); info.cores.push_back(core); - if (pipelineStageCount > 1) - info.pipelineStages.push_back(core / stageSize); + if (pipelineStageCount > 1) { + size_t stage = materialization.processorStages[core]; + if (stage >= pipelineStageCount) + return op.emitOpError("phase 2 scheduled core has an invalid pipeline stage"); + info.pipelineStages.push_back(stage); + } } for (size_t lane = 0; lane < info.cores.size(); ++lane) info.streamIds.push_back(nextStream++); diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredTransferPlanning.hpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredTransferPlanning.hpp index 96d915d..93356c3 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredTransferPlanning.hpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/DeferredTransferPlanning.hpp @@ -8,6 +8,7 @@ namespace onnx_mlir::spatial { struct DeferredTransferPlan { + std::vector processorStages; llvm::SmallVector scheduled; llvm::SmallVector> producedStorage; llvm::DenseMap> producedByGraph; diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.cpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.cpp index 4dc6705..4b990a1 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.cpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.cpp @@ -808,7 +808,9 @@ materializeScheduledCompute(func::FuncOp funcOp, } } - return ScheduledComputeMaterializationResult {std::move(peftClassPlans), std::move(materializedSchedules), std::move(graphComputeToBlockMap)}; + return ScheduledComputeMaterializationResult { + std::move(peftClassPlans), std::move(materializedSchedules), + std::move(graphComputeToBlockMap), schedule.processorStages}; } diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.hpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.hpp index 96d5b1f..61309d5 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.hpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.hpp @@ -14,6 +14,7 @@ struct ScheduledComputeMaterializationResult { llvm::MapVector peftClassPlans; std::vector materializedSchedules; DenseMap graphComputeToBlockMap; + std::vector processorStages; }; FailureOr diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledSpatialPasses.cpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledSpatialPasses.cpp index dff6291..8d2b0c1 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledSpatialPasses.cpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledSpatialPasses.cpp @@ -39,8 +39,9 @@ static SchedulingTarget getPipelineSchedulingTarget( if (pipelineStages == 1) return physicalTarget; + PipelineCoreLayout layout(physicalTarget.processorCount, pipelineStages); SchedulingTarget schedulingTarget = physicalTarget; - schedulingTarget.processorCount = physicalTarget.processorCount / pipelineStages; + schedulingTarget.processorCount = layout.getLogicalProcessorCount(); schedulingTarget.residentWeightCapacity = checkedMultiply( physicalTarget.residentWeightCapacity, pipelineStages); schedulingTarget.interProcessorLatencyNs.assign( @@ -88,7 +89,8 @@ struct ScheduleAndRealizeSpatialPass final signalPassFailure(); return; } - if (pipelineStages == 0 || target.processorCount % pipelineStages != 0 + PipelineCoreLayout pipelineLayout(target.processorCount, pipelineStages); + if (!pipelineLayout.isValid() || (pipelineStages > 1 && target.synchronizationRegisterCount == 0) || target.residentWeightCapacity @@ -115,19 +117,24 @@ struct ScheduleAndRealizeSpatialPass final scheduledGraph = analysis.getGraph(); schedule = std::move(analysis.getResult()); std::string pipelineError; + if (pipelineStages > 1) { + FailureOr preparation = + preparePipelineWorkload( + scheduledGraph, schedule, pipelineStages, target, pipelineError); + if (failed(preparation)) { + moduleOp.emitError() << pipelineError; + signalPassFailure(); + return; + } + if (*preparation == PipelineWorkloadPreparation::Changed) + continue; + } if (succeeded(applyPipelineScheduling( scheduledGraph, schedule, pipelineStages, target, pipelineError))) break; - std::string splitError; - if (pipelineStages == 1 - || failed(splitPipelineWorkload( - scheduledGraph, schedule, pipelineStages, target, splitError))) { - if (!splitError.empty()) - pipelineError = splitError; - moduleOp.emitError() << pipelineError; - signalPassFailure(); - return; - } + moduleOp.emitError() << pipelineError; + signalPassFailure(); + return; } PatternRewriter rewriter(moduleOp.getContext()); FailureOr materialization = diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/MergeSchedule.hpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/MergeSchedule.hpp index 19af1cb..c792d83 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/MergeSchedule.hpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/MergeSchedule.hpp @@ -14,6 +14,7 @@ namespace spatial { struct MergeScheduleResult { size_t processorCount = 0; + std::vector processorStages; std::vector dominanceOrderCompute; llvm::DenseMap computeToCpuMap; llvm::DenseMap computeToCpuSlotMap; diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.cpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.cpp index 6ba90ca..00814f4 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.cpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.cpp @@ -244,11 +244,13 @@ FailureOr buildLanePublicationSignatures(SpatComputeB } // namespace std::vector mapLogicalProcessorsToPhysicalCores(ArrayRef logicalTrafficFlits, - const SchedulingTarget& target) { + const SchedulingTarget& target, + ArrayRef placementGroups) { const size_t processorCount = target.processorCount; assert(logicalTrafficFlits.size() == processorCount * processorCount && "logical traffic matrix must cover every processor pair"); - + assert((placementGroups.empty() || placementGroups.size() == processorCount) + && "physical placement groups must cover every processor"); std::vector physicalCoreForLogicalProcessor(processorCount); std::iota(physicalCoreForLogicalProcessor.begin(), physicalCoreForLogicalProcessor.end(), 0); @@ -266,6 +268,10 @@ std::vector mapLogicalProcessorsToPhysicalCores(ArrayRef logicalTr for (size_t peerLogicalProcessor = 0; peerLogicalProcessor < processorCount; ++peerLogicalProcessor) { if (peerLogicalProcessor == logicalProcessor) continue; + if (!placementGroups.empty() + && placementGroups[peerLogicalProcessor] + != placementGroups[logicalProcessor]) + continue; size_t physicalCore = physicalCoreForLogicalProcessor[logicalProcessor]; size_t peerPhysicalCore = physicalCoreForLogicalProcessor[peerLogicalProcessor]; Cost currentCost = 0; diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.hpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.hpp index 4170d6d..053d457 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.hpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.hpp @@ -29,7 +29,8 @@ inline Time getPeftTransferTime(const TransferCost& transferCost, MergeScheduleResult runPeftScheduler(const ComputeGraph& graph, const PeftScheduleOptions& options); std::vector mapLogicalProcessorsToPhysicalCores(llvm::ArrayRef logicalTrafficFlits, - const SchedulingTarget& target); + const SchedulingTarget& target, + llvm::ArrayRef placementGroups = {}); } // namespace spatial } // namespace onnx_mlir diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.cpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.cpp index be2e30c..ab035cf 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.cpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.cpp @@ -1,7 +1,10 @@ +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/STLExtras.h" #include #include +#include #include #include #include @@ -556,6 +559,10 @@ static LogicalResult splitBatchCompute(SpatGraphComputeBatch batch, return failure(); if (failed(verifySplittableVmmUses(splitBody->vmms, error))) return failure(); + if (!batch->hasAttr("pipeline.stage_group")) + batch->setAttr( + "pipeline.stage_group", + DistinctAttr::create(UnitAttr::get(batch.getContext()))); size_t partCount = std::min(pipelineStages, splitBody->vmms.size()); SmallVector, 4> partitions = @@ -601,11 +608,10 @@ static LogicalResult splitBatchCompute(SpatGraphComputeBatch batch, return success(); } -static LogicalResult splitPipelineWorkloadImpl(const ComputeGraph &graph, - const MergeScheduleResult &schedule, - size_t pipelineStages, - const SchedulingTarget &physicalTarget, - std::string &error) { +static FailureOr preparePipelineWorkloadImpl( + const ComputeGraph &graph, const MergeScheduleResult &schedule, + size_t pipelineStages, const SchedulingTarget &physicalTarget, + std::string &error) { size_t groupSize = schedule.processorCount; std::vector tasksByCpu(groupSize); for (size_t task = 0; task < graph.nodes.size(); ++task) { @@ -654,7 +660,7 @@ static LogicalResult splitPipelineWorkloadImpl(const ComputeGraph &graph, std::string currentError; if (succeeded(splitBatchCompute( batch, pipelineStages, physicalTarget, currentError))) - return success(); + return PipelineWorkloadPreparation::Changed; if (!currentError.empty()) candidateError = currentError; } @@ -663,7 +669,8 @@ static LogicalResult splitPipelineWorkloadImpl(const ComputeGraph &graph, : candidateError; return failure(); } - return failure(); + + return PipelineWorkloadPreparation::Ready; } bool fits(const ComputeGraph& graph, @@ -719,193 +726,585 @@ Cost findMaximumPackCost(const ComputeGraph& graph, return low; } -static Cost getCoreCost(const TaskList &tasks, const TaskCosts &taskCosts) { - Cost cost = 0; - for (size_t task : tasks) - cost = checkedAdd(cost, taskCosts[task]); - return cost; -} - -static Cost getStageMaximumAssemblyCost( - const std::vector &tasksByCpu, - const TaskCosts &assemblyCosts, size_t groupSize, size_t stage) { - Cost maximum = 0; - for (size_t cpu = stage * groupSize; - cpu < (stage + 1) * groupSize; ++cpu) - maximum = std::max( - maximum, getCoreCost(tasksByCpu[cpu], assemblyCosts)); - return maximum; -} - -static bool fitsResidentWeights(const ComputeGraph &graph, - const TaskList &tasks, size_t candidate, - size_t residentWeightCapacity) { - ResidentWeightSet weights; - for (size_t task : tasks) - insertResidentWeights(weights, graph.nodes[task].residentWeights); - return getResidentWeightUnionSize( - weights, graph.nodes[candidate].residentWeights) - <= residentWeightCapacity; -} - -static void repackPipelineStage( - const ComputeGraph &graph, const TaskCosts &schedulingCosts, - const TaskCosts &assemblyCosts, - std::vector &tasksByCpu, size_t groupSize, size_t stage, - size_t residentWeightCapacity) { - TaskList tasks; - Cost originalMaximum = 0; - for (size_t cpu = stage * groupSize; - cpu < (stage + 1) * groupSize; ++cpu) { - llvm::append_range(tasks, tasksByCpu[cpu]); - originalMaximum = std::max( - originalMaximum, - getCoreCost(tasksByCpu[cpu], schedulingCosts)); +static Cost findMaximumIndexedPackCost( + const TaskCosts &taskCosts, + const std::vector &taskWeightIds, size_t weightCount, + const TaskList &tasks, size_t residentWeightCapacity, + size_t maximumPacks) { + Cost low = 0; + Cost high = 0; + for (size_t task : tasks) { + low = std::max(low, taskCosts[task]); + high = checkedAdd(high, taskCosts[task]); } - llvm::sort(tasks, [&](size_t lhs, size_t rhs) { + low = std::max( + low, high / maximumPacks + (high % maximumPacks != 0)); + + std::vector seen(weightCount); + size_t generation = 0; + while (low < high) { + Cost middle = low + (high - low) / 2; + size_t packs = 1; + Cost cost = 0; + size_t packWeightCount = 0; + ++generation; + bool fits = true; + bool packEmpty = true; + for (size_t task : tasks) { + size_t addedWeights = 0; + for (size_t weight : taskWeightIds[task]) + addedWeights += seen[weight] != generation; + Cost taskCost = taskCosts[task]; + bool startsNewPack = !packEmpty + && (cost > middle - taskCost + || packWeightCount + addedWeights > residentWeightCapacity); + if (startsNewPack) { + if (++packs > maximumPacks) { + fits = false; + break; + } + cost = 0; + packWeightCount = 0; + ++generation; + packEmpty = true; + } + cost = checkedAdd(cost, taskCost); + for (size_t weight : taskWeightIds[task]) + if (seen[weight] != generation) { + seen[weight] = generation; + ++packWeightCount; + } + packEmpty = false; + } + if (fits) + high = middle; + else + low = middle + 1; + } + return low; +} + +static size_t findMinimumIndexedPackCount( + const std::vector &taskWeightIds, const TaskList &tasks, + size_t residentWeightCapacity) { + if (tasks.empty()) + return 0; + size_t packs = 1; + TaskList weights; + for (size_t task : tasks) { + size_t unionSize = weights.size(); + for (size_t weight : taskWeightIds[task]) + unionSize += !llvm::is_contained(weights, weight); + if (!weights.empty() && unionSize > residentWeightCapacity) { + ++packs; + weights.clear(); + } + for (size_t weight : taskWeightIds[task]) + if (!llvm::is_contained(weights, weight)) + weights.push_back(weight); + } + return packs; +} + +struct PipelineGroup { + TaskList tasks; + TaskList successors; + size_t originalOrder = std::numeric_limits::max(); + TaskList weightIds; + bool consumesPipelineInput = false; +}; + +struct PipelineStageAssignment { + std::vector taskStages; + std::vector stageSizes; +}; + +static const TaskCosts &getPipelineBalanceCosts( + const ComputeGraph &graph, const PipelineTaskModel &model) { + for (size_t task = 0; task < graph.nodes.size(); ++task) + if (graph.nodes[task].instance.op && model.assemblyCosts[task] > 1 + && !model.predecessors[task].empty()) + return model.assemblyCosts; + return model.schedulingCosts; +} + +static bool consumesPipelineInput(const ComputeGraphNode &node) { + if (!node.instance.op) + return false; + return llvm::any_of(getComputeInstanceInputs(node.instance), + [](Value input) { return isa(input); }); +} + +static FailureOr assignPipelineStages( + const ComputeGraph &graph, const PipelineTaskModel &model, + const PipelineCoreLayout &layout, size_t residentWeightCapacity, + std::string &error) { + if (graph.nodes.empty()) + return PipelineStageAssignment { + {}, std::vector(layout.getStageCount(), 1)}; + std::vector tasksByOrder(graph.nodes.size()); + std::iota(tasksByOrder.begin(), tasksByOrder.end(), 0); + llvm::sort(tasksByOrder, [&](size_t lhs, size_t rhs) { return graph.nodes[lhs].originalOrder < graph.nodes[rhs].originalOrder; }); - std::vector packed(groupSize); - std::vector weights(groupSize); - TaskCosts loads(groupSize); - TaskCosts assemblyLoads(groupSize); + std::vector groups; + std::vector taskToGroup(graph.nodes.size()); + ResidentWeightSet indexedWeights; + std::vector taskWeightIds(graph.nodes.size()); + for (size_t task : tasksByOrder) + for (const ResidentWeight &weight : graph.nodes[task].residentWeights) { + auto indexed = llvm::find(indexedWeights, weight); + size_t id = indexed - indexedWeights.begin(); + if (indexed == indexedWeights.end()) { + id = indexedWeights.size(); + indexedWeights.push_back(weight); + } + taskWeightIds[task].push_back(id); + } + llvm::DenseMap operationToGroup; + llvm::DenseMap splitOperationToGroup; + for (size_t task : tasksByOrder) { + Operation *operation = graph.nodes[task].instance.op; + Attribute splitGroup = operation + ? operation->getAttr("pipeline.stage_group") + : Attribute(); + size_t group; + auto existingSplit = splitGroup + ? splitOperationToGroup.find(splitGroup) + : splitOperationToGroup.end(); + auto existingOperation = operation && !splitGroup + ? operationToGroup.find(operation) + : operationToGroup.end(); + if (existingSplit != splitOperationToGroup.end()) { + group = existingSplit->second; + } else if (existingOperation != operationToGroup.end()) { + group = existingOperation->second; + } else { + group = groups.size(); + groups.emplace_back(); + if (splitGroup) + splitOperationToGroup[splitGroup] = group; + else if (operation) + operationToGroup[operation] = group; + } + taskToGroup[task] = group; + PipelineGroup &pipelineGroup = groups[group]; + pipelineGroup.tasks.push_back(task); + pipelineGroup.originalOrder = std::min( + pipelineGroup.originalOrder, graph.nodes[task].originalOrder); + pipelineGroup.consumesPipelineInput |= + consumesPipelineInput(graph.nodes[task]); + for (size_t weight : taskWeightIds[task]) + if (!llvm::is_contained(pipelineGroup.weightIds, weight)) + pipelineGroup.weightIds.push_back(weight); + } + + std::vector indegree(groups.size()); + for (size_t task = 0; task < graph.nodes.size(); ++task) + for (size_t predecessor : model.predecessors[task]) { + size_t source = taskToGroup[predecessor]; + size_t target = taskToGroup[task]; + if (source == target + || llvm::is_contained(groups[source].successors, target)) + continue; + groups[source].successors.push_back(target); + ++indegree[target]; + } + + auto laterOriginalOrder = [&](size_t lhs, size_t rhs) { + return groups[lhs].originalOrder > groups[rhs].originalOrder; + }; + std::priority_queue, decltype(laterOriginalOrder)> + ready(laterOriginalOrder); + for (size_t group = 0; group < groups.size(); ++group) + if (indegree[group] == 0) + ready.push(group); + + TaskList groupOrder; + while (!ready.empty()) { + size_t group = ready.top(); + ready.pop(); + groupOrder.push_back(group); + for (size_t successor : groups[group].successors) + if (--indegree[successor] == 0) + ready.push(successor); + } + if (groupOrder.size() != groups.size()) { + error = "pipeline scheduling cannot keep every operation in one stage " + "because the collapsed operation graph is cyclic"; + return failure(); + } + + std::vector position(groups.size()); + for (auto [index, group] : llvm::enumerate(groupOrder)) + position[group] = index; + size_t minimumStageZeroEnd = 0; + for (auto [index, group] : llvm::enumerate(groupOrder)) + if (groups[group].consumesPipelineInput) + minimumStageZeroEnd = index + 1; + std::vector furthestSuccessorBefore(groups.size() + 1, 0); + bool hasCrossingEdge = false; + size_t furthestSuccessor = 0; + for (size_t cut = 1; cut <= groups.size(); ++cut) { + size_t group = groupOrder[cut - 1]; + for (size_t successor : groups[group].successors) { + if (position[successor] <= position[group]) { + error = "pipeline scheduling operation order is not topological"; + return failure(); + } + furthestSuccessor = std::max(furthestSuccessor, position[successor]); + hasCrossingEdge = true; + } + furthestSuccessorBefore[cut] = furthestSuccessor; + } + + auto partitionGroups = [&](ArrayRef coreCounts) + -> FailureOr> { + const Cost infinity = std::numeric_limits::max(); + const size_t noCut = std::numeric_limits::max(); + std::vector> best( + coreCounts.size() + 1, + std::vector(groups.size() + 1, infinity)); + std::vector> parent( + coreCounts.size() + 1, + std::vector(groups.size() + 1, noCut)); + std::vector stageCostCache(coreCounts.size()); + std::vector cachedCoreCounts; + std::vector>> segmentCostCaches; + for (auto [stage, coreCount] : llvm::enumerate(coreCounts)) { + auto cached = llvm::find(cachedCoreCounts, coreCount); + if (cached == cachedCoreCounts.end()) { + stageCostCache[stage] = segmentCostCaches.size(); + cachedCoreCounts.push_back(coreCount); + segmentCostCaches.emplace_back( + groups.size() + 1, + std::vector(groups.size() + 1, infinity)); + } else { + stageCostCache[stage] = cached - cachedCoreCounts.begin(); + } + } + best[0][0] = 0; + + // ponytail: operation groups are small; replace this quadratic partition + // only if scheduling profiles show it matters. + for (size_t stage = 0; stage < coreCounts.size(); ++stage) { + size_t coreCount = coreCounts[stage]; + size_t stageWeightCapacity = checkedMultiply( + coreCount, residentWeightCapacity); + for (size_t start = 0; start < groups.size(); ++start) { + if (best[stage][start] == infinity) + continue; + TaskList segmentTasks; + llvm::SmallBitVector segmentWeights(indexedWeights.size()); + size_t segmentWeightCount = 0; + for (size_t end = start + 1; end <= groups.size(); ++end) { + const PipelineGroup &group = groups[groupOrder[end - 1]]; + llvm::append_range(segmentTasks, group.tasks); + for (size_t weight : group.weightIds) + if (!segmentWeights.test(weight)) { + segmentWeights.set(weight); + ++segmentWeightCount; + } + if (segmentWeightCount > stageWeightCapacity) + break; + if (stage == 0 && end < minimumStageZeroEnd) + continue; + if (stage != 0 && hasCrossingEdge + && furthestSuccessorBefore[start] >= end) + continue; + Cost &segmentCost = + segmentCostCaches[stageCostCache[stage]][start][end]; + if (segmentCost == infinity) + segmentCost = findMaximumIndexedPackCost( + model.schedulingCosts, taskWeightIds, indexedWeights.size(), + segmentTasks, residentWeightCapacity, coreCount); + Cost maximumLoad = std::max(best[stage][start], segmentCost); + if (maximumLoad < best[stage + 1][end]) { + best[stage + 1][end] = maximumLoad; + parent[stage + 1][end] = start; + } + } + } + } + + size_t usedStages = 0; + Cost bestLoad = infinity; + for (size_t stages = 1; stages <= coreCounts.size(); ++stages) + if (best[stages][groups.size()] != infinity + && best[stages][groups.size()] <= bestLoad) { + bestLoad = best[stages][groups.size()]; + usedStages = stages; + } + if (usedStages == 0) { + error = "pipeline scheduling cannot split operations into dependency-adjacent " + "stages within the physical crossbar limit"; + return failure(); + } + + std::vector groupStages(groups.size()); + size_t end = groups.size(); + for (size_t stage = usedStages; stage > 0; --stage) { + size_t start = parent[stage][end]; + assert(start != noCut && "selected pipeline partition has no parent"); + for (size_t position = start; position < end; ++position) + groupStages[groupOrder[position]] = stage - 1; + end = start; + } + return groupStages; + }; + + FailureOr> initialGroupStages = + partitionGroups(layout.getStageSizes()); + if (failed(initialGroupStages)) + return failure(); + + std::vector tasksByStage(layout.getStageCount()); + for (size_t group : groupOrder) + llvm::append_range( + tasksByStage[(*initialGroupStages)[group]], groups[group].tasks); + std::vector stageSizes(layout.getStageCount(), 1); + size_t assignedCores = stageSizes.size(); + for (size_t stage = 0; stage < stageSizes.size(); ++stage) { + for (size_t task : tasksByStage[stage]) + if (taskWeightIds[task].size() > residentWeightCapacity) { + error = "pipeline scheduling cannot fit one compute instance in a " + "physical core's crossbars"; + return failure(); + } + stageSizes[stage] = std::max( + stageSizes[stage], findMinimumIndexedPackCount( + taskWeightIds, tasksByStage[stage], + residentWeightCapacity)); + assignedCores += stageSizes[stage] - 1; + } + if (assignedCores > layout.getProcessorCount()) { + error = "pipeline scheduling cannot fit dependency-adjacent stages " + "within the physical crossbar limit"; + return failure(); + } + + const TaskCosts &balanceCosts = getPipelineBalanceCosts(graph, model); + auto getStageCost = [&](size_t stage, size_t coreCount) { + Cost schedulingCost = findMaximumIndexedPackCost( + model.schedulingCosts, taskWeightIds, indexedWeights.size(), + tasksByStage[stage], residentWeightCapacity, coreCount); + if (&balanceCosts == &model.schedulingCosts) + return schedulingCost; + Cost assemblyCost = findMaximumIndexedPackCost( + balanceCosts, taskWeightIds, indexedWeights.size(), + tasksByStage[stage], residentWeightCapacity, coreCount); + return std::max(schedulingCost, assemblyCost); + }; + std::vector stageCosts(stageSizes.size()); + std::vector nextStageCosts(stageSizes.size()); + for (size_t stage = 0; stage < stageSizes.size(); ++stage) + stageCosts[stage] = getStageCost(stage, stageSizes[stage]); + for (size_t stage = 0; stage < stageSizes.size(); ++stage) + nextStageCosts[stage] = getStageCost(stage, stageSizes[stage] + 1); + while (assignedCores < layout.getProcessorCount()) { + size_t bestStage = 0; + Cost bestBenefit = 0; + for (size_t stage = 0; stage < stageSizes.size(); ++stage) { + Cost benefit = stageCosts[stage] - nextStageCosts[stage]; + if (benefit > bestBenefit + || (benefit == bestBenefit + && (stageCosts[stage] > stageCosts[bestStage] + || (stageCosts[stage] == stageCosts[bestStage] + && stageSizes[stage] < stageSizes[bestStage])))) { + bestStage = stage; + bestBenefit = benefit; + } + } + ++stageSizes[bestStage]; + stageCosts[bestStage] = nextStageCosts[bestStage]; + nextStageCosts[bestStage] = + getStageCost(bestStage, stageSizes[bestStage] + 1); + ++assignedCores; + } + FailureOr> refinedGroupStages = + partitionGroups(stageSizes); + if (failed(refinedGroupStages)) + return failure(); + std::vector taskStages(graph.nodes.size()); + for (size_t task = 0; task < graph.nodes.size(); ++task) + taskStages[task] = (*refinedGroupStages)[taskToGroup[task]]; + return PipelineStageAssignment { + std::move(taskStages), std::move(stageSizes)}; +} + +static bool packPipelineStage( + const ComputeGraph &graph, const TaskCosts &schedulingCosts, + const TaskCosts &assemblyCosts, + std::vector &tasksByCpu, const PipelineCoreLayout &layout, + ArrayRef topologicalPosition, size_t stage, + size_t residentWeightCapacity, const SchedulingTarget &target, + std::vector &taskCpus) { + PipelineStageRange range = layout.getStageRange(stage); + TaskList tasks; + for (size_t cpu = range.begin; cpu < range.begin + range.size; ++cpu) + llvm::append_range(tasks, tasksByCpu[cpu]); + llvm::sort(tasks, [&](size_t lhs, size_t rhs) { + return topologicalPosition[lhs] < topologicalPosition[rhs]; + }); + std::vector packed(range.size); + std::vector weights(range.size); + TaskCosts loads(range.size); + TaskCosts assemblyLoads(range.size); for (size_t task : tasks) { std::optional bestCore; - std::optional> bestScore; - for (size_t core = 0; core < groupSize; ++core) { + using PackScore = std::tuple; + std::optional bestScore; + for (size_t core = 0; core < range.size; ++core) { size_t unionSize = getResidentWeightUnionSize( weights[core], graph.nodes[task].residentWeights); if (unionSize > residentWeightCapacity) continue; size_t addedWeights = unionSize - weights[core].size(); - auto score = std::make_tuple( - checkedAdd(assemblyLoads[core], assemblyCosts[task]), - checkedAdd(loads[core], schedulingCosts[task]), addedWeights, core); + Cost assemblyLoad = checkedAdd( + assemblyLoads[core], assemblyCosts[task]); + Cost schedulingLoad = checkedAdd( + loads[core], schedulingCosts[task]); + Time transferTime = 0; + size_t candidateCpu = range.begin + core; + for (const auto &[predecessor, transferCost] : + graph.predecessors[task]) + if (taskCpus[predecessor] < target.processorCount) + transferTime = checkedAdd( + transferTime, getPeftTransferTime( + transferCost, taskCpus[predecessor], + candidateCpu, target)); + PackScore score { + assemblyLoad, transferTime, schedulingLoad, addedWeights, core}; if (!bestScore || score < *bestScore) { bestCore = core; bestScore = score; } } if (!bestCore) - return; + return false; packed[*bestCore].push_back(task); insertResidentWeights( weights[*bestCore], graph.nodes[task].residentWeights); loads[*bestCore] = checkedAdd(loads[*bestCore], schedulingCosts[task]); assemblyLoads[*bestCore] = checkedAdd( assemblyLoads[*bestCore], assemblyCosts[task]); + taskCpus[task] = range.begin + *bestCore; } - if (*std::max_element(loads.begin(), loads.end()) > originalMaximum) - return; - for (size_t core = 0; core < groupSize; ++core) - tasksByCpu[stage * groupSize + core] = std::move(packed[core]); + for (size_t core = 0; core < range.size; ++core) + tasksByCpu[range.begin + core] = std::move(packed[core]); + return true; } -static void rebalancePipelineStages( +static LogicalResult packPipelineStages( const ComputeGraph &graph, const PipelineTaskModel &model, - std::vector &tasksByCpu, size_t groupSize, - size_t pipelineStages, size_t residentWeightCapacity) { - size_t minimumAssemblyFanIn = std::numeric_limits::max(); + std::vector &tasksByCpu, const PipelineCoreLayout &layout, + size_t pipelineStages, size_t residentWeightCapacity, + const SchedulingTarget &target, size_t &failedStage, + std::string &error) { + std::vector indegree(graph.nodes.size()); + std::vector successors(graph.nodes.size()); for (size_t task = 0; task < graph.nodes.size(); ++task) - if (graph.nodes[task].instance.op && model.assemblyCosts[task] > 1 - && !model.predecessors[task].empty()) - minimumAssemblyFanIn = std::min( - minimumAssemblyFanIn, model.predecessors[task].size()); - bool hasAssembly = minimumAssemblyFanIn != std::numeric_limits::max(); - if (hasAssembly && groupSize < minimumAssemblyFanIn) - return; - const TaskCosts &balanceCosts = - hasAssembly ? model.assemblyCosts : model.schedulingCosts; + for (size_t predecessor : model.predecessors[task]) { + successors[predecessor].push_back(task); + ++indegree[task]; + } + auto laterOriginalOrder = [&](size_t lhs, size_t rhs) { + return graph.nodes[lhs].originalOrder > graph.nodes[rhs].originalOrder; + }; + std::priority_queue, decltype(laterOriginalOrder)> + ready(laterOriginalOrder); + for (size_t task = 0; task < graph.nodes.size(); ++task) + if (indegree[task] == 0) + ready.push(task); + std::vector topologicalPosition(graph.nodes.size()); + size_t position = 0; + while (!ready.empty()) { + size_t task = ready.top(); + ready.pop(); + topologicalPosition[task] = position++; + for (size_t successor : successors[task]) + if (--indegree[successor] == 0) + ready.push(successor); + } + if (position != graph.nodes.size()) { + error = "pipeline rebalancing received a cyclic task graph"; + return failure(); + } - Cost schedulingLimit = 0; - for (const TaskList &tasks : tasksByCpu) - schedulingLimit = std::max( - schedulingLimit, getCoreCost(tasks, model.schedulingCosts)); + const TaskCosts &balanceCosts = getPipelineBalanceCosts(graph, model); + std::vector taskCpus(graph.nodes.size(), target.processorCount); for (size_t stage = 0; stage < pipelineStages; ++stage) - repackPipelineStage( - graph, model.schedulingCosts, balanceCosts, tasksByCpu, - groupSize, stage, - residentWeightCapacity); + if (!packPipelineStage( + graph, model.schedulingCosts, balanceCosts, tasksByCpu, + layout, topologicalPosition, stage, residentWeightCapacity, + target, taskCpus)) { + failedStage = stage; + error = "pipeline scheduling cannot pack dependency-monotone stage " + + std::to_string(stage) + + " within the physical crossbar limit"; + return failure(); + } + return success(); +} - std::vector taskToCpu(graph.nodes.size()); - for (size_t cpu = 0; cpu < tasksByCpu.size(); ++cpu) - for (size_t task : tasksByCpu[cpu]) - taskToCpu[task] = cpu; - - bool changed; - do { - changed = false; - for (size_t sourceStage = pipelineStages; sourceStage-- > 1;) { - size_t targetStage = sourceStage - 1; - while (true) { - Cost sourceMaximum = getStageMaximumAssemblyCost( - tasksByCpu, balanceCosts, groupSize, sourceStage); - Cost targetMaximum = getStageMaximumAssemblyCost( - tasksByCpu, balanceCosts, groupSize, targetStage); - if (targetMaximum >= sourceMaximum) - break; - - struct Move { - size_t sourceCpu; - size_t targetCpu; - size_t task; - }; - std::optional best; - std::optional> bestScore; - for (size_t sourceCpu = sourceStage * groupSize; - sourceCpu < (sourceStage + 1) * groupSize; ++sourceCpu) { - if (tasksByCpu[sourceCpu].empty()) - continue; - size_t task = tasksByCpu[sourceCpu].front(); - bool dependenciesReady = llvm::all_of( - model.predecessors[task], [&](size_t predecessor) { - return taskToCpu[predecessor] / groupSize <= targetStage; - }); - if (!dependenciesReady) - continue; - - Cost sourceAfter = getCoreCost( - tasksByCpu[sourceCpu], balanceCosts) - - balanceCosts[task]; - for (size_t targetCpu = targetStage * groupSize; - targetCpu < (targetStage + 1) * groupSize; ++targetCpu) { - const TaskList &targetTasks = tasksByCpu[targetCpu]; - if (!fitsResidentWeights( - graph, targetTasks, task, residentWeightCapacity)) - continue; - Cost targetAfter = checkedAdd( - getCoreCost(targetTasks, balanceCosts), balanceCosts[task]); - Cost targetSchedulingAfter = checkedAdd( - getCoreCost(targetTasks, model.schedulingCosts), - model.schedulingCosts[task]); - if (targetAfter >= sourceMaximum - || targetSchedulingAfter > schedulingLimit) - continue; - auto score = std::make_tuple( - graph.nodes[task].originalOrder, - std::max(sourceAfter, targetAfter), targetAfter, targetCpu); - if (!bestScore || score < *bestScore) { - best = Move {sourceCpu, targetCpu, task}; - bestScore = score; - } - } - } - if (!best) - break; - tasksByCpu[best->sourceCpu].erase( - tasksByCpu[best->sourceCpu].begin()); - TaskList &targetTasks = tasksByCpu[best->targetCpu]; - auto insertion = llvm::find_if(targetTasks, [&](size_t task) { - return graph.nodes[task].originalOrder - > graph.nodes[best->task].originalOrder; - }); - targetTasks.insert(insertion, best->task); - taskToCpu[best->task] = best->targetCpu; - changed = true; +static LogicalResult verifyPipelineStageAssignment( + const ComputeGraph &graph, const PipelineTaskModel &model, + const std::vector &tasksByCpu, + const PipelineCoreLayout &layout, std::string &error) { + const size_t noStage = std::numeric_limits::max(); + std::vector taskStages(graph.nodes.size(), noStage); + llvm::DenseMap operationStages; + llvm::DenseMap splitOperationStages; + for (size_t cpu = 0; cpu < tasksByCpu.size(); ++cpu) { + std::optional stage = layout.getStageForCore(cpu); + if (!stage) { + error = "pipeline scheduling assigned a task outside the stage layout"; + return failure(); + } + for (size_t task : tasksByCpu[cpu]) { + if (task >= graph.nodes.size() || taskStages[task] != noStage) { + error = "pipeline scheduling did not assign every task exactly once"; + return failure(); + } + taskStages[task] = *stage; + if (*stage != 0 && consumesPipelineInput(graph.nodes[task])) { + error = "pipeline scheduling assigned a direct function-input " + "consumer after stage zero"; + return failure(); + } + Operation *operation = graph.nodes[task].instance.op; + if (!operation) + continue; + Attribute splitGroup = operation->getAttr("pipeline.stage_group"); + bool consistent; + if (splitGroup) { + auto [entry, inserted] = + splitOperationStages.try_emplace(splitGroup, *stage); + consistent = inserted || entry->second == *stage; + } else { + auto [entry, inserted] = + operationStages.try_emplace(operation, *stage); + consistent = inserted || entry->second == *stage; + } + if (!consistent) { + error = "pipeline scheduling split one operation across stages"; + return failure(); } } - } while (changed); + } + if (llvm::is_contained(taskStages, noStage)) { + error = "pipeline scheduling did not assign every task exactly once"; + return failure(); + } + for (size_t task = 0; task < graph.nodes.size(); ++task) + for (size_t predecessor : model.predecessors[task]) + if (taskStages[predecessor] > taskStages[task] + || taskStages[task] - taskStages[predecessor] > 1) { + error = "pipeline scheduling produced a backward or skipped-stage dependency"; + return failure(); + } + return success(); } mlir::LogicalResult assignPipelineCores(const ComputeGraph& graph, @@ -914,7 +1313,13 @@ mlir::LogicalResult assignPipelineCores(const ComputeGraph& graph, const SchedulingTarget& physicalTarget, std::string& error) { const size_t groupSize = schedule.processorCount; - std::vector tasksByCpu(groupSize); + PipelineCoreLayout balancedLayout( + physicalTarget.processorCount, pipelineStages); + if (!balancedLayout.isValid() + || groupSize != balancedLayout.getLogicalProcessorCount()) { + error = "pipeline scheduling received an incompatible physical core layout"; + return mlir::failure(); + } for (size_t task = 0; task < graph.nodes.size(); ++task) { const ComputeInstance& instance = graph.nodes[task].instance; auto cpu = schedule.computeToCpuMap.find(instance); @@ -924,74 +1329,69 @@ mlir::LogicalResult assignPipelineCores(const ComputeGraph& graph, error = "pipeline scheduling received an incomplete PEFT schedule"; return mlir::failure(); } - tasksByCpu[cpu->second].push_back(task); } - for (TaskList& tasks : tasksByCpu) - llvm::sort(tasks, [&](size_t lhs, size_t rhs) { - return schedule.computeToCpuSlotMap.lookup(graph.nodes[lhs].instance) - < schedule.computeToCpuSlotMap.lookup(graph.nodes[rhs].instance); - }); PipelineTaskModel taskModel = getPipelineTaskModel( graph, schedule, physicalTarget); - const TaskCosts &taskCosts = taskModel.schedulingCosts; - + FailureOr assignment = assignPipelineStages( + graph, taskModel, balancedLayout, + physicalTarget.residentWeightCapacity, error); + if (failed(assignment)) + return failure(); std::vector tasksByPhysicalCpu(physicalTarget.processorCount); - for (size_t sourceCpu = 0; sourceCpu < groupSize; ++sourceCpu) { - const TaskList& tasks = tasksByCpu[sourceCpu]; - if (tasks.empty()) - continue; - for (size_t task : tasks) - if (graph.nodes[task].residentWeights.size() > physicalTarget.residentWeightCapacity) { - error = "pipeline scheduling cannot fit one compute instance in a physical core's crossbars"; - return mlir::failure(); - } - - Cost maximumCost = findMaximumPackCost( - graph, taskCosts, tasks, physicalTarget.residentWeightCapacity, pipelineStages); - if (!fits(graph, taskCosts, tasks, maximumCost, - physicalTarget.residentWeightCapacity, pipelineStages)) { - error = "pipeline scheduling cannot partition one PEFT core within the physical crossbar limit"; - return mlir::failure(); + std::vector minimumPackableStageSizes(pipelineStages, 1); + std::string packingError; + bool packed = false; + for (size_t attempt = 0; attempt < physicalTarget.processorCount; ++attempt) { + PipelineCoreLayout candidateLayout(assignment->stageSizes); + for (TaskList &tasks : tasksByPhysicalCpu) + tasks.clear(); + for (size_t task = 0; task < graph.nodes.size(); ++task) { + PipelineStageRange range = + candidateLayout.getStageRange(assignment->taskStages[task]); + tasksByPhysicalCpu[range.begin].push_back(task); } - - const size_t desiredPacks = std::min(pipelineStages, tasks.size()); - size_t stage = 0; - Cost packCost = 0; - ResidentWeightSet packWeights; - bool packEmpty = true; - for (size_t index = 0; index < tasks.size(); ++index) { - size_t task = tasks[index]; - const ComputeGraphNode& node = graph.nodes[task]; - Cost taskCost = taskCosts[task]; - bool exceedsLimit = - !packEmpty - && (packCost > maximumCost - taskCost - || getResidentWeightUnionSize(packWeights, node.residentWeights) > physicalTarget.residentWeightCapacity); - bool reserveOneTaskPerPack = !packEmpty && tasks.size() - index == desiredPacks - stage - 1; - if (exceedsLimit || reserveOneTaskPerPack) { - ++stage; - packCost = 0; - packWeights.clear(); - packEmpty = true; - } - if (stage >= pipelineStages) { - error = "pipeline scheduling produced too many packs"; - return mlir::failure(); - } - size_t physicalCpu = sourceCpu + stage * groupSize; - tasksByPhysicalCpu[physicalCpu].push_back(task); - packCost = checkedAdd(packCost, taskCost); - insertResidentWeights(packWeights, node.residentWeights); - packEmpty = false; + size_t failedStage = 0; + if (succeeded(packPipelineStages( + graph, taskModel, tasksByPhysicalCpu, candidateLayout, + pipelineStages, physicalTarget.residentWeightCapacity, + physicalTarget, failedStage, packingError))) { + packed = true; + break; } + minimumPackableStageSizes[failedStage] = std::max( + minimumPackableStageSizes[failedStage], + assignment->stageSizes[failedStage] + 1); + std::optional donor; + for (size_t stage = 0; stage < pipelineStages; ++stage) + if (stage != failedStage + && assignment->stageSizes[stage] + > minimumPackableStageSizes[stage] + && (!donor + || assignment->stageSizes[stage] + > assignment->stageSizes[*donor])) + donor = stage; + if (!donor) + break; + --assignment->stageSizes[*donor]; + ++assignment->stageSizes[failedStage]; } - - rebalancePipelineStages( - graph, taskModel, tasksByPhysicalCpu, groupSize, pipelineStages, - physicalTarget.residentWeightCapacity); + if (!packed) { + error = packingError; + return failure(); + } + PipelineCoreLayout pipelineLayout(assignment->stageSizes); + if (failed(verifyPipelineStageAssignment( + graph, taskModel, tasksByPhysicalCpu, pipelineLayout, error))) + return failure(); schedule.computeToCpuMap.clear(); schedule.processorCount = physicalTarget.processorCount; + schedule.processorStages.resize(physicalTarget.processorCount); + for (size_t stage = 0; stage < pipelineLayout.getStageCount(); ++stage) { + PipelineStageRange range = pipelineLayout.getStageRange(stage); + std::fill_n( + schedule.processorStages.begin() + range.begin, range.size, stage); + } schedule.computeToCpuSlotMap.clear(); schedule.computeToAestMap.clear(); schedule.isLastComputeOfCpu.clear(); @@ -1071,21 +1471,22 @@ mlir::LogicalResult applyPipelineScheduling(const ComputeGraph& graph, std::string& error) { if (pipelineStages == 1) return mlir::success(); - if (pipelineStages == 0 || schedule.processorCount == 0 - || schedule.processorCount > std::numeric_limits::max() / pipelineStages - || schedule.processorCount * pipelineStages != physicalTarget.processorCount) { - error = "pipeline scheduling requires physical cores = scheduled cores * pipeline stages"; + PipelineCoreLayout pipelineLayout( + physicalTarget.processorCount, pipelineStages); + if (!pipelineLayout.isValid() || schedule.processorCount == 0 + || schedule.processorCount + != pipelineLayout.getLogicalProcessorCount()) { + error = "pipeline scheduling requires a valid balanced physical core layout"; return mlir::failure(); } return assignPipelineCores(graph, schedule, pipelineStages, physicalTarget, error); } -mlir::LogicalResult splitPipelineWorkload(const ComputeGraph &graph, - const MergeScheduleResult &schedule, - size_t pipelineStages, - const SchedulingTarget &physicalTarget, - std::string &error) { - return splitPipelineWorkloadImpl( +mlir::FailureOr preparePipelineWorkload( + const ComputeGraph &graph, const MergeScheduleResult &schedule, + size_t pipelineStages, const SchedulingTarget &physicalTarget, + std::string &error) { + return preparePipelineWorkloadImpl( graph, schedule, pipelineStages, physicalTarget, error); } diff --git a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.hpp b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.hpp index 2c75cbc..dabbcbe 100644 --- a/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.hpp +++ b/src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.hpp @@ -2,8 +2,15 @@ #include "mlir/Support/LogicalResult.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" + +#include #include +#include +#include #include +#include #include "ComputeGraph.hpp" #include "MergeSchedule.hpp" @@ -11,16 +18,82 @@ namespace onnx_mlir::spatial { +struct PipelineStageRange { + size_t begin; + size_t size; +}; + +class PipelineCoreLayout { +public: + PipelineCoreLayout(size_t processorCount, size_t stageCount) + : processorCount(processorCount), stageSizes(stageCount) { + if (stageCount == 0) + return; + size_t baseSize = processorCount / stageCount; + size_t largerStageCount = processorCount % stageCount; + for (size_t stage = 0; stage < stageCount; ++stage) + stageSizes[stage] = baseSize + (stage < largerStageCount); + } + + explicit PipelineCoreLayout(llvm::ArrayRef stageSizes) + : processorCount(std::accumulate( + stageSizes.begin(), stageSizes.end(), size_t {0})), + stageSizes(stageSizes.begin(), stageSizes.end()) {} + + bool isValid() const { + return !stageSizes.empty() + && llvm::none_of(stageSizes, [](size_t size) { return size == 0; }); + } + + size_t getLogicalProcessorCount() const { + return isValid() + ? *std::min_element(stageSizes.begin(), stageSizes.end()) + : 0; + } + + size_t getStageCount() const { return stageSizes.size(); } + + size_t getProcessorCount() const { return processorCount; } + + llvm::ArrayRef getStageSizes() const { return stageSizes; } + + PipelineStageRange getStageRange(size_t stage) const { + return {std::accumulate( + stageSizes.begin(), stageSizes.begin() + stage, size_t {0}), + stageSizes[stage]}; + } + + std::optional getStageForCore(size_t core) const { + if (!isValid() || core >= processorCount) + return std::nullopt; + size_t end = 0; + for (auto [stage, size] : llvm::enumerate(stageSizes)) { + end += size; + if (core < end) + return stage; + } + return std::nullopt; + } + +private: + size_t processorCount; + std::vector stageSizes; +}; + mlir::LogicalResult applyPipelineScheduling(const ComputeGraph& graph, MergeScheduleResult& schedule, size_t pipelineStages, const SchedulingTarget& physicalTarget, std::string& error); -mlir::LogicalResult splitPipelineWorkload(const ComputeGraph& graph, - const MergeScheduleResult& schedule, - size_t pipelineStages, - const SchedulingTarget& physicalTarget, - std::string& error); +enum class PipelineWorkloadPreparation { + Ready, + Changed, +}; + +mlir::FailureOr preparePipelineWorkload( + const ComputeGraph& graph, const MergeScheduleResult& schedule, + size_t pipelineStages, const SchedulingTarget& physicalTarget, + std::string& error); } // namespace onnx_mlir::spatial diff --git a/test/PIM/SpatialSchedulingTargetTest.cpp b/test/PIM/SpatialSchedulingTargetTest.cpp index dce2d35..c6c937c 100644 --- a/test/PIM/SpatialSchedulingTargetTest.cpp +++ b/test/PIM/SpatialSchedulingTargetTest.cpp @@ -9,6 +9,36 @@ using namespace onnx_mlir::spatial; int main() { + PipelineCoreLayout unevenLayout(138, 4); + assert(unevenLayout.isValid()); + assert(unevenLayout.getLogicalProcessorCount() == 34); + assert(unevenLayout.getStageRange(0).begin == 0); + assert(unevenLayout.getStageRange(0).size == 35); + assert(unevenLayout.getStageRange(1).begin == 35); + assert(unevenLayout.getStageRange(1).size == 35); + assert(unevenLayout.getStageRange(2).begin == 70); + assert(unevenLayout.getStageRange(2).size == 34); + assert(unevenLayout.getStageRange(3).begin == 104); + assert(unevenLayout.getStageRange(3).size == 34); + assert(unevenLayout.getStageForCore(34) == 0); + assert(unevenLayout.getStageForCore(35) == 1); + assert(unevenLayout.getStageForCore(69) == 1); + assert(unevenLayout.getStageForCore(70) == 2); + assert(unevenLayout.getStageForCore(137) == 3); + assert(!unevenLayout.getStageForCore(138)); + + PipelineCoreLayout dynamicLayout(std::vector {2, 4, 1, 3}); + assert(dynamicLayout.isValid()); + assert(dynamicLayout.getProcessorCount() == 10); + assert(dynamicLayout.getStageRange(0).begin == 0); + assert(dynamicLayout.getStageRange(1).begin == 2); + assert(dynamicLayout.getStageRange(2).begin == 6); + assert(dynamicLayout.getStageRange(3).begin == 7); + assert(dynamicLayout.getStageForCore(1) == 0); + assert(dynamicLayout.getStageForCore(2) == 1); + assert(dynamicLayout.getStageForCore(6) == 2); + assert(dynamicLayout.getStageForCore(9) == 3); + TransferCost transfer {.fixed = 50, .networkFlits = 4}; SchedulingTarget fast; @@ -57,6 +87,13 @@ int main() { }; assert(mapLogicalProcessorsToPhysicalCores(logicalTrafficFlits, alreadyPlaced) == std::vector({0, 1, 2})); + std::vector placementGroups {0, 1, 1}; + std::vector groupedPlacement = mapLogicalProcessorsToPhysicalCores( + logicalTrafficFlits, line, placementGroups); + for (size_t processor = 0; processor < groupedPlacement.size(); ++processor) + assert(placementGroups[processor] + == placementGroups[groupedPlacement[processor]]); + ComputeGraph graph; graph.successors.resize(6); graph.predecessors.resize(6); @@ -71,16 +108,16 @@ int main() { graph.instanceToIndex[instance] = task; } - MergeScheduleResult pipelineSchedule; - pipelineSchedule.processorCount = 2; - pipelineSchedule.dominanceOrderCompute.reserve(graph.nodes.size()); + MergeScheduleResult logicalSchedule; + logicalSchedule.processorCount = 2; + logicalSchedule.dominanceOrderCompute.reserve(graph.nodes.size()); for (size_t task = 0; task < graph.nodes.size(); ++task) { const ComputeInstance& instance = graph.nodes[task].instance; - pipelineSchedule.dominanceOrderCompute.push_back(instance); + logicalSchedule.dominanceOrderCompute.push_back(instance); size_t cpu = task < 4 ? 0 : 1; - pipelineSchedule.computeToCpuMap[instance] = cpu; - pipelineSchedule.computeToCpuSlotMap[instance] = task < 4 ? task : task - 4; - pipelineSchedule.computeToAestMap[instance] = task; + logicalSchedule.computeToCpuMap[instance] = cpu; + logicalSchedule.computeToCpuSlotMap[instance] = task < 4 ? task : task - 4; + logicalSchedule.computeToAestMap[instance] = task; } SchedulingTarget physical = fast; @@ -93,20 +130,50 @@ int main() { 3, 3, 3, 0, }; std::string pipelineError; + MergeScheduleResult pipelineSchedule = logicalSchedule; assert(mlir::succeeded(applyPipelineScheduling( graph, pipelineSchedule, 2, physical, pipelineError))); assert(pipelineSchedule.processorCount == 4); - assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[0].instance) == 0); - assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[1].instance) == 0); - assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[2].instance) == 2); - assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[3].instance) == 2); - assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[4].instance) == 1); - assert(pipelineSchedule.computeToCpuMap.lookup(graph.nodes[5].instance) == 3); + size_t predecessorCore = pipelineSchedule.computeToCpuMap.lookup( + graph.nodes[1].instance); + size_t successorCore = pipelineSchedule.computeToCpuMap.lookup( + graph.nodes[2].instance); assert(pipelineSchedule.computeToAestMap.lookup(graph.nodes[2].instance) >= pipelineSchedule.computeToAestMap.lookup(graph.nodes[1].instance) - + graph.nodes[1].cost + 4); + + graph.nodes[1].cost + + getPeftTransferTime( + TransferCost {.fixed = 1, .networkFlits = 1}, + predecessorCore, successorCore, physical)); + assert(pipelineSchedule.processorStages[predecessorCore] + <= pipelineSchedule.processorStages[successorCore]); + assert(pipelineSchedule.processorStages[successorCore] + <= pipelineSchedule.processorStages[predecessorCore] + 1); assert(pipelineSchedule.equivalentClass.empty()); + graph.successors[0].push_back( + {5, TransferCost {.fixed = 1, .networkFlits = 1}}); + graph.predecessors[5].push_back( + {0, TransferCost {.fixed = 1, .networkFlits = 1}}); + SchedulingTarget fourStagePhysical = physical; + fourStagePhysical.processorCount = 8; + fourStagePhysical.interProcessorLatencyNs.assign(64, 3); + for (size_t core = 0; core < 8; ++core) + fourStagePhysical.interProcessorLatencyNs[core * 8 + core] = 0; + MergeScheduleResult fourStageSchedule = logicalSchedule; + assert(mlir::succeeded(applyPipelineScheduling( + graph, fourStageSchedule, 4, fourStagePhysical, pipelineError))); + for (size_t task = 0; task < graph.nodes.size(); ++task) + for (const auto &[predecessor, cost] : graph.predecessors[task]) { + (void)cost; + size_t sourceStage = fourStageSchedule.processorStages[ + fourStageSchedule.computeToCpuMap.lookup( + graph.nodes[predecessor].instance)]; + size_t targetStage = fourStageSchedule.processorStages[ + fourStageSchedule.computeToCpuMap.lookup(graph.nodes[task].instance)]; + assert(sourceStage <= targetStage); + assert(targetStage <= sourceStage + 1); + } + ComputeGraph communicationGraph; communicationGraph.successors.resize(5); communicationGraph.predecessors.resize(5); @@ -136,15 +203,19 @@ int main() { MergeScheduleResult fastCommunicationSchedule = communicationSchedule; assert(mlir::succeeded(applyPipelineScheduling( communicationGraph, fastCommunicationSchedule, 2, fastPipeline, pipelineError))); - assert(fastCommunicationSchedule.computeToCpuMap.lookup( - communicationGraph.nodes[2].instance) == 2); SchedulingTarget slowPipeline = fastPipeline; slowPipeline.averageInterProcessorLatencyNs = 10; MergeScheduleResult slowCommunicationSchedule = communicationSchedule; assert(mlir::succeeded(applyPipelineScheduling( communicationGraph, slowCommunicationSchedule, 2, slowPipeline, pipelineError))); - assert(slowCommunicationSchedule.computeToCpuMap.lookup( - communicationGraph.nodes[2].instance) < 2); + size_t sourceCore = slowCommunicationSchedule.computeToCpuMap.lookup( + communicationGraph.nodes[4].instance); + size_t targetCore = slowCommunicationSchedule.computeToCpuMap.lookup( + communicationGraph.nodes[3].instance); + assert(slowCommunicationSchedule.processorStages[sourceCore] + <= slowCommunicationSchedule.processorStages[targetCore]); + assert(slowCommunicationSchedule.processorStages[targetCore] + <= slowCommunicationSchedule.processorStages[sourceCore] + 1); return EXIT_SUCCESS; } diff --git a/validation/.gitignore b/validation/.gitignore index 0d62ec7..2f72deb 100644 --- a/validation/.gitignore +++ b/validation/.gitignore @@ -9,6 +9,7 @@ operations/**/*.csv networks/**/inputs networks/**/outputs networks/**/raptor +networks/**/raptor_functional networks/**/pimcomp networks/**/runner networks/**/simulation diff --git a/validation/networks/pimcomp_models/results.csv b/validation/networks/pimcomp_models/results.csv index ec52381..a3d1668 100644 --- a/validation/networks/pimcomp_models/results.csv +++ b/validation/networks/pimcomp_models/results.csv @@ -1,41 +1,61 @@ -model,arch,mode,raptor_pipeline,pimcomp_pipeline,raptor_functional_validation,pimcomp_functional_validation,raptor_throughput_samples_s,pimcomp_throughput_samples_s,raptor_latency_ms,pimcomp_latency_ms,raptor_power_mw,pimcomp_power_mw,raptor_energy_pj,pimcomp_energy_pj,better_compiler,speedup -vgg8,arch-a,latency,1,element,PASS,PASS,NA,NA,1.465778,7.985074,325.627854,200.111367,477298145.040001,1597904071.120000,raptor,5.45 -vgg8,arch-b,latency,1,element,PASS,PASS,NA,NA,1.438869,7.152125,304.673458,173.768633,438385194.040001,1242814988.120001,raptor,4.97 -vgg8,arch-c,latency,1,element,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -vgg8,arch-a,throughput,2,batch,PASS,PASS,1480.000000,1380.000000,0.674197,0.725548,456.064662,475.694103,307477506.200000,345138738.300000,raptor,1.07 -vgg8,arch-b,throughput,2,batch,PASS,PASS,1160.000000,1080.000000,0.861527,0.921878,333.045167,408.540967,286927542.600000,376624916.800000,raptor,1.07 -vgg8,arch-c,throughput,2,batch,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -vgg8,arch-a,throughput,4,batch,PASS,PASS,2160.000000,1380.000000,0.462342,0.725548,446.528150,475.694103,206448818.800000,345138738.300000,raptor,1.57 -vgg8,arch-c,throughput,4,batch,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -vgg8,arch-a,throughput,8,batch,PASS,PASS,831.000000,1380.000000,1.202894,0.725548,331.341726,475.694103,398569128.700000,345138738.300000,pimcomp,1.66 -vgg8,arch-c,throughput,8,batch,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -resnet18,arch-a,latency,1,element,PASS,PASS,NA,NA,28.099951,58.855175,312.513413,237.590194,8781611597.119984,13983412446.119972,raptor,2.09 -resnet18,arch-b,latency,1,element,PASS,PASS,NA,NA,34.938563,65.084209,254.439797,200.986958,8889760875.119959,13081077194.119965,raptor,1.86 -resnet18,arch-c,latency,1,element,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -resnet18,arch-a,throughput,2,batch,PASS,FAIL,20.000000,76.000000,50.000000,13.149606,263.148477,479.788072,13157423870.000000,6309024249.000000,pimcomp,3.80 -resnet18,arch-b,throughput,2,batch,PASS,FAIL,26.300000,83.200000,38.016529,12.020906,250.553072,483.029728,9525158116.000000,5806454916.000000,pimcomp,3.16 -resnet18,arch-c,throughput,2,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -resnet18,arch-a,throughput,4,batch,PASS,FAIL,31.700000,76.000000,31.578947,13.149606,336.949886,479.788072,10640522720.000000,6309024249.000000,pimcomp,2.40 -resnet18,arch-c,throughput,4,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -resnet18,arch-a,throughput,8,batch,PASS,FAIL,46.400000,76.000000,21.566110,13.149606,319.292391,479.788072,6885894954.000000,6309024249.000000,pimcomp,1.64 -resnet18,arch-c,throughput,8,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -resnet34,arch-a,latency,1,element,PASS,PASS,NA,NA,45.781484,91.608751,326.833876,248.044564,14962939889.679951,22723052668.680016,raptor,2.00 -resnet34,arch-b,latency,1,element,PASS,PASS,NA,NA,72.119607,94.519582,239.192092,215.513439,17250439680.679901,20370240175.680019,raptor,1.31 -resnet34,arch-c,latency,1,element,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -resnet34,arch-a,throughput,2,batch,FAIL,FAIL,NA,40.800000,NA,24.522761,NA,506.131154,NA,12411733160.000000,NA,NA -resnet34,arch-b,throughput,2,batch,PASS,FAIL,11.600000,43.300000,86.250000,23.076923,260.049856,489.500435,22429300100.000000,11296163880.000000,pimcomp,3.73 -resnet34,arch-c,throughput,2,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -resnet34,arch-a,throughput,4,batch,FAIL,FAIL,NA,40.800000,NA,24.522761,NA,506.131154,NA,12411733160.000000,NA,NA -resnet34,arch-c,throughput,4,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -resnet34,arch-a,throughput,8,batch,PASS,FAIL,24.300000,40.800000,41.176471,24.522761,271.814969,506.131154,11192381060.000000,12411733160.000000,pimcomp,1.68 -resnet34,arch-c,throughput,8,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -googlenet,arch-a,latency,1,element,PASS,PASS,NA,NA,13.032305,62.923369,465.072002,231.194088,6060960174.919998,14547510894.240002,raptor,4.83 -googlenet,arch-b,latency,1,element,PASS,PASS,NA,NA,16.086822,37.935747,378.951815,242.039077,6096130396.919978,9181933205.239973,raptor,2.36 -googlenet,arch-c,latency,1,element,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -googlenet,arch-a,throughput,2,batch,PASS,FAIL,55.000000,66.200000,18.181818,15.094340,346.696726,434.959232,6303576840.000000,6565422375.000000,pimcomp,1.20 -googlenet,arch-b,throughput,2,batch,PASS,FAIL,55.000000,72.000000,18.181818,13.888889,314.645370,417.992095,5720824912.000000,5805445765.000000,pimcomp,1.31 -googlenet,arch-c,throughput,2,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -googlenet,arch-a,throughput,4,batch,PASS,FAIL,111.000000,66.200000,9.012016,15.094340,373.195227,434.959232,3363241363.000000,6565422375.000000,raptor,1.68 -googlenet,arch-c,throughput,4,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -googlenet,arch-a,throughput,8,batch,PASS,FAIL,61.300000,66.200000,16.310680,15.094340,341.592923,434.959232,5571612719.000000,6565422375.000000,pimcomp,1.08 -googlenet,arch-c,throughput,8,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch,model,mode,raptor_pipeline,pimcomp_pipeline,raptor_functional_validation,pimcomp_functional_validation,raptor_latency_ms,pimcomp_latency_ms,raptor_throughput_samples_s,pimcomp_throughput_samples_s,raptor_power_mw,pimcomp_power_mw,raptor_energy_pj,pimcomp_energy_pj,better_compiler,speedup +arch-a,vgg8,latency,1,element,PASS,PASS,1.47,7.99,NA,NA,325.67,200.11,477232782.04,1597904071.12,raptor,5.45 +arch-a,vgg8,throughput,2,batch,PASS,PASS,0.94,1.04,1060.00,965.00,377.54,482.60,474325940.70,541691691.00,raptor,1.10 +arch-a,vgg8,throughput,4,batch,PASS,PASS,1.19,1.04,839.00,965.00,310.32,482.60,500148858.20,541691691.00,pimcomp,1.15 +arch-a,vgg8,throughput,8,batch,PASS,PASS,1.52,1.04,658.00,965.00,279.37,482.60,554348483.90,541691691.00,pimcomp,1.47 +arch-a,resnet18,latency,1,element,PASS,FAIL,15.65,58.18,NA,NA,425.87,238.39,6666000553.12,13869146503.12,raptor,3.72 +arch-a,resnet18,throughput,2,batch,PASS,FAIL,30.55,13.46,32.70,74.30,295.90,481.60,10218790630.00,6562535800.00,pimcomp,2.27 +arch-a,resnet18,throughput,4,batch,PASS,FAIL,26.60,13.46,37.60,74.30,313.14,481.60,10993189350.00,6562535800.00,pimcomp,1.98 +arch-a,resnet18,throughput,8,batch,PASS,FAIL,35.51,13.46,28.20,74.30,275.95,481.60,12844245960.00,6562535800.00,pimcomp,2.63 +arch-a,resnet34,latency,1,element,PASS,FAIL,32.37,66.71,NA,NA,391.82,277.48,12684227802.68,18511540483.68,raptor,2.06 +arch-a,resnet34,throughput,2,batch,FAIL,FAIL,NA,23.58,NA,42.40,NA,515.66,NA,12277699310.00,NA,NA +arch-a,resnet34,throughput,4,batch,FAIL,FAIL,NA,23.58,NA,42.40,NA,515.66,NA,12277699310.00,NA,NA +arch-a,resnet34,throughput,8,batch,PASS,FAIL,115.11,23.58,8.69,42.40,229.85,515.66,29881854960.00,12277699310.00,pimcomp,4.88 +arch-a,googlenet,latency,1,element,PASS,PASS,13.03,62.92,NA,NA,465.11,231.19,6060646341.92,14547510894.24,raptor,4.83 +arch-a,googlenet,throughput,2,batch,PASS,FAIL,24.01,18.27,41.70,54.70,328.17,435.11,8529823770.00,8164469406.00,pimcomp,1.31 +arch-a,googlenet,throughput,4,batch,PASS,FAIL,27.01,18.27,37.00,54.70,305.68,435.11,10498372450.00,8164469406.00,pimcomp,1.48 +arch-a,googlenet,throughput,8,batch,PASS,FAIL,40.03,18.27,25.00,54.70,268.61,435.11,15290418970.00,8164469406.00,pimcomp,2.19 +arch-a,yolo11n,latency,1,element,PASS,FAIL,267.73,NA,NA,NA,235.73,NA,63111612279.00,NA,NA,NA +arch-a,yolo11n,throughput,2,batch,PASS,FAIL,500.00,NA,2.00,NA,227.74,NA,113867559100.00,NA,NA,NA +arch-a,yolo11n,throughput,4,batch,PASS,FAIL,500.00,NA,2.00,NA,233.16,NA,116581237400.00,NA,NA,NA +arch-a,yolo11n,throughput,8,batch,PASS,FAIL,500.00,NA,2.00,NA,253.59,NA,126797224900.00,NA,NA,NA +arch-b,vgg8,latency,1,element,PASS,PASS,1.44,7.15,NA,NA,304.72,173.77,438329594.04,1242814988.12,raptor,4.97 +arch-b,vgg8,throughput,2,batch,PASS,PASS,1.56,1.07,640.00,932.00,287.50,409.47,478592086.00,439288835.80,pimcomp,1.46 +arch-b,vgg8,throughput,4,batch,PASS,PASS,1.14,1.07,874.00,932.00,323.79,409.47,457617420.30,439288835.80,pimcomp,1.07 +arch-b,vgg8,throughput,8,batch,PASS,PASS,1.48,1.07,676.00,932.00,282.34,409.47,437422264.40,439288835.80,pimcomp,1.38 +arch-b,resnet18,latency,1,element,PASS,FAIL,17.98,64.38,NA,NA,362.63,201.66,6520518736.12,12983607699.12,raptor,3.58 +arch-b,resnet18,throughput,2,batch,PASS,FAIL,33.84,13.43,29.60,74.40,253.32,484.80,9423636948.00,6569655551.00,pimcomp,2.51 +arch-b,resnet18,throughput,4,batch,PASS,FAIL,26.14,13.43,38.30,74.40,286.86,484.80,9493311384.00,6569655551.00,pimcomp,1.94 +arch-b,resnet18,throughput,8,batch,PASS,FAIL,28.29,13.43,35.30,74.40,272.66,484.80,11314980340.00,6569655551.00,pimcomp,2.11 +arch-b,resnet34,latency,1,element,PASS,FAIL,49.51,107.20,NA,NA,284.72,206.47,14097763205.68,22134333948.68,raptor,2.17 +arch-b,resnet34,throughput,2,batch,PASS,FAIL,93.13,22.80,10.70,43.90,215.38,493.39,21278771500.00,11381213070.00,pimcomp,4.10 +arch-b,resnet34,throughput,4,batch,PASS,FAIL,67.55,22.80,14.80,43.90,237.97,493.39,19346594270.00,11381213070.00,pimcomp,2.97 +arch-b,resnet34,throughput,8,batch,PASS,FAIL,115.01,22.80,8.70,43.90,197.27,493.39,26678372930.00,11381213070.00,pimcomp,5.05 +arch-b,googlenet,latency,1,element,PASS,PASS,16.08,37.94,NA,NA,378.99,242.04,6095729659.92,9181933205.24,raptor,2.36 +arch-b,googlenet,throughput,2,batch,PASS,FAIL,28.37,21.39,35.20,46.70,267.15,417.83,8684222064.00,9014655684.00,pimcomp,1.33 +arch-b,googlenet,throughput,4,batch,PASS,FAIL,26.16,21.39,38.20,46.70,280.21,417.83,9300527914.00,9014655684.00,pimcomp,1.22 +arch-b,googlenet,throughput,8,batch,PASS,FAIL,46.45,21.39,21.50,46.70,237.73,417.83,14078049200.00,9014655684.00,pimcomp,2.17 +arch-b,yolo11n,latency,1,element,PASS,FAIL,316.70,NA,NA,NA,195.43,NA,61892225295.00,NA,NA,NA +arch-b,yolo11n,throughput,2,batch,PASS,FAIL,333.33,NA,3.00,NA,214.01,NA,71336401290.00,NA,NA,NA +arch-b,yolo11n,throughput,4,batch,PASS,FAIL,333.33,NA,3.00,NA,216.24,NA,72079194110.00,NA,NA,NA +arch-b,yolo11n,throughput,8,batch,PASS,FAIL,500.00,NA,2.00,NA,218.42,NA,109211119900.00,NA,NA,NA +arch-c,vgg8,latency,1,element,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,vgg8,throughput,2,batch,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,vgg8,throughput,4,batch,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,vgg8,throughput,8,batch,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,resnet18,latency,1,element,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,resnet18,throughput,2,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,resnet18,throughput,4,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,resnet18,throughput,8,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,resnet34,latency,1,element,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,resnet34,throughput,2,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,resnet34,throughput,4,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,resnet34,throughput,8,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,googlenet,latency,1,element,FAIL,PASS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,googlenet,throughput,2,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,googlenet,throughput,4,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,googlenet,throughput,8,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,yolo11n,latency,1,element,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,yolo11n,throughput,2,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,yolo11n,throughput,4,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +arch-c,yolo11n,throughput,8,batch,FAIL,FAIL,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA diff --git a/validation/operations/validation_results.csv b/validation/operations/validation_results.csv index 93b0945..ab2d740 100644 --- a/validation/operations/validation_results.csv +++ b/validation/operations/validation_results.csv @@ -1,178 +1,178 @@ Operation,Arch,Result (l),Result (t),Compile (l),Host mem (l),Cores mem (l),Cores (l),Xbars (l),Latency (l),Power (l),Energy (l),Compile (t),Host mem (t),Cores mem (t),Cores (t),Xbars (t),Avg latency (t),Throughput (t),Avg power (t),Avg energy (t) -add/after_gemm,arch-a,PASS,PASS,0.058 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,104.70 mW,815012.96 pJ,0.057 s,0.01 MiB,0.01 MiB,6,4,145000.00 samples/s,0.01 ms,31.45 mW,216167.21 pJ/it -add/basic,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.050 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -add/broadcast_row,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.051 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -add/channel_broadcast_1024,arch-a,PASS,PASS,0.049 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.051 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it -add/leading_dimension_broadcast,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.049 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -concat/channel_axis,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.16 mW,35718.00 pJ,0.050 s,0.00 MiB,0.00 MiB,1,0,2200000.00 samples/s,0.00 ms,2.16 mW,934.67 pJ/it -concat/negative_axis,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.09 mW,81450.00 pJ,0.051 s,0.00 MiB,0.00 MiB,1,0,961000.00 samples/s,0.00 ms,2.09 mW,2108.00 pJ/it -concat/three_inputs_channel_axis,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.15 mW,50328.00 pJ,0.047 s,0.00 MiB,0.00 MiB,1,0,1560000.00 samples/s,0.00 ms,2.15 mW,1332.67 pJ/it -conv/batch_2,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.00 MiB,2,2,0.01 ms,82.62 mW,1131451.48 pJ,0.062 s,0.00 MiB,0.01 MiB,4,2,129000.00 samples/s,0.01 ms,51.25 mW,406238.48 pJ/it -conv/batch_4_pointwise,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.01 MiB,5,4,0.00 ms,116.08 mW,456420.96 pJ,0.061 s,0.00 MiB,0.01 MiB,5,4,243000.00 samples/s,0.00 ms,44.13 mW,180813.46 pJ/it -conv/depthwise_1024_channels,arch-a,PASS,PASS,0.080 s,0.19 MiB,0.38 MiB,129,128,0.22 ms,178.45 mW,39393966.72 pJ,0.141 s,0.36 MiB,0.48 MiB,87,128,3620.00 samples/s,0.28 ms,131.43 mW,37256350.26 pJ/it -conv/depthwise_grouped,arch-a,PASS,PASS,0.056 s,0.01 MiB,0.00 MiB,5,4,0.01 ms,107.78 mW,671878.96 pJ,0.061 s,0.01 MiB,0.00 MiB,7,4,235000.00 samples/s,0.00 ms,53.10 mW,227356.96 pJ/it -conv/dilated_3x3,arch-a,PASS,PASS,0.061 s,0.01 MiB,0.01 MiB,10,9,0.01 ms,118.77 mW,1034819.16 pJ,0.071 s,0.01 MiB,0.01 MiB,12,9,119000.00 samples/s,0.01 ms,61.00 mW,511357.16 pJ/it -conv/dynamic,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,92.28 mW,169336.00 pJ,0.057 s,0.00 MiB,0.00 MiB,6,0,784000.00 samples/s,0.00 ms,18.61 mW,26517.00 pJ/it -conv/explicit_padding,arch-a,PASS,PASS,0.060 s,0.01 MiB,0.02 MiB,17,16,0.01 ms,145.34 mW,1454397.84 pJ,0.064 s,0.01 MiB,0.02 MiB,19,16,153000.00 samples/s,0.01 ms,109.61 mW,715669.59 pJ/it -conv/grouped_many_groups,arch-a,PASS,PASS,0.498 s,0.05 MiB,0.09 MiB,65,64,0.18 ms,142.21 mW,25867112.36 pJ,0.547 s,0.11 MiB,0.79 MiB,127,64,3750.00 samples/s,0.27 ms,141.11 mW,43353235.67 pJ/it -conv/grouped_two_groups,arch-a,PASS,PASS,0.064 s,0.00 MiB,0.00 MiB,3,2,0.01 ms,101.46 mW,543914.48 pJ,0.066 s,0.00 MiB,0.01 MiB,9,2,146000.00 samples/s,0.01 ms,108.34 mW,741101.98 pJ/it -conv/huge_pointwise_1024,arch-a,PASS,PASS,0.166 s,0.01 MiB,0.11 MiB,73,64,0.02 ms,249.55 mW,3896647.36 pJ,0.182 s,0.04 MiB,0.11 MiB,74,64,33300.00 samples/s,0.03 ms,133.89 mW,4052259.07 pJ/it -conv/huge_pointwise_1024_dynamic,arch-a,PASS,PASS,0.084 s,8.04 MiB,12.61 MiB,168,0,2.63 ms,169.52 mW,445489032.00 pJ,0.263 s,11.49 MiB,10.61 MiB,127,0,213.00 samples/s,4.70 ms,164.24 mW,811591564.70 pJ/it -conv/input_224_7x7_stride2,arch-a,PASS,PASS,0.775 s,24.14 MiB,61.87 MiB,168,169,38.41 ms,185.26 mW,7116544212.12 pJ,1.142 s,46.43 MiB,73.41 MiB,126,153,27.30 samples/s,36.66 ms,177.05 mW,6915042527.00 pJ/it -conv/kernel_2x2,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,1,1,0.00 ms,83.83 mW,360568.24 pJ,0.055 s,0.00 MiB,0.00 MiB,3,1,334000.00 samples/s,0.00 ms,51.45 mW,171905.91 pJ/it -conv/kernel_3x3,arch-a,PASS,PASS,0.060 s,0.01 MiB,0.01 MiB,10,9,0.01 ms,123.80 mW,889640.16 pJ,0.063 s,0.01 MiB,0.01 MiB,12,9,219000.00 samples/s,0.00 ms,83.71 mW,382318.91 pJ/it -conv/kernel_equals_input_spatial,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,2,2,0.00 ms,89.61 mW,415689.48 pJ,0.057 s,0.00 MiB,0.00 MiB,4,2,293000.00 samples/s,0.00 ms,59.39 mW,204713.48 pJ/it -conv/large_input_channels_1x1,arch-a,PASS,PASS,0.096 s,0.01 MiB,0.02 MiB,9,8,0.01 ms,117.82 mW,901121.92 pJ,0.092 s,0.01 MiB,0.02 MiB,10,8,132000.00 samples/s,0.01 ms,59.24 mW,447909.92 pJ/it -conv/large_output_channels_1x1,arch-a,PASS,PASS,0.089 s,0.01 MiB,0.02 MiB,17,8,0.01 ms,128.44 mW,1139415.92 pJ,0.095 s,0.01 MiB,0.02 MiB,18,8,123000.00 samples/s,0.01 ms,43.92 mW,355735.17 pJ/it -conv/large_spatial,arch-a,PASS,PASS,0.059 s,0.01 MiB,0.04 MiB,37,36,0.02 ms,172.07 mW,2928344.64 pJ,0.078 s,0.01 MiB,0.04 MiB,39,36,88500.00 samples/s,0.01 ms,169.91 mW,1920027.89 pJ/it -conv/multi_channel,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,105.68 mW,685040.72 pJ,0.060 s,0.00 MiB,0.00 MiB,4,3,146000.00 samples/s,0.01 ms,30.09 mW,205787.97 pJ/it -conv/non_square_kernel_1x3,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,3,2,0.01 ms,99.35 mW,679752.48 pJ,0.059 s,0.00 MiB,0.00 MiB,3,2,141000.00 samples/s,0.01 ms,12.12 mW,85739.48 pJ/it -conv/non_square_kernel_3x1,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.00 MiB,3,2,0.01 ms,95.89 mW,1292976.48 pJ,0.061 s,0.00 MiB,0.00 MiB,3,2,72900.00 samples/s,0.01 ms,8.83 mW,121109.48 pJ/it -conv/non_uniform_stride,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,104.05 mW,790874.72 pJ,0.059 s,0.00 MiB,0.00 MiB,4,3,131000.00 samples/s,0.01 ms,29.05 mW,221084.97 pJ/it -conv/output_channel_grouping_minimal,arch-a,PASS,PASS,0.089 s,0.10 MiB,0.34 MiB,131,128,0.26 ms,170.73 mW,44125916.72 pJ,0.181 s,0.18 MiB,0.33 MiB,131,128,3910.00 samples/s,0.26 ms,181.50 mW,48146979.72 pJ/it -conv/pointwise_1x1,arch-a,PASS,PASS,0.071 s,0.00 MiB,0.00 MiB,1,1,0.01 ms,80.24 mW,987244.24 pJ,0.084 s,0.00 MiB,0.00 MiB,3,1,131000.00 samples/s,0.01 ms,47.08 mW,380210.74 pJ/it -conv/pointwise_tiled_chain,arch-a,PASS,PASS,0.819 s,0.01 MiB,0.04 MiB,20,80,0.04 ms,153.88 mW,6445455.20 pJ,0.777 s,0.05 MiB,0.08 MiB,22,80,12500.00 samples/s,0.08 ms,69.67 mW,5573378.45 pJ/it -conv/real_asymmetric_padding,arch-a,PASS,PASS,0.074 s,0.01 MiB,0.03 MiB,29,28,0.01 ms,153.67 mW,2221606.72 pJ,0.087 s,0.00 MiB,0.03 MiB,31,28,104000.00 samples/s,0.01 ms,135.38 mW,1295814.97 pJ/it -conv/relu_conv_store,arch-a,PASS,PASS,0.102 s,0.16 MiB,0.67 MiB,168,184,0.56 ms,183.08 mW,103057892.80 pJ,0.291 s,0.32 MiB,0.67 MiB,168,166,1640.00 samples/s,0.61 ms,182.39 mW,113644022.20 pJ/it -conv/same_lower_3x3,arch-a,PASS,PASS,0.069 s,0.01 MiB,0.02 MiB,26,25,0.01 ms,166.15 mW,2215009.00 pJ,0.088 s,0.01 MiB,0.03 MiB,28,25,114000.00 samples/s,0.01 ms,134.46 mW,1180460.00 pJ/it -conv/same_padding_3x3,arch-a,PASS,PASS,0.062 s,0.01 MiB,0.02 MiB,26,25,0.01 ms,166.15 mW,2215009.00 pJ,0.083 s,0.01 MiB,0.03 MiB,28,25,114000.00 samples/s,0.01 ms,134.46 mW,1180460.00 pJ/it -conv/strategy_depthwise_16,arch-a,PASS,PASS,0.093 s,0.06 MiB,0.35 MiB,168,168,0.34 ms,197.94 mW,66331479.08 pJ,0.298 s,0.15 MiB,0.37 MiB,168,168,2890.00 samples/s,0.35 ms,196.87 mW,70672344.81 pJ/it -conv/strategy_input_k_tiled,arch-a,PASS,PASS,0.079 s,0.08 MiB,0.27 MiB,109,108,0.35 ms,170.81 mW,60422605.92 pJ,0.120 s,0.16 MiB,0.30 MiB,85,101,3520.00 samples/s,0.28 ms,138.29 mW,40167697.42 pJ/it -conv/strategy_output_channel_tiled,arch-a,PASS,PASS,0.079 s,0.03 MiB,0.16 MiB,74,72,0.09 ms,155.74 mW,14244739.28 pJ,0.146 s,0.08 MiB,0.25 MiB,111,72,12000.00 samples/s,0.08 ms,137.73 mW,12695085.91 pJ/it -conv/strategy_streamed_packed,arch-a,PASS,PASS,0.168 s,3.34 MiB,7.89 MiB,168,168,9.35 ms,179.86 mW,1682364509.56 pJ,0.453 s,5.38 MiB,7.87 MiB,127,126,119.00 samples/s,8.39 ms,175.52 mW,1616768905.00 pJ/it -conv/strategy_streamed_patch,arch-a,PASS,PASS,0.110 s,0.34 MiB,1.32 MiB,168,168,1.90 ms,181.91 mW,346476645.64 pJ,0.416 s,0.84 MiB,1.29 MiB,127,126,525.00 samples/s,1.90 ms,176.18 mW,359355537.30 pJ/it -conv/strategy_tiled_2d,arch-a,PASS,PASS,0.170 s,0.11 MiB,0.44 MiB,168,168,0.42 ms,182.13 mW,75690907.84 pJ,0.235 s,0.28 MiB,0.45 MiB,130,168,3010.00 samples/s,0.33 ms,178.45 mW,62153061.01 pJ/it -conv/stride_2,arch-a,PASS,PASS,0.060 s,0.01 MiB,0.00 MiB,5,4,0.01 ms,110.78 mW,580154.96 pJ,0.061 s,0.01 MiB,0.00 MiB,7,4,297000.00 samples/s,0.00 ms,48.26 mW,163092.63 pJ/it -conv/with_bias_3x3,arch-a,PASS,PASS,0.069 s,0.00 MiB,0.01 MiB,4,3,0.01 ms,104.16 mW,776220.72 pJ,0.066 s,0.00 MiB,0.01 MiB,4,3,128000.00 samples/s,0.01 ms,28.71 mW,224217.97 pJ/it -conv/with_constant,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.00 MiB,1,1,0.01 ms,81.74 mW,541270.24 pJ,0.067 s,0.00 MiB,0.00 MiB,4,1,138000.00 samples/s,0.01 ms,90.41 mW,664255.74 pJ/it -conv/without_kernel_shape_attr,arch-a,PASS,PASS,0.064 s,0.01 MiB,0.01 MiB,10,9,0.01 ms,123.80 mW,889640.16 pJ,0.066 s,0.01 MiB,0.01 MiB,12,9,219000.00 samples/s,0.00 ms,83.71 mW,382318.91 pJ/it -conv/yolo11n_depthwise_head,arch-a,PASS,PASS,2.447 s,8.66 MiB,34.24 MiB,168,255,42.70 ms,200.52 mW,8562449708.00 pJ,3.011 s,22.90 MiB,34.20 MiB,168,216,19.40 samples/s,51.59 ms,195.15 mW,10205156420.00 pJ/it -conv/yolo11n_heavy,arch-a,PASS,PASS,0.585 s,4.82 MiB,19.10 MiB,161,800,8.54 ms,350.86 mW,2994764012.00 pJ,1.897 s,10.40 MiB,20.59 MiB,161,800,83.80 samples/s,11.93 ms,299.23 mW,3739084612.00 pJ/it -conv/yolo11n_stem,arch-a,PASS,PASS,0.996 s,12.86 MiB,37.59 MiB,168,488,14.24 ms,301.23 mW,4289558753.00 pJ,1.726 s,22.34 MiB,32.79 MiB,168,362,23.80 samples/s,42.04 ms,214.78 mW,9030156087.00 pJ/it -div/after_gemm,arch-a,PASS,PASS,0.065 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,104.70 mW,815012.96 pJ,0.071 s,0.01 MiB,0.01 MiB,6,4,145000.00 samples/s,0.01 ms,31.45 mW,216167.21 pJ/it -div/basic,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.057 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -div/channel_broadcast_1024,arch-a,PASS,PASS,0.060 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.056 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it -div/leading_dimension_broadcast,arch-a,PASS,PASS,0.067 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.060 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -div/runtime_scalar_rhs,arch-a,PASS,PASS,0.057 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.055 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it -div/scalar_constant,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.055 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -gather/3d_input_axis1,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.08 mW,45990.00 pJ,0.056 s,0.00 MiB,0.00 MiB,1,0,1700000.00 samples/s,0.00 ms,2.08 mW,1174.67 pJ/it -gather/axis0_matrix_indices,arch-a,PASS,PASS,0.083 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.07 mW,54414.00 pJ,0.072 s,0.00 MiB,0.00 MiB,1,0,1440000.00 samples/s,0.00 ms,2.07 mW,1390.67 pJ/it -gather/axis1,arch-a,PASS,PASS,0.064 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.06 mW,62526.00 pJ,0.066 s,0.00 MiB,0.00 MiB,1,0,1250000.00 samples/s,0.00 ms,2.06 mW,1598.67 pJ/it -gather/negative_axis,arch-a,PASS,PASS,0.078 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.03 mW,112134.00 pJ,0.064 s,0.00 MiB,0.00 MiB,1,0,697000.00 samples/s,0.00 ms,2.03 mW,2870.67 pJ/it -gather/negative_indices,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.13 mW,29376.00 pJ,0.062 s,0.00 MiB,0.00 MiB,1,0,2670000.00 samples/s,0.00 ms,2.12 mW,748.67 pJ/it -gemm/alpha_beta,arch-a,PASS,PASS,0.068 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,105.27 mW,784908.96 pJ,0.070 s,0.01 MiB,0.01 MiB,6,4,153000.00 samples/s,0.01 ms,32.18 mW,210663.21 pJ/it -gemm/bias_rank2_broadcast,arch-a,PASS,PASS,0.063 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,105.98 mW,749484.96 pJ,0.063 s,0.01 MiB,0.01 MiB,6,4,168000.00 samples/s,0.01 ms,33.68 mW,200469.21 pJ/it -gemm/dynamic,arch-a,PASS,PASS,0.065 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.48 mW,221475.00 pJ,0.062 s,0.00 MiB,0.00 MiB,5,0,471000.00 samples/s,0.00 ms,20.30 mW,43105.75 pJ/it -gemm/dynamic_alpha,arch-a,PASS,PASS,0.064 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.42 mW,298198.00 pJ,0.063 s,0.00 MiB,0.00 MiB,5,0,337000.00 samples/s,0.00 ms,20.28 mW,60117.75 pJ/it -gemm/dynamic_beta,arch-a,PASS,PASS,0.070 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.32 mW,398595.00 pJ,0.059 s,0.00 MiB,0.00 MiB,5,0,246000.00 samples/s,0.00 ms,20.21 mW,82201.75 pJ/it -gemm/dynamic_bias,arch-a,PASS,PASS,0.066 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.45 mW,243703.00 pJ,0.063 s,0.00 MiB,0.00 MiB,5,0,422000.00 samples/s,0.00 ms,20.28 mW,48009.75 pJ/it -gemm/dynamic_bias_alpha_beta,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,5,0,0.01 ms,91.28 mW,513811.00 pJ,0.077 s,0.00 MiB,0.00 MiB,5,0,188000.00 samples/s,0.01 ms,20.20 mW,107673.75 pJ/it -gemm/dynamic_transpose_b,arch-a,PASS,PASS,0.064 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.38 mW,118883.00 pJ,0.065 s,0.00 MiB,0.00 MiB,5,0,781000.00 samples/s,0.00 ms,20.51 mW,26151.50 pJ/it -gemm/huge_1024,arch-a,PASS,PASS,0.182 s,0.01 MiB,0.10 MiB,73,64,0.02 ms,215.04 mW,3767885.36 pJ,0.220 s,0.03 MiB,0.10 MiB,73,64,36900.00 samples/s,0.03 ms,148.63 mW,4053069.50 pJ/it -gemm/large,arch-a,PASS,PASS,0.074 s,0.02 MiB,0.03 MiB,17,16,0.01 ms,140.15 mW,1573768.84 pJ,0.082 s,0.02 MiB,0.03 MiB,17,16,88800.00 samples/s,0.01 ms,84.59 mW,942235.51 pJ/it -gemm/large_k_small_n,arch-a,PASS,PASS,0.142 s,0.01 MiB,0.01 MiB,9,8,0.00 ms,133.48 mW,633769.92 pJ,0.119 s,0.01 MiB,0.01 MiB,9,8,194000.00 samples/s,0.01 ms,76.91 mW,390598.09 pJ/it -gemm/non_square,arch-a,PASS,PASS,0.069 s,0.00 MiB,0.01 MiB,5,4,0.00 ms,118.96 mW,419565.96 pJ,0.069 s,0.00 MiB,0.01 MiB,5,4,270000.00 samples/s,0.00 ms,46.78 mW,172713.46 pJ/it -gemm/scalar_bias,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,105.98 mW,749484.96 pJ,0.066 s,0.01 MiB,0.01 MiB,6,4,168000.00 samples/s,0.01 ms,33.68 mW,200469.21 pJ/it -gemm/small,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.00 MiB,2,2,0.00 ms,90.14 mW,398436.48 pJ,0.059 s,0.00 MiB,0.00 MiB,4,2,327000.00 samples/s,0.00 ms,61.13 mW,188023.48 pJ/it -gemm/small_k_large_n,arch-a,PASS,PASS,0.112 s,0.01 MiB,0.02 MiB,17,8,0.01 ms,131.01 mW,1043061.92 pJ,0.100 s,0.01 MiB,0.02 MiB,18,8,141000.00 samples/s,0.01 ms,47.48 mW,336507.17 pJ/it -gemm/square_weights,arch-a,PASS,PASS,0.080 s,0.03 MiB,0.08 MiB,42,40,0.02 ms,151.77 mW,3284393.60 pJ,0.100 s,0.03 MiB,0.09 MiB,44,40,51800.00 samples/s,0.02 ms,115.71 mW,2278356.60 pJ/it -gemm/transpose_a,arch-a,PASS,PASS,0.063 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,109.14 mW,628868.96 pJ,0.062 s,0.00 MiB,0.01 MiB,6,4,212000.00 samples/s,0.00 ms,38.03 mW,179501.21 pJ/it -gemm/transpose_a_and_b,arch-a,PASS,PASS,0.070 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,109.14 mW,628868.96 pJ,0.080 s,0.00 MiB,0.01 MiB,6,4,212000.00 samples/s,0.00 ms,38.03 mW,179501.21 pJ/it -gemm/transpose_b,arch-a,PASS,PASS,0.065 s,0.00 MiB,0.01 MiB,5,4,0.00 ms,118.96 mW,419565.96 pJ,0.069 s,0.00 MiB,0.01 MiB,5,4,270000.00 samples/s,0.00 ms,46.78 mW,172713.46 pJ/it -gemm/transpose_b_with_bias,arch-a,PASS,PASS,0.064 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,110.55 mW,557818.96 pJ,0.071 s,0.01 MiB,0.01 MiB,5,4,191000.00 samples/s,0.01 ms,38.98 mW,203117.46 pJ/it -gemm/with_bias,arch-a,PASS,PASS,0.064 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,108.77 mW,604966.96 pJ,0.062 s,0.01 MiB,0.01 MiB,5,4,175000.00 samples/s,0.01 ms,37.33 mW,213443.71 pJ/it -gemv/all_constant,arch-a,PASS,PASS,0.071 s,0.00 MiB,0.00 MiB,0,0,0.00 ms,2.00 mW,0.00 pJ,0.061 s,0.00 MiB,0.00 MiB,0,0,0.00 samples/s,0.00 ms,2.00 mW,0.00 pJ/it -gemv/constant_weight,arch-a,PASS,PASS,0.100 s,0.00 MiB,0.01 MiB,6,4,0.01 ms,111.15 mW,573535.96 pJ,0.079 s,0.00 MiB,0.01 MiB,8,4,235000.00 samples/s,0.00 ms,68.14 mW,293181.96 pJ/it -gemv/non_uniform_bias,arch-a,PASS,PASS,0.080 s,0.00 MiB,0.01 MiB,6,4,0.01 ms,109.82 mW,609371.96 pJ,0.081 s,0.00 MiB,0.01 MiB,8,4,215000.00 samples/s,0.00 ms,66.23 mW,310779.96 pJ/it -gemv/scalar_bias,arch-a,PASS,PASS,0.092 s,0.00 MiB,0.01 MiB,6,4,0.01 ms,109.82 mW,609371.96 pJ,0.095 s,0.00 MiB,0.01 MiB,8,4,215000.00 samples/s,0.00 ms,66.23 mW,310779.96 pJ/it -gemv/uniform_bias,arch-a,PASS,PASS,0.090 s,0.00 MiB,0.01 MiB,6,4,0.01 ms,109.82 mW,609371.96 pJ,0.149 s,0.00 MiB,0.01 MiB,8,4,215000.00 samples/s,0.00 ms,66.23 mW,310779.96 pJ/it -matmul/basic,arch-a,PASS,PASS,0.089 s,0.00 MiB,0.00 MiB,2,2,0.00 ms,90.14 mW,398436.48 pJ,0.071 s,0.00 MiB,0.00 MiB,4,2,327000.00 samples/s,0.00 ms,61.13 mW,188023.48 pJ/it -matmul/batched_3d,arch-a,PASS,PASS,0.099 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,108.59 mW,646972.96 pJ,0.086 s,0.00 MiB,0.01 MiB,6,4,207000.00 samples/s,0.00 ms,37.52 mW,181507.21 pJ/it -matmul/batched_3d_dynamic,arch-a,PASS,PASS,0.065 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,92.19 mW,167975.00 pJ,0.065 s,0.00 MiB,0.00 MiB,5,0,736000.00 samples/s,0.00 ms,17.42 mW,23971.67 pJ/it -matmul/batched_left_constant,arch-a,PASS,PASS,0.069 s,0.00 MiB,0.02 MiB,9,8,0.01 ms,114.39 mW,1009105.92 pJ,0.070 s,0.01 MiB,0.02 MiB,11,8,133000.00 samples/s,0.01 ms,58.19 mW,441494.75 pJ/it -matmul/batched_lhs_broadcast,arch-a,PASS,PASS,0.065 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,109.39 mW,621440.96 pJ,0.071 s,0.00 MiB,0.01 MiB,6,4,217000.00 samples/s,0.00 ms,38.52 mW,177665.21 pJ/it -matmul/batched_rhs_broadcast,arch-a,PASS,PASS,0.065 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,108.59 mW,646972.96 pJ,0.065 s,0.00 MiB,0.01 MiB,6,4,207000.00 samples/s,0.00 ms,37.52 mW,181507.21 pJ/it -matmul/dynamic,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.42 mW,148195.00 pJ,0.080 s,0.00 MiB,0.00 MiB,5,0,628000.00 samples/s,0.00 ms,20.41 mW,32505.75 pJ/it -matmul/huge_1024,arch-a,PASS,PASS,0.188 s,0.01 MiB,0.10 MiB,73,64,0.02 ms,215.04 mW,3767885.36 pJ,0.224 s,0.03 MiB,0.10 MiB,73,64,36900.00 samples/s,0.03 ms,148.63 mW,4053069.50 pJ/it -matmul/left_constant,arch-a,PASS,PASS,0.076 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,108.86 mW,637168.96 pJ,0.068 s,0.00 MiB,0.01 MiB,6,4,208000.00 samples/s,0.00 ms,37.62 mW,180976.21 pJ/it -matmul/matrix_vector,arch-a,PASS,PASS,0.120 s,0.52 MiB,0.78 MiB,168,173,0.38 ms,202.13 mW,77751814.88 pJ,0.384 s,0.97 MiB,0.72 MiB,127,173,2250.00 samples/s,0.44 ms,193.72 mW,92630594.79 pJ/it -matmul/vector_matrix,arch-a,PASS,PASS,0.099 s,0.01 MiB,0.01 MiB,9,8,0.01 ms,118.68 mW,879301.92 pJ,0.104 s,0.01 MiB,0.01 MiB,9,8,132000.00 samples/s,0.01 ms,45.10 mW,342617.42 pJ/it -matmul/yolo_attention,arch-a,PASS,PASS,0.526 s,1.02 MiB,43.44 MiB,168,0,8.15 ms,170.00 mW,1385775865.00 pJ,0.796 s,13.76 MiB,43.56 MiB,136,0,65.40 samples/s,15.29 ms,166.46 mW,2545338467.00 pJ/it -mul/after_conv,arch-a,PASS,PASS,0.072 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,107.64 mW,586955.72 pJ,0.072 s,0.00 MiB,0.00 MiB,4,3,183000.00 samples/s,0.01 ms,32.66 mW,178132.97 pJ/it -mul/after_conv_scalar_constant,arch-a,PASS,PASS,0.120 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,107.64 mW,586955.72 pJ,0.160 s,0.00 MiB,0.00 MiB,4,3,183000.00 samples/s,0.01 ms,32.66 mW,178132.97 pJ/it -mul/basic,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.086 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -mul/channel_broadcast_1024,arch-a,PASS,PASS,0.063 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.061 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it -mul/leading_dimension_broadcast,arch-a,PASS,PASS,0.064 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.059 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -mul/scalar_constant,arch-a,PASS,PASS,0.065 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.066 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -pool/avg_basic,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.02 mW,931506.00 pJ,0.063 s,0.00 MiB,0.00 MiB,1,0,84000.00 samples/s,0.01 ms,2.02 mW,24067.00 pJ/it -pool/avg_ceil_mode,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.03 mW,340146.00 pJ,0.057 s,0.00 MiB,0.00 MiB,1,0,230000.00 samples/s,0.00 ms,2.03 mW,8810.67 pJ/it -pool/avg_explicit_padding,arch-a,PASS,PASS,0.125 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.03 mW,688356.00 pJ,0.077 s,0.00 MiB,0.00 MiB,1,0,114000.00 samples/s,0.01 ms,2.03 mW,17809.00 pJ/it -pool/avg_include_pad,arch-a,PASS,PASS,0.064 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.02 mW,663612.00 pJ,0.059 s,0.00 MiB,0.00 MiB,1,0,118000.00 samples/s,0.01 ms,2.02 mW,17081.00 pJ/it -pool/avg_large_channels,arch-a,PASS,PASS,0.069 s,0.04 MiB,0.02 MiB,1,0,0.24 ms,78.00 mW,18399156.00 pJ,0.067 s,0.04 MiB,0.02 MiB,1,0,4250.00 samples/s,0.24 ms,2.00 mW,471428.00 pJ/it -pool/avg_non_uniform_stride,arch-a,PASS,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.02 mW,1132254.00 pJ,0.060 s,0.00 MiB,0.00 MiB,1,0,69100.00 samples/s,0.01 ms,2.02 mW,29191.00 pJ/it -pool/avg_real_asymmetric_padding,arch-a,PASS,PASS,0.070 s,0.00 MiB,0.00 MiB,1,0,0.03 ms,78.02 mW,1966692.00 pJ,0.073 s,0.00 MiB,0.00 MiB,1,0,39700.00 samples/s,0.03 ms,2.02 mW,50961.00 pJ/it -pool/max_after_conv,arch-a,PASS,PASS,0.069 s,0.00 MiB,0.00 MiB,5,4,0.01 ms,99.12 mW,1210689.96 pJ,0.074 s,0.00 MiB,0.00 MiB,5,4,81600.00 samples/s,0.01 ms,28.10 mW,344619.71 pJ/it -pool/max_basic,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.06 mW,324744.00 pJ,0.055 s,0.00 MiB,0.00 MiB,1,0,241000.00 samples/s,0.00 ms,2.06 mW,8532.67 pJ/it -pool/max_ceil_mode,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.07 mW,151464.00 pJ,0.059 s,0.00 MiB,0.00 MiB,1,0,516000.00 samples/s,0.00 ms,2.07 mW,3972.67 pJ/it -pool/max_global_style_kernel_equals_input,arch-a,PASS,PASS,0.066 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.01 mW,658626.00 pJ,0.063 s,0.00 MiB,0.00 MiB,1,0,119000.00 samples/s,0.01 ms,2.01 mW,16871.00 pJ/it -pool/max_non_square_kernel,arch-a,PASS,PASS,0.070 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.02 mW,1063068.00 pJ,0.063 s,0.00 MiB,0.00 MiB,1,0,73600.00 samples/s,0.01 ms,2.02 mW,27417.00 pJ/it -pool/max_real_asymmetric_padding,arch-a,PASS,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.03 mW,814992.00 pJ,0.060 s,0.00 MiB,0.00 MiB,1,0,96100.00 samples/s,0.01 ms,2.03 mW,21173.00 pJ/it -pool/max_same_upper,arch-a,PASS,PASS,0.066 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.04 mW,625068.00 pJ,0.067 s,0.00 MiB,0.00 MiB,1,0,125000.00 samples/s,0.01 ms,2.04 mW,16233.00 pJ/it -pool/max_stride2_multichannel,arch-a,PASS,PASS,0.067 s,0.00 MiB,0.00 MiB,1,0,0.02 ms,78.02 mW,1247274.00 pJ,0.074 s,0.00 MiB,0.00 MiB,1,0,62700.00 samples/s,0.02 ms,2.02 mW,32153.00 pJ/it -reduce_mean/4d_spatial,arch-a,PASS,PASS,0.068 s,0.00 MiB,0.00 MiB,3,0,0.00 ms,92.45 mW,29676.00 pJ,0.068 s,0.00 MiB,0.00 MiB,3,0,2310000.00 samples/s,0.00 ms,4.54 mW,1959.17 pJ/it -reduce_mean/4d_spatial_keepdims_0,arch-a,PASS,PASS,0.072 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,94.35 mW,61801.00 pJ,0.070 s,0.00 MiB,0.00 MiB,4,0,1210000.00 samples/s,0.00 ms,19.43 mW,16020.25 pJ/it -reduce_mean/after_conv,arch-a,PASS,PASS,0.071 s,0.00 MiB,0.00 MiB,5,3,0.01 ms,106.95 mW,571332.72 pJ,0.075 s,0.00 MiB,0.00 MiB,5,3,183000.00 samples/s,0.01 ms,19.71 mW,107526.72 pJ/it -reduce_mean/all_axes_keepdims_0,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.00 MiB,2,0,0.00 ms,79.24 mW,30982.00 pJ,0.063 s,0.00 MiB,0.00 MiB,2,0,2530000.00 samples/s,0.00 ms,3.31 mW,1260.00 pJ/it -reduce_mean/all_axes_keepdims_1,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.067 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it -reduce_mean/basic,arch-a,PASS,PASS,0.068 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,93.51 mW,34881.00 pJ,0.061 s,0.00 MiB,0.00 MiB,4,0,2600000.00 samples/s,0.00 ms,5.85 mW,2235.67 pJ/it -reduce_mean/channel_axis_nchw,arch-a,PASS,PASS,0.061 s,0.03 MiB,0.02 MiB,4,0,0.16 ms,93.60 mW,15436518.00 pJ,0.062 s,0.03 MiB,0.08 MiB,4,0,12900.00 samples/s,0.08 ms,5.00 mW,388853.50 pJ/it -reduce_mean/keepdims_0,arch-a,PASS,PASS,0.067 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.40 mW,68368.00 pJ,0.056 s,0.00 MiB,0.00 MiB,5,0,1300000.00 samples/s,0.00 ms,20.71 mW,16115.50 pJ/it -reduce_mean/large_dimension_1024,arch-a,PASS,PASS,0.057 s,0.01 MiB,0.00 MiB,1,0,0.00 ms,78.02 mW,217278.00 pJ,0.056 s,0.01 MiB,0.00 MiB,1,0,359000.00 samples/s,0.00 ms,2.02 mW,5274.00 pJ/it -reduce_mean/legacy_axes_1_2_keepdims_1,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,2,0,0.00 ms,79.35 mW,21505.00 pJ,0.058 s,0.00 MiB,0.00 MiB,2,0,3620000.00 samples/s,0.00 ms,3.45 mW,898.00 pJ/it -reduce_mean/legacy_axis1_keepdims_0,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,9,0,0.00 ms,92.50 mW,183708.00 pJ,0.065 s,0.00 MiB,0.00 MiB,9,0,679000.00 samples/s,0.00 ms,38.84 mW,57998.17 pJ/it -reduce_mean/legacy_axis1_keepdims_1,arch-a,PASS,PASS,0.060 s,0.00 MiB,0.00 MiB,8,0,0.00 ms,94.56 mW,129830.00 pJ,0.066 s,0.00 MiB,0.00 MiB,8,0,1340000.00 samples/s,0.00 ms,10.15 mW,7594.50 pJ/it -reduce_mean/legacy_empty_axes_noop,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.055 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it -reduce_mean/legacy_nchw_spatial,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.00 MiB,3,0,0.00 ms,92.45 mW,29676.00 pJ,0.058 s,0.00 MiB,0.00 MiB,3,0,1720000.00 samples/s,0.00 ms,4.40 mW,2552.75 pJ/it -reduce_mean/legacy_negative_axis,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,6,0,0.00 ms,93.52 mW,51717.00 pJ,0.060 s,0.00 MiB,0.00 MiB,6,0,1760000.00 samples/s,0.00 ms,8.07 mW,4588.50 pJ/it -reduce_mean/legacy_reduce_all_keepdims_1,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.054 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it -reduce_mean/negative_axis,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.00 MiB,6,0,0.00 ms,93.52 mW,51717.00 pJ,0.058 s,0.00 MiB,0.00 MiB,6,0,1760000.00 samples/s,0.00 ms,8.07 mW,4588.50 pJ/it -relu/4d,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.18 mW,40734.00 pJ,0.053 s,0.00 MiB,0.00 MiB,1,0,1930000.00 samples/s,0.00 ms,2.18 mW,1014.00 pJ/it -relu/after_conv,arch-a,PASS,PASS,0.063 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,107.89 mW,577437.72 pJ,0.067 s,0.00 MiB,0.00 MiB,4,3,187000.00 samples/s,0.01 ms,32.91 mW,176189.97 pJ/it -relu/after_gemm,arch-a,PASS,PASS,0.069 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,105.16 mW,790056.96 pJ,0.074 s,0.01 MiB,0.01 MiB,6,4,151000.00 samples/s,0.01 ms,32.04 mW,211536.21 pJ/it -relu/basic,arch-a,PASS,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.057 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it -reshape/4d_to_2d_flatten,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.28 mW,20196.00 pJ,0.061 s,0.00 MiB,0.00 MiB,1,0,3910000.00 samples/s,0.00 ms,2.28 mW,488.00 pJ/it -reshape/infer_dim_minus_one,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,12684.00 pJ,0.058 s,0.00 MiB,0.00 MiB,1,0,6250000.00 samples/s,0.00 ms,2.30 mW,308.00 pJ/it -reshape/same_rank,arch-a,PASS,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,12684.00 pJ,0.058 s,0.00 MiB,0.00 MiB,1,0,6250000.00 samples/s,0.00 ms,2.30 mW,308.00 pJ/it -reshape/zero_copies_input_dim,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,12684.00 pJ,0.056 s,0.00 MiB,0.00 MiB,1,0,6250000.00 samples/s,0.00 ms,2.30 mW,308.00 pJ/it -resize/height_only,arch-a,PASS,PASS,0.060 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,93.55 mW,64833.00 pJ,0.063 s,0.00 MiB,0.00 MiB,4,0,1880000.00 samples/s,0.00 ms,5.60 mW,2986.00 pJ/it -resize/nearest_2x,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,93.57 mW,109761.00 pJ,0.059 s,0.00 MiB,0.00 MiB,4,0,1450000.00 samples/s,0.00 ms,5.46 mW,3776.00 pJ/it -resize/nearest_downsample,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.00 MiB,2,0,0.00 ms,79.45 mW,33925.00 pJ,0.059 s,0.00 MiB,0.00 MiB,2,0,2330000.00 samples/s,0.00 ms,3.28 mW,1360.50 pJ/it -resize/non_uniform_scales,arch-a,PASS,PASS,0.063 s,0.00 MiB,0.00 MiB,6,0,0.00 ms,93.58 mW,164037.00 pJ,0.069 s,0.00 MiB,0.00 MiB,6,0,1250000.00 samples/s,0.00 ms,7.76 mW,6207.25 pJ/it -resize/width_only,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,2,0,0.00 ms,79.50 mW,53029.00 pJ,0.059 s,0.00 MiB,0.00 MiB,2,0,1700000.00 samples/s,0.00 ms,3.20 mW,1833.50 pJ/it -resize/with_sizes,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,3,0,0.00 ms,92.54 mW,73756.00 pJ,0.068 s,0.00 MiB,0.00 MiB,3,0,1700000.00 samples/s,0.00 ms,4.39 mW,2586.75 pJ/it -sigmoid/4d,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.18 mW,40734.00 pJ,0.060 s,0.00 MiB,0.00 MiB,1,0,1930000.00 samples/s,0.00 ms,2.18 mW,1014.00 pJ/it -sigmoid/after_gemm,arch-a,PASS,PASS,0.063 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,105.16 mW,790056.96 pJ,0.062 s,0.01 MiB,0.01 MiB,6,4,151000.00 samples/s,0.01 ms,32.04 mW,211536.21 pJ/it -sigmoid/basic,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.060 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it -slice/2d_basic,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,18948.00 pJ,0.055 s,0.00 MiB,0.00 MiB,1,0,4170000.00 samples/s,0.00 ms,2.30 mW,491.67 pJ/it -slice/after_conv,arch-a,PASS,PASS,0.067 s,0.00 MiB,0.01 MiB,7,6,0.01 ms,118.19 mW,1335082.88 pJ,0.074 s,0.00 MiB,0.01 MiB,7,6,87400.00 samples/s,0.01 ms,47.90 mW,547806.13 pJ/it -slice/default_axes,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,18948.00 pJ,0.054 s,0.00 MiB,0.00 MiB,1,0,4170000.00 samples/s,0.00 ms,2.30 mW,491.67 pJ/it -slice/large_channel_1024,arch-a,PASS,PASS,0.059 s,0.01 MiB,0.00 MiB,1,0,0.00 ms,78.14 mW,221304.00 pJ,0.052 s,0.01 MiB,0.00 MiB,1,0,353000.00 samples/s,0.00 ms,2.14 mW,5058.00 pJ/it -slice/nchw_spatial_crop,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.24 mW,101868.00 pJ,0.060 s,0.00 MiB,0.00 MiB,1,0,769000.00 samples/s,0.00 ms,2.24 mW,2851.67 pJ/it -slice/negative_axis,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,44004.00 pJ,0.055 s,0.00 MiB,0.00 MiB,1,0,1790000.00 samples/s,0.00 ms,2.30 mW,1227.67 pJ/it -slice/negative_indices,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,25212.00 pJ,0.054 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.30 mW,675.67 pJ/it -slice/step2,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.29 mW,159876.00 pJ,0.053 s,0.00 MiB,0.00 MiB,1,0,490000.00 samples/s,0.00 ms,2.29 mW,4619.67 pJ/it -softmax/3d_last_axis,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.056 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED -softmax/basic,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.058 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED -softmax/channel_axis,arch-a,PASS,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.067 s,0.00 MiB,0.00 MiB,3,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED -softmax/large_dimension_1024,arch-a,PASS,PASS,0.059 s,0.01 MiB,0.01 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.054 s,0.01 MiB,0.01 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED -softmax/negative_axis,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.060 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED -split/basic,arch-a,PASS,PASS,0.114 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,31554.00 pJ,0.067 s,0.00 MiB,0.00 MiB,1,0,2490000.00 samples/s,0.00 ms,2.30 mW,861.67 pJ/it -split/equal_three_way,arch-a,PASS,PASS,0.060 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,44160.00 pJ,0.073 s,0.00 MiB,0.00 MiB,1,0,1780000.00 samples/s,0.00 ms,2.30 mW,1231.67 pJ/it -split/negative_axis,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.29 mW,84786.00 pJ,0.059 s,0.00 MiB,0.00 MiB,1,0,925000.00 samples/s,0.00 ms,2.29 mW,2413.67 pJ/it -split/uneven_channel_axis_4d,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,18948.00 pJ,0.060 s,0.00 MiB,0.00 MiB,1,0,4170000.00 samples/s,0.00 ms,2.30 mW,491.67 pJ/it -sub/after_gemm,arch-a,PASS,PASS,0.065 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,104.70 mW,815012.96 pJ,0.065 s,0.01 MiB,0.01 MiB,6,4,145000.00 samples/s,0.01 ms,31.45 mW,216167.21 pJ/it -sub/basic,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.055 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -sub/broadcast_row,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.077 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it -sub/channel_broadcast_1024,arch-a,PASS,PASS,0.064 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.058 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it -sub/constant_lhs_broadcast,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25188.00 pJ,0.061 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,656.67 pJ/it -sub/leading_dimension_broadcast,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.057 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +add/after_gemm,arch-a,PASS,PASS,0.056 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,104.70 mW,815012.96 pJ,0.043 s,0.01 MiB,0.01 MiB,6,4,218000.00 samples/s,0.00 ms,107.94 mW,570766.12 pJ/it +add/basic,arch-a,PASS,PASS,0.053 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.041 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +add/broadcast_row,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.037 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +add/channel_broadcast_1024,arch-a,PASS,PASS,0.052 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.036 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it +add/leading_dimension_broadcast,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.038 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +concat/channel_axis,arch-a,PASS,PASS,0.047 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.16 mW,35718.00 pJ,0.034 s,0.00 MiB,0.00 MiB,1,0,2200000.00 samples/s,0.00 ms,2.16 mW,934.67 pJ/it +concat/negative_axis,arch-a,PASS,PASS,0.046 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.09 mW,81450.00 pJ,0.038 s,0.00 MiB,0.00 MiB,1,0,961000.00 samples/s,0.00 ms,2.09 mW,2108.00 pJ/it +concat/three_inputs_channel_axis,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.15 mW,50328.00 pJ,0.035 s,0.00 MiB,0.00 MiB,1,0,1560000.00 samples/s,0.00 ms,2.15 mW,1332.67 pJ/it +conv/batch_2,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,2,2,0.01 ms,82.62 mW,1131451.48 pJ,0.044 s,0.00 MiB,0.01 MiB,4,2,147000.00 samples/s,0.01 ms,92.90 mW,669920.48 pJ/it +conv/batch_4_pointwise,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.01 MiB,5,4,0.00 ms,116.08 mW,456420.96 pJ,0.043 s,0.01 MiB,0.01 MiB,5,4,242000.00 samples/s,0.00 ms,69.62 mW,291187.04 pJ/it +conv/depthwise_1024_channels,arch-a,PASS,PASS,0.082 s,0.19 MiB,0.38 MiB,129,128,0.22 ms,178.45 mW,39393966.72 pJ,0.117 s,0.38 MiB,0.46 MiB,45,118,4930.00 samples/s,0.20 ms,144.34 mW,33005602.67 pJ/it +conv/depthwise_grouped,arch-a,PASS,PASS,0.055 s,0.01 MiB,0.00 MiB,5,4,0.01 ms,107.78 mW,671878.96 pJ,0.042 s,0.01 MiB,0.00 MiB,7,4,418000.00 samples/s,0.00 ms,168.64 mW,479471.12 pJ/it +conv/dilated_3x3,arch-a,PASS,PASS,0.057 s,0.01 MiB,0.01 MiB,10,9,0.01 ms,118.77 mW,1034819.16 pJ,0.057 s,0.01 MiB,0.01 MiB,12,9,104000.00 samples/s,0.01 ms,155.40 mW,1574973.57 pJ/it +conv/dynamic,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,92.28 mW,169336.00 pJ,0.044 s,0.00 MiB,0.00 MiB,6,0,778000.00 samples/s,0.00 ms,86.62 mW,124092.33 pJ/it +conv/explicit_padding,arch-a,PASS,PASS,0.053 s,0.01 MiB,0.02 MiB,17,16,0.01 ms,145.34 mW,1454397.84 pJ,0.048 s,0.01 MiB,0.02 MiB,19,16,179000.00 samples/s,0.01 ms,201.80 mW,1234440.20 pJ/it +conv/grouped_many_groups,arch-a,PASS,PASS,0.474 s,0.05 MiB,0.09 MiB,65,64,0.18 ms,142.21 mW,25867112.36 pJ,0.476 s,0.08 MiB,0.73 MiB,87,64,3660.00 samples/s,0.27 ms,97.46 mW,30277556.57 pJ/it +conv/grouped_two_groups,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,3,2,0.01 ms,101.46 mW,543914.48 pJ,0.047 s,0.00 MiB,0.01 MiB,9,2,378000.00 samples/s,0.00 ms,105.40 mW,353700.73 pJ/it +conv/huge_pointwise_1024,arch-a,PASS,PASS,0.151 s,0.01 MiB,0.11 MiB,73,64,0.02 ms,249.58 mW,3895759.36 pJ,0.163 s,0.08 MiB,0.10 MiB,52,64,19200.00 samples/s,0.05 ms,163.09 mW,8722111.37 pJ/it +conv/huge_pointwise_1024_dynamic,arch-a,PASS,PASS,0.080 s,8.04 MiB,12.61 MiB,168,0,2.63 ms,169.52 mW,445489032.00 pJ,0.224 s,12.75 MiB,6.82 MiB,45,0,188.00 samples/s,5.31 ms,134.20 mW,746263826.70 pJ/it +conv/input_224_7x7_stride2,arch-a,PASS,PASS,0.759 s,24.14 MiB,61.87 MiB,168,169,38.41 ms,185.26 mW,7116544212.12 pJ,1.060 s,51.25 MiB,67.85 MiB,45,84,24.70 samples/s,40.56 ms,148.32 mW,6561548886.00 pJ/it +conv/kernel_2x2,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.00 MiB,1,1,0.00 ms,83.83 mW,360568.24 pJ,0.046 s,0.00 MiB,0.00 MiB,3,1,356000.00 samples/s,0.00 ms,93.82 mW,298919.07 pJ/it +conv/kernel_3x3,arch-a,PASS,PASS,0.061 s,0.01 MiB,0.01 MiB,10,9,0.01 ms,123.80 mW,889640.16 pJ,0.046 s,0.01 MiB,0.01 MiB,12,9,271000.00 samples/s,0.00 ms,195.49 mW,787478.85 pJ/it +conv/kernel_equals_input_spatial,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,2,2,0.00 ms,89.61 mW,415689.48 pJ,0.041 s,0.00 MiB,0.00 MiB,4,2,376000.00 samples/s,0.00 ms,104.42 mW,305239.85 pJ/it +conv/large_input_channels_1x1,arch-a,PASS,PASS,0.085 s,0.01 MiB,0.02 MiB,9,8,0.01 ms,117.84 mW,900569.92 pJ,0.081 s,0.02 MiB,0.02 MiB,10,8,135000.00 samples/s,0.01 ms,113.25 mW,910683.04 pJ/it +conv/large_output_channels_1x1,arch-a,PASS,PASS,0.095 s,0.01 MiB,0.02 MiB,17,8,0.01 ms,128.44 mW,1139415.92 pJ,0.078 s,0.02 MiB,0.02 MiB,18,8,93600.00 samples/s,0.01 ms,151.83 mW,1755770.60 pJ/it +conv/large_spatial,arch-a,PASS,PASS,0.061 s,0.01 MiB,0.04 MiB,37,36,0.02 ms,172.07 mW,2928344.64 pJ,0.061 s,0.01 MiB,0.04 MiB,39,36,84200.00 samples/s,0.01 ms,208.30 mW,2603711.62 pJ/it +conv/multi_channel,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,105.68 mW,685040.72 pJ,0.050 s,0.00 MiB,0.00 MiB,4,3,140000.00 samples/s,0.01 ms,54.54 mW,393755.39 pJ/it +conv/non_square_kernel_1x3,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,3,2,0.01 ms,99.35 mW,679752.48 pJ,0.044 s,0.00 MiB,0.00 MiB,3,2,140000.00 samples/s,0.01 ms,51.01 mW,367557.81 pJ/it +conv/non_square_kernel_3x1,arch-a,PASS,PASS,0.053 s,0.00 MiB,0.00 MiB,3,2,0.01 ms,95.89 mW,1292976.48 pJ,0.045 s,0.00 MiB,0.00 MiB,3,2,72200.00 samples/s,0.01 ms,47.79 mW,664683.81 pJ/it +conv/non_uniform_stride,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,104.05 mW,790874.72 pJ,0.044 s,0.00 MiB,0.00 MiB,4,3,126000.00 samples/s,0.01 ms,53.56 mW,429978.05 pJ/it +conv/output_channel_grouping_minimal,arch-a,PASS,PASS,0.080 s,0.10 MiB,0.34 MiB,131,128,0.26 ms,170.73 mW,44125916.72 pJ,0.148 s,0.28 MiB,0.96 MiB,87,84,2630.00 samples/s,0.38 ms,136.74 mW,58542917.01 pJ/it +conv/pointwise_1x1,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,1,0.01 ms,80.24 mW,987244.24 pJ,0.041 s,0.00 MiB,0.00 MiB,3,1,131000.00 samples/s,0.01 ms,89.08 mW,719413.57 pJ/it +conv/pointwise_tiled_chain,arch-a,PASS,PASS,0.642 s,0.01 MiB,0.04 MiB,20,80,0.04 ms,153.90 mW,6443957.20 pJ,0.620 s,0.06 MiB,0.08 MiB,22,80,16400.00 samples/s,0.06 ms,186.69 mW,12410041.37 pJ/it +conv/real_asymmetric_padding,arch-a,PASS,PASS,0.057 s,0.01 MiB,0.03 MiB,29,28,0.01 ms,153.67 mW,2221606.72 pJ,0.055 s,0.01 MiB,0.03 MiB,31,28,105000.00 samples/s,0.01 ms,204.35 mW,2058223.49 pJ/it +conv/relu_conv_store,arch-a,PASS,PASS,0.085 s,0.16 MiB,0.67 MiB,168,184,0.56 ms,183.08 mW,103057723.80 pJ,0.209 s,0.37 MiB,0.58 MiB,60,58,1500.00 samples/s,0.67 ms,146.73 mW,101291048.70 pJ/it +conv/same_lower_3x3,arch-a,PASS,PASS,0.060 s,0.01 MiB,0.02 MiB,26,25,0.01 ms,166.15 mW,2215009.00 pJ,0.054 s,0.01 MiB,0.03 MiB,28,25,119000.00 samples/s,0.01 ms,204.48 mW,1837219.40 pJ/it +conv/same_padding_3x3,arch-a,PASS,PASS,0.058 s,0.01 MiB,0.02 MiB,26,25,0.01 ms,166.15 mW,2215009.00 pJ,0.056 s,0.01 MiB,0.03 MiB,28,25,119000.00 samples/s,0.01 ms,204.48 mW,1837219.40 pJ/it +conv/strategy_depthwise_16,arch-a,PASS,PASS,0.093 s,0.06 MiB,0.35 MiB,168,168,0.34 ms,197.94 mW,66331479.08 pJ,0.257 s,0.20 MiB,0.17 MiB,45,84,2650.00 samples/s,0.38 ms,153.71 mW,60322816.49 pJ/it +conv/strategy_input_k_tiled,arch-a,PASS,PASS,0.082 s,0.08 MiB,0.27 MiB,109,108,0.35 ms,170.81 mW,60422605.92 pJ,0.100 s,0.22 MiB,0.28 MiB,45,90,4250.00 samples/s,0.24 ms,143.52 mW,36750587.75 pJ/it +conv/strategy_output_channel_tiled,arch-a,PASS,PASS,0.073 s,0.03 MiB,0.16 MiB,74,72,0.09 ms,155.74 mW,14244739.28 pJ,0.110 s,0.13 MiB,0.22 MiB,81,72,9220.00 samples/s,0.11 ms,145.73 mW,18577796.14 pJ/it +conv/strategy_streamed_packed,arch-a,PASS,PASS,0.155 s,3.34 MiB,7.89 MiB,168,168,9.35 ms,179.86 mW,1682364509.56 pJ,0.357 s,5.32 MiB,7.79 MiB,43,42,113.00 samples/s,8.87 ms,61.68 mW,558465684.90 pJ/it +conv/strategy_streamed_patch,arch-a,PASS,PASS,0.115 s,0.34 MiB,1.32 MiB,168,168,1.90 ms,181.91 mW,346476645.64 pJ,0.299 s,0.82 MiB,1.21 MiB,43,42,501.00 samples/s,1.99 ms,62.44 mW,125148059.00 pJ/it +conv/strategy_tiled_2d,arch-a,PASS,PASS,0.111 s,0.11 MiB,0.44 MiB,168,168,0.42 ms,182.13 mW,75690907.84 pJ,0.219 s,0.36 MiB,0.46 MiB,47,144,4070.00 samples/s,0.25 ms,155.26 mW,43400768.51 pJ/it +conv/stride_2,arch-a,PASS,PASS,0.056 s,0.01 MiB,0.00 MiB,5,4,0.01 ms,110.78 mW,580154.96 pJ,0.043 s,0.01 MiB,0.00 MiB,7,4,476000.00 samples/s,0.00 ms,175.93 mW,424103.12 pJ/it +conv/with_bias_3x3,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.01 MiB,4,3,0.01 ms,104.16 mW,776220.72 pJ,0.046 s,0.00 MiB,0.01 MiB,4,3,133000.00 samples/s,0.01 ms,53.85 mW,416288.72 pJ/it +conv/with_constant,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,1,0.01 ms,81.74 mW,541270.24 pJ,0.043 s,0.00 MiB,0.00 MiB,4,1,231000.00 samples/s,0.00 ms,133.09 mW,655848.91 pJ/it +conv/without_kernel_shape_attr,arch-a,PASS,PASS,0.053 s,0.01 MiB,0.01 MiB,10,9,0.01 ms,123.80 mW,889640.16 pJ,0.047 s,0.01 MiB,0.01 MiB,12,9,271000.00 samples/s,0.00 ms,195.49 mW,787478.85 pJ/it +conv/yolo11n_depthwise_head,arch-a,PASS,PASS,1.709 s,8.66 MiB,34.24 MiB,168,255,42.70 ms,200.52 mW,8562452412.00 pJ,2.373 s,27.15 MiB,20.31 MiB,87,214,20.60 samples/s,48.55 ms,157.12 mW,8007922821.00 pJ/it +conv/yolo11n_heavy,arch-a,PASS,PASS,0.519 s,4.82 MiB,19.10 MiB,161,800,8.53 ms,350.87 mW,2994683017.00 pJ,1.007 s,11.06 MiB,13.87 MiB,85,420,79.10 samples/s,12.64 ms,218.17 mW,2857451109.00 pJ/it +conv/yolo11n_stem,arch-a,PASS,PASS,0.893 s,12.86 MiB,37.59 MiB,168,488,14.24 ms,301.23 mW,4289558246.00 pJ,1.374 s,25.19 MiB,21.24 MiB,85,126,44.60 samples/s,22.42 ms,176.88 mW,4028789243.00 pJ/it +div/after_gemm,arch-a,PASS,PASS,0.053 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,104.70 mW,815012.96 pJ,0.045 s,0.01 MiB,0.01 MiB,6,4,218000.00 samples/s,0.00 ms,107.94 mW,570766.12 pJ/it +div/basic,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.036 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +div/channel_broadcast_1024,arch-a,PASS,PASS,0.049 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.039 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it +div/leading_dimension_broadcast,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.040 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +div/runtime_scalar_rhs,arch-a,PASS,PASS,0.053 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.040 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it +div/scalar_constant,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.036 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +gather/3d_input_axis1,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.08 mW,45990.00 pJ,0.038 s,0.00 MiB,0.00 MiB,1,0,1700000.00 samples/s,0.00 ms,2.08 mW,1174.67 pJ/it +gather/axis0_matrix_indices,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.07 mW,54414.00 pJ,0.039 s,0.00 MiB,0.00 MiB,1,0,1440000.00 samples/s,0.00 ms,2.07 mW,1390.67 pJ/it +gather/axis1,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.06 mW,62526.00 pJ,0.036 s,0.00 MiB,0.00 MiB,1,0,1250000.00 samples/s,0.00 ms,2.06 mW,1598.67 pJ/it +gather/negative_axis,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.03 mW,112134.00 pJ,0.039 s,0.00 MiB,0.00 MiB,1,0,697000.00 samples/s,0.00 ms,2.03 mW,2870.67 pJ/it +gather/negative_indices,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.13 mW,29376.00 pJ,0.041 s,0.00 MiB,0.00 MiB,1,0,2670000.00 samples/s,0.00 ms,2.12 mW,748.67 pJ/it +gemm/alpha_beta,arch-a,PASS,PASS,0.056 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,105.27 mW,784908.96 pJ,0.050 s,0.01 MiB,0.01 MiB,6,4,212000.00 samples/s,0.00 ms,107.78 mW,574589.95 pJ/it +gemm/bias_rank2_broadcast,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,105.98 mW,749484.96 pJ,0.043 s,0.01 MiB,0.01 MiB,6,4,229000.00 samples/s,0.00 ms,109.50 mW,540708.12 pJ/it +gemm/dynamic,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.48 mW,221475.00 pJ,0.044 s,0.00 MiB,0.00 MiB,5,0,489000.00 samples/s,0.00 ms,44.34 mW,93754.67 pJ/it +gemm/dynamic_alpha,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.42 mW,298198.00 pJ,0.041 s,0.00 MiB,0.00 MiB,5,0,464000.00 samples/s,0.00 ms,44.39 mW,105291.67 pJ/it +gemm/dynamic_beta,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.32 mW,397230.00 pJ,0.042 s,0.00 MiB,0.00 MiB,5,0,247000.00 samples/s,0.00 ms,20.21 mW,81901.75 pJ/it +gemm/dynamic_bias,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.45 mW,243703.00 pJ,0.046 s,0.00 MiB,0.00 MiB,5,0,422000.00 samples/s,0.00 ms,20.28 mW,48009.75 pJ/it +gemm/dynamic_bias_alpha_beta,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,5,0,0.01 ms,91.28 mW,513811.00 pJ,0.043 s,0.00 MiB,0.00 MiB,5,0,188000.00 samples/s,0.01 ms,20.20 mW,107673.75 pJ/it +gemm/dynamic_transpose_b,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.38 mW,118883.00 pJ,0.040 s,0.00 MiB,0.00 MiB,5,0,803000.00 samples/s,0.00 ms,44.55 mW,58232.00 pJ/it +gemm/huge_1024,arch-a,PASS,PASS,0.149 s,0.01 MiB,0.10 MiB,73,64,0.02 ms,215.07 mW,3767010.36 pJ,0.160 s,0.05 MiB,0.09 MiB,51,64,26400.00 samples/s,0.04 ms,135.13 mW,5670462.59 pJ/it +gemm/large,arch-a,PASS,PASS,0.058 s,0.02 MiB,0.03 MiB,17,16,0.01 ms,140.15 mW,1573768.84 pJ,0.050 s,0.03 MiB,0.03 MiB,17,16,78500.00 samples/s,0.01 ms,79.60 mW,1008067.12 pJ/it +gemm/large_k_small_n,arch-a,PASS,PASS,0.088 s,0.01 MiB,0.01 MiB,9,8,0.00 ms,133.53 mW,633217.92 pJ,0.082 s,0.01 MiB,0.01 MiB,9,8,182000.00 samples/s,0.01 ms,84.31 mW,476982.66 pJ/it +gemm/non_square,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.01 MiB,5,4,0.00 ms,118.96 mW,419565.96 pJ,0.043 s,0.01 MiB,0.01 MiB,5,4,242000.00 samples/s,0.00 ms,71.16 mW,302182.45 pJ/it +gemm/scalar_bias,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,105.98 mW,749484.96 pJ,0.045 s,0.01 MiB,0.01 MiB,6,4,229000.00 samples/s,0.00 ms,109.50 mW,540708.12 pJ/it +gemm/small,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,2,2,0.00 ms,90.14 mW,398436.48 pJ,0.043 s,0.00 MiB,0.00 MiB,4,2,376000.00 samples/s,0.00 ms,105.00 mW,297577.19 pJ/it +gemm/small_k_large_n,arch-a,PASS,PASS,0.090 s,0.01 MiB,0.02 MiB,17,8,0.01 ms,131.01 mW,1043061.92 pJ,0.082 s,0.02 MiB,0.02 MiB,18,8,92700.00 samples/s,0.01 ms,152.38 mW,1742739.72 pJ/it +gemm/square_weights,arch-a,PASS,PASS,0.073 s,0.03 MiB,0.08 MiB,42,40,0.02 ms,151.77 mW,3284393.60 pJ,0.075 s,0.07 MiB,0.09 MiB,44,40,25700.00 samples/s,0.04 ms,155.80 mW,6344327.95 pJ/it +gemm/transpose_a,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,109.14 mW,628868.96 pJ,0.047 s,0.01 MiB,0.01 MiB,6,4,290000.00 samples/s,0.00 ms,115.23 mW,456854.62 pJ/it +gemm/transpose_a_and_b,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,109.14 mW,628868.96 pJ,0.044 s,0.01 MiB,0.01 MiB,6,4,290000.00 samples/s,0.00 ms,115.23 mW,456854.62 pJ/it +gemm/transpose_b,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.01 MiB,5,4,0.00 ms,118.96 mW,419565.96 pJ,0.045 s,0.01 MiB,0.01 MiB,5,4,242000.00 samples/s,0.00 ms,71.16 mW,302182.45 pJ/it +gemm/transpose_b_with_bias,arch-a,PASS,PASS,0.057 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,110.55 mW,557818.96 pJ,0.046 s,0.01 MiB,0.01 MiB,5,4,218000.00 samples/s,0.00 ms,67.31 mW,333372.79 pJ/it +gemm/with_bias,arch-a,PASS,PASS,0.057 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,108.77 mW,604966.96 pJ,0.043 s,0.01 MiB,0.01 MiB,5,4,203000.00 samples/s,0.00 ms,66.54 mW,341027.79 pJ/it +gemv/all_constant,arch-a,PASS,PASS,0.053 s,0.00 MiB,0.00 MiB,0,0,0.00 ms,2.00 mW,0.00 pJ,0.039 s,0.00 MiB,0.00 MiB,0,0,0.00 samples/s,0.00 ms,2.00 mW,0.00 pJ/it +gemv/constant_weight,arch-a,PASS,PASS,0.065 s,0.00 MiB,0.01 MiB,6,4,0.01 ms,111.15 mW,573535.96 pJ,0.051 s,0.01 MiB,0.01 MiB,8,4,263000.00 samples/s,0.00 ms,154.40 mW,641346.96 pJ/it +gemv/non_uniform_bias,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.01 MiB,6,4,0.01 ms,109.81 mW,609463.96 pJ,0.051 s,0.01 MiB,0.01 MiB,8,4,243000.00 samples/s,0.00 ms,152.55 mW,697203.20 pJ/it +gemv/scalar_bias,arch-a,PASS,PASS,0.061 s,0.00 MiB,0.01 MiB,6,4,0.01 ms,109.81 mW,609463.96 pJ,0.052 s,0.01 MiB,0.01 MiB,8,4,243000.00 samples/s,0.00 ms,152.55 mW,697203.20 pJ/it +gemv/uniform_bias,arch-a,PASS,PASS,0.066 s,0.00 MiB,0.01 MiB,6,4,0.01 ms,109.81 mW,609463.96 pJ,0.049 s,0.01 MiB,0.01 MiB,8,4,243000.00 samples/s,0.00 ms,152.55 mW,697203.20 pJ/it +matmul/basic,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,2,2,0.00 ms,90.14 mW,398436.48 pJ,0.040 s,0.00 MiB,0.00 MiB,4,2,376000.00 samples/s,0.00 ms,105.00 mW,297577.19 pJ/it +matmul/batched_3d,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,108.59 mW,646972.96 pJ,0.048 s,0.01 MiB,0.01 MiB,6,4,275000.00 samples/s,0.00 ms,114.15 mW,469999.95 pJ/it +matmul/batched_3d_dynamic,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,92.19 mW,167975.00 pJ,0.041 s,0.00 MiB,0.00 MiB,5,0,758000.00 samples/s,0.00 ms,18.49 mW,24624.50 pJ/it +matmul/batched_left_constant,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.02 MiB,9,8,0.01 ms,114.39 mW,1009105.92 pJ,0.059 s,0.01 MiB,0.02 MiB,11,8,149000.00 samples/s,0.01 ms,159.00 mW,1186296.28 pJ/it +matmul/batched_lhs_broadcast,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,109.39 mW,621440.96 pJ,0.042 s,0.01 MiB,0.01 MiB,6,4,276000.00 samples/s,0.00 ms,114.66 mW,463736.29 pJ/it +matmul/batched_rhs_broadcast,arch-a,PASS,PASS,0.058 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,108.59 mW,646972.96 pJ,0.043 s,0.01 MiB,0.01 MiB,6,4,275000.00 samples/s,0.00 ms,114.15 mW,469999.95 pJ/it +matmul/dynamic,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.42 mW,148195.00 pJ,0.041 s,0.00 MiB,0.00 MiB,5,0,660000.00 samples/s,0.00 ms,44.46 mW,70471.33 pJ/it +matmul/huge_1024,arch-a,PASS,PASS,0.146 s,0.01 MiB,0.10 MiB,73,64,0.02 ms,215.07 mW,3767010.36 pJ,0.162 s,0.05 MiB,0.09 MiB,51,64,26400.00 samples/s,0.04 ms,135.13 mW,5670462.59 pJ/it +matmul/left_constant,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.01 MiB,5,4,0.01 ms,108.86 mW,637168.96 pJ,0.045 s,0.01 MiB,0.01 MiB,6,4,297000.00 samples/s,0.00 ms,115.66 mW,451626.62 pJ/it +matmul/matrix_vector,arch-a,PASS,PASS,0.098 s,0.52 MiB,0.78 MiB,168,173,0.38 ms,202.13 mW,77751476.88 pJ,0.289 s,1.04 MiB,0.84 MiB,44,171,2150.00 samples/s,0.46 ms,119.16 mW,65096859.53 pJ/it +matmul/vector_matrix,arch-a,PASS,PASS,0.089 s,0.01 MiB,0.01 MiB,9,8,0.01 ms,118.70 mW,878749.92 pJ,0.083 s,0.02 MiB,0.02 MiB,10,8,140000.00 samples/s,0.01 ms,115.31 mW,910373.16 pJ/it +matmul/yolo_attention,arch-a,PASS,PASS,0.474 s,1.02 MiB,43.44 MiB,168,0,8.15 ms,170.00 mW,1385775865.00 pJ,0.645 s,5.57 MiB,42.54 MiB,75,0,145.00 samples/s,6.89 ms,119.04 mW,932561637.00 pJ/it +mul/after_conv,arch-a,PASS,PASS,0.059 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,107.64 mW,586955.72 pJ,0.050 s,0.00 MiB,0.00 MiB,4,3,194000.00 samples/s,0.01 ms,58.31 mW,304072.05 pJ/it +mul/after_conv_scalar_constant,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,107.64 mW,586955.72 pJ,0.046 s,0.00 MiB,0.00 MiB,4,3,194000.00 samples/s,0.01 ms,58.31 mW,304072.05 pJ/it +mul/basic,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.040 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +mul/channel_broadcast_1024,arch-a,PASS,PASS,0.050 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.038 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it +mul/leading_dimension_broadcast,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.038 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +mul/scalar_constant,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.034 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +pool/avg_basic,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.02 mW,929400.00 pJ,0.038 s,0.00 MiB,0.00 MiB,1,0,84200.00 samples/s,0.01 ms,2.02 mW,24013.00 pJ/it +pool/avg_ceil_mode,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.03 mW,339210.00 pJ,0.044 s,0.00 MiB,0.00 MiB,1,0,230000.00 samples/s,0.00 ms,2.03 mW,8786.67 pJ/it +pool/avg_explicit_padding,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.03 mW,685860.00 pJ,0.039 s,0.00 MiB,0.00 MiB,1,0,114000.00 samples/s,0.01 ms,2.03 mW,17745.00 pJ/it +pool/avg_include_pad,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.02 mW,661116.00 pJ,0.041 s,0.00 MiB,0.00 MiB,1,0,118000.00 samples/s,0.01 ms,2.02 mW,17017.00 pJ/it +pool/avg_large_channels,arch-a,PASS,PASS,0.059 s,0.04 MiB,0.02 MiB,1,0,0.24 ms,78.00 mW,18397284.00 pJ,0.046 s,0.04 MiB,0.02 MiB,1,0,4250.00 samples/s,0.24 ms,2.00 mW,471380.00 pJ/it +pool/avg_non_uniform_stride,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.02 mW,1129134.00 pJ,0.039 s,0.00 MiB,0.00 MiB,1,0,69300.00 samples/s,0.01 ms,2.02 mW,29111.00 pJ/it +pool/avg_real_asymmetric_padding,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,0.03 ms,78.02 mW,1959204.00 pJ,0.041 s,0.00 MiB,0.00 MiB,1,0,39900.00 samples/s,0.03 ms,2.02 mW,50769.00 pJ/it +pool/max_after_conv,arch-a,PASS,PASS,0.063 s,0.00 MiB,0.00 MiB,5,4,0.01 ms,99.12 mW,1209961.96 pJ,0.051 s,0.00 MiB,0.00 MiB,5,4,140000.00 samples/s,0.01 ms,58.47 mW,468396.45 pJ/it +pool/max_basic,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.06 mW,324744.00 pJ,0.039 s,0.00 MiB,0.00 MiB,1,0,241000.00 samples/s,0.00 ms,2.06 mW,8532.67 pJ/it +pool/max_ceil_mode,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.07 mW,151464.00 pJ,0.035 s,0.00 MiB,0.00 MiB,1,0,516000.00 samples/s,0.00 ms,2.07 mW,3972.67 pJ/it +pool/max_global_style_kernel_equals_input,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.01 mW,657534.00 pJ,0.042 s,0.00 MiB,0.00 MiB,1,0,119000.00 samples/s,0.01 ms,2.01 mW,16843.00 pJ/it +pool/max_non_square_kernel,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.02 mW,1060572.00 pJ,0.047 s,0.00 MiB,0.00 MiB,1,0,73700.00 samples/s,0.01 ms,2.02 mW,27353.00 pJ/it +pool/max_real_asymmetric_padding,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.03 mW,814992.00 pJ,0.040 s,0.00 MiB,0.00 MiB,1,0,96100.00 samples/s,0.01 ms,2.03 mW,21173.00 pJ/it +pool/max_same_upper,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.04 mW,625068.00 pJ,0.042 s,0.00 MiB,0.00 MiB,1,0,125000.00 samples/s,0.01 ms,2.04 mW,16233.00 pJ/it +pool/max_stride2_multichannel,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.02 ms,78.02 mW,1245870.00 pJ,0.036 s,0.00 MiB,0.00 MiB,1,0,62800.00 samples/s,0.02 ms,2.02 mW,32117.00 pJ/it +reduce_mean/4d_spatial,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.02 mW,326814.00 pJ,0.044 s,0.00 MiB,0.00 MiB,1,0,239000.00 samples/s,0.00 ms,2.02 mW,8390.67 pJ/it +reduce_mean/4d_spatial_keepdims_0,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,94.35 mW,61801.00 pJ,0.041 s,0.00 MiB,0.00 MiB,4,0,1470000.00 samples/s,0.00 ms,44.66 mW,31425.33 pJ/it +reduce_mean/after_conv,arch-a,PASS,PASS,0.062 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,100.79 mW,1119699.72 pJ,0.057 s,0.00 MiB,0.00 MiB,4,3,125000.00 samples/s,0.01 ms,54.14 mW,474782.17 pJ/it +reduce_mean/all_axes_keepdims_0,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,2,0,0.00 ms,79.24 mW,30982.00 pJ,0.038 s,0.00 MiB,0.00 MiB,2,0,2720000.00 samples/s,0.00 ms,44.37 mW,16707.00 pJ/it +reduce_mean/all_axes_keepdims_1,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.039 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it +reduce_mean/basic,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,93.51 mW,34881.00 pJ,0.042 s,0.00 MiB,0.00 MiB,4,0,2600000.00 samples/s,0.00 ms,5.85 mW,2235.67 pJ/it +reduce_mean/channel_axis_nchw,arch-a,PASS,PASS,0.054 s,0.03 MiB,0.02 MiB,4,0,0.16 ms,93.60 mW,15436518.00 pJ,0.040 s,0.03 MiB,0.08 MiB,4,0,12900.00 samples/s,0.08 ms,5.00 mW,388853.50 pJ/it +reduce_mean/keepdims_0,arch-a,PASS,PASS,0.053 s,0.00 MiB,0.00 MiB,5,0,0.00 ms,91.40 mW,68368.00 pJ,0.043 s,0.00 MiB,0.00 MiB,5,0,1300000.00 samples/s,0.00 ms,44.76 mW,36032.00 pJ/it +reduce_mean/large_dimension_1024,arch-a,PASS,PASS,0.048 s,0.01 MiB,0.00 MiB,1,0,0.00 ms,78.02 mW,217278.00 pJ,0.040 s,0.01 MiB,0.00 MiB,1,0,359000.00 samples/s,0.00 ms,2.02 mW,5274.00 pJ/it +reduce_mean/legacy_axes_1_2_keepdims_1,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,2,0,0.00 ms,79.35 mW,21505.00 pJ,0.042 s,0.00 MiB,0.00 MiB,2,0,3620000.00 samples/s,0.00 ms,3.45 mW,898.00 pJ/it +reduce_mean/legacy_axis1_keepdims_0,arch-a,PASS,PASS,0.056 s,0.00 MiB,0.00 MiB,9,0,0.00 ms,92.50 mW,183708.00 pJ,0.042 s,0.00 MiB,0.00 MiB,9,0,654000.00 samples/s,0.00 ms,45.89 mW,72573.50 pJ/it +reduce_mean/legacy_axis1_keepdims_1,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,8,0,0.00 ms,94.56 mW,129830.00 pJ,0.049 s,0.00 MiB,0.00 MiB,8,0,1340000.00 samples/s,0.00 ms,10.15 mW,7594.50 pJ/it +reduce_mean/legacy_empty_axes_noop,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.037 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it +reduce_mean/legacy_nchw_spatial,arch-a,PASS,PASS,0.055 s,0.00 MiB,0.00 MiB,1,0,0.01 ms,78.01 mW,498648.00 pJ,0.044 s,0.00 MiB,0.00 MiB,1,0,156000.00 samples/s,0.01 ms,2.01 mW,12796.67 pJ/it +reduce_mean/legacy_negative_axis,arch-a,PASS,PASS,0.053 s,0.00 MiB,0.00 MiB,6,0,0.00 ms,93.52 mW,51717.00 pJ,0.041 s,0.00 MiB,0.00 MiB,6,0,1760000.00 samples/s,0.00 ms,8.07 mW,4588.50 pJ/it +reduce_mean/legacy_reduce_all_keepdims_1,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.038 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it +reduce_mean/negative_axis,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,6,0,0.00 ms,93.52 mW,51717.00 pJ,0.041 s,0.00 MiB,0.00 MiB,6,0,1760000.00 samples/s,0.00 ms,8.07 mW,4588.50 pJ/it +relu/4d,arch-a,PASS,PASS,0.047 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.18 mW,40734.00 pJ,0.046 s,0.00 MiB,0.00 MiB,1,0,1930000.00 samples/s,0.00 ms,2.18 mW,1014.00 pJ/it +relu/after_conv,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.00 MiB,4,3,0.01 ms,107.89 mW,577437.72 pJ,0.048 s,0.00 MiB,0.00 MiB,4,3,191000.00 samples/s,0.01 ms,58.26 mW,304800.72 pJ/it +relu/after_gemm,arch-a,PASS,PASS,0.054 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,105.16 mW,790056.96 pJ,0.042 s,0.01 MiB,0.01 MiB,6,4,230000.00 samples/s,0.00 ms,109.21 mW,545663.29 pJ/it +relu/basic,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.036 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it +reshape/4d_to_2d_flatten,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.28 mW,20196.00 pJ,0.039 s,0.00 MiB,0.00 MiB,1,0,3910000.00 samples/s,0.00 ms,2.28 mW,488.00 pJ/it +reshape/infer_dim_minus_one,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,12684.00 pJ,0.036 s,0.00 MiB,0.00 MiB,1,0,6250000.00 samples/s,0.00 ms,2.30 mW,308.00 pJ/it +reshape/same_rank,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,12684.00 pJ,0.036 s,0.00 MiB,0.00 MiB,1,0,6250000.00 samples/s,0.00 ms,2.30 mW,308.00 pJ/it +reshape/zero_copies_input_dim,arch-a,PASS,PASS,0.054 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,12684.00 pJ,0.034 s,0.00 MiB,0.00 MiB,1,0,6250000.00 samples/s,0.00 ms,2.30 mW,308.00 pJ/it +resize/height_only,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,93.55 mW,64833.00 pJ,0.038 s,0.00 MiB,0.00 MiB,4,0,1880000.00 samples/s,0.00 ms,5.60 mW,2986.00 pJ/it +resize/nearest_2x,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,4,0,0.00 ms,93.57 mW,109761.00 pJ,0.038 s,0.00 MiB,0.00 MiB,4,0,1450000.00 samples/s,0.00 ms,5.46 mW,3776.00 pJ/it +resize/nearest_downsample,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,2,0,0.00 ms,79.45 mW,33925.00 pJ,0.039 s,0.00 MiB,0.00 MiB,2,0,2330000.00 samples/s,0.00 ms,3.28 mW,1360.50 pJ/it +resize/non_uniform_scales,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,6,0,0.00 ms,93.58 mW,164037.00 pJ,0.042 s,0.00 MiB,0.00 MiB,6,0,1250000.00 samples/s,0.00 ms,7.76 mW,6207.25 pJ/it +resize/width_only,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,2,0,0.00 ms,79.50 mW,53029.00 pJ,0.037 s,0.00 MiB,0.00 MiB,2,0,1700000.00 samples/s,0.00 ms,3.20 mW,1833.50 pJ/it +resize/with_sizes,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,3,0,0.00 ms,92.54 mW,73756.00 pJ,0.039 s,0.00 MiB,0.00 MiB,3,0,1700000.00 samples/s,0.00 ms,4.39 mW,2586.75 pJ/it +sigmoid/4d,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.18 mW,40734.00 pJ,0.035 s,0.00 MiB,0.00 MiB,1,0,1930000.00 samples/s,0.00 ms,2.18 mW,1014.00 pJ/it +sigmoid/after_gemm,arch-a,PASS,PASS,0.054 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,105.16 mW,790056.96 pJ,0.043 s,0.01 MiB,0.01 MiB,6,4,230000.00 samples/s,0.00 ms,109.21 mW,545663.29 pJ/it +sigmoid/basic,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,17286.00 pJ,0.036 s,0.00 MiB,0.00 MiB,1,0,4570000.00 samples/s,0.00 ms,2.22 mW,437.33 pJ/it +slice/2d_basic,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,18948.00 pJ,0.038 s,0.00 MiB,0.00 MiB,1,0,4170000.00 samples/s,0.00 ms,2.30 mW,491.67 pJ/it +slice/after_conv,arch-a,PASS,PASS,0.057 s,0.00 MiB,0.01 MiB,7,6,0.01 ms,118.19 mW,1335082.88 pJ,0.053 s,0.00 MiB,0.01 MiB,7,6,106000.00 samples/s,0.01 ms,73.96 mW,732218.55 pJ/it +slice/default_axes,arch-a,PASS,PASS,0.047 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,18948.00 pJ,0.035 s,0.00 MiB,0.00 MiB,1,0,4170000.00 samples/s,0.00 ms,2.30 mW,491.67 pJ/it +slice/large_channel_1024,arch-a,PASS,PASS,0.049 s,0.01 MiB,0.00 MiB,1,0,0.00 ms,78.14 mW,221304.00 pJ,0.036 s,0.01 MiB,0.00 MiB,1,0,353000.00 samples/s,0.00 ms,2.14 mW,5058.00 pJ/it +slice/nchw_spatial_crop,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.24 mW,101868.00 pJ,0.042 s,0.00 MiB,0.00 MiB,1,0,769000.00 samples/s,0.00 ms,2.24 mW,2851.67 pJ/it +slice/negative_axis,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,44004.00 pJ,0.037 s,0.00 MiB,0.00 MiB,1,0,1790000.00 samples/s,0.00 ms,2.30 mW,1227.67 pJ/it +slice/negative_indices,arch-a,PASS,PASS,0.052 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,25212.00 pJ,0.037 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.30 mW,675.67 pJ/it +slice/step2,arch-a,PASS,PASS,0.053 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.29 mW,159876.00 pJ,0.042 s,0.00 MiB,0.00 MiB,1,0,490000.00 samples/s,0.00 ms,2.29 mW,4619.67 pJ/it +softmax/3d_last_axis,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.035 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED +softmax/basic,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.036 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED +softmax/channel_axis,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.040 s,0.00 MiB,0.00 MiB,3,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED +softmax/large_dimension_1024,arch-a,PASS,PASS,0.049 s,0.01 MiB,0.01 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.036 s,0.01 MiB,0.01 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED +softmax/negative_axis,arch-a,PASS,PASS,0.048 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,0.036 s,0.00 MiB,0.00 MiB,1,0,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED,UNSUPPORTED +split/basic,arch-a,PASS,PASS,0.051 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,31554.00 pJ,0.037 s,0.00 MiB,0.00 MiB,1,0,2490000.00 samples/s,0.00 ms,2.30 mW,861.67 pJ/it +split/equal_three_way,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,44160.00 pJ,0.035 s,0.00 MiB,0.00 MiB,1,0,1780000.00 samples/s,0.00 ms,2.30 mW,1231.67 pJ/it +split/negative_axis,arch-a,PASS,PASS,0.053 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.29 mW,84786.00 pJ,0.039 s,0.00 MiB,0.00 MiB,1,0,925000.00 samples/s,0.00 ms,2.29 mW,2413.67 pJ/it +split/uneven_channel_axis_4d,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.30 mW,18948.00 pJ,0.046 s,0.00 MiB,0.00 MiB,1,0,4170000.00 samples/s,0.00 ms,2.30 mW,491.67 pJ/it +sub/after_gemm,arch-a,PASS,PASS,0.056 s,0.01 MiB,0.01 MiB,5,4,0.01 ms,104.70 mW,815012.96 pJ,0.045 s,0.01 MiB,0.01 MiB,6,4,218000.00 samples/s,0.00 ms,107.94 mW,570766.12 pJ/it +sub/basic,arch-a,PASS,PASS,0.046 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.037 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +sub/broadcast_row,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.042 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it +sub/channel_broadcast_1024,arch-a,PASS,PASS,0.052 s,0.02 MiB,0.01 MiB,1,0,0.01 ms,78.12 mW,540030.00 pJ,0.037 s,0.02 MiB,0.01 MiB,1,0,145000.00 samples/s,0.01 ms,2.11 mW,13388.67 pJ/it +sub/constant_lhs_broadcast,arch-a,PASS,PASS,0.049 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25188.00 pJ,0.034 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,656.67 pJ/it +sub/leading_dimension_broadcast,arch-a,PASS,PASS,0.050 s,0.00 MiB,0.00 MiB,1,0,0.00 ms,78.22 mW,25266.00 pJ,0.038 s,0.00 MiB,0.00 MiB,1,0,3120000.00 samples/s,0.00 ms,2.23 mW,658.67 pJ/it diff --git a/validation/tools/pim/pimcomp/compare/compare_raptor_pimcomp.py b/validation/tools/pim/pimcomp/compare/compare_raptor_pimcomp.py index 9017f4e..021b0c7 100755 --- a/validation/tools/pim/pimcomp/compare/compare_raptor_pimcomp.py +++ b/validation/tools/pim/pimcomp/compare/compare_raptor_pimcomp.py @@ -1153,6 +1153,7 @@ def write_report( pimcomp_pipeline: str, pimcomp_replication: str, ): + report_path.parent.mkdir(parents=True, exist_ok=True) lines = [ "# Raptor vs PIMCOMP Comparison Report", "", @@ -1302,6 +1303,11 @@ def write_report( def main(): parser = argparse.ArgumentParser() parser.add_argument("--model", required=True, type=Path) + parser.add_argument( + "--functional-model", + type=Path, + help="Optional canonical model used only for Raptor functional validation.", + ) parser.add_argument("--out-dir", required=True, type=Path) parser.add_argument( "--common-dir", @@ -1325,7 +1331,7 @@ def main(): parser.add_argument("--pimsim-nn-build-dir", default=REPO / "backend-simulators/pim/pimsim-nn/build", type=Path) parser.add_argument("--seed", type=int, default=0) parser.add_argument("--threshold", type=float, default=1e-3) - parser.add_argument("--rtol", type=float, default=1e-5) + parser.add_argument("--rtol", type=float, default=1e-4) parser.add_argument( "--timeout-seconds", type=float, @@ -1390,6 +1396,11 @@ def main(): args.pimcomp_pipeline = "element" if args.pimsim_mode == "latency" else "batch" model_path = args.model.resolve() + functional_model_path = ( + args.functional_model.resolve() + if args.functional_model is not None + else model_path + ) args.pimcomp_dir = args.pimcomp_dir.resolve() args.pimcomp_config = ( args.pimcomp_config.resolve() @@ -1407,7 +1418,7 @@ def main(): if args.prepare_common: print_step("Prepare shared artifacts") - prepare_common_artifacts(args, model_path, common_dir) + prepare_common_artifacts(args, functional_model_path, common_dir) print(f"Shared artifacts: {common_dir}") return @@ -1450,7 +1461,13 @@ def main(): if loaded_hardware is not None: hardware = loaded_hardware - model_io = try_stage(failures, "Load model inputs", load_model_inputs, model_path, args.seed) + model_io = try_stage( + failures, + "Load model inputs", + load_model_inputs, + functional_model_path, + args.seed, + ) if model_io is not None: inputs_desc, outputs_desc, arrays_in_order = model_io runtime_inputs = arrays_in_order @@ -1530,7 +1547,7 @@ def main(): "Compile reference", compile_reference, args, - model_path, + functional_model_path, common_dir, steps, ) @@ -1548,7 +1565,7 @@ def main(): generate_reference_outputs, runner_path, runner_path.parent, - model_path, + functional_model_path, arrays_in_order, steps, args, @@ -1578,7 +1595,7 @@ def main(): generate_reference_batch_outputs, runner_path, runner_path.parent, - model_path, + functional_model_path, input_batch, steps, args, @@ -1610,13 +1627,33 @@ def main(): "Raptor PIM compile was skipped because the ONNX model or hardware configuration is not available.", ) - if not reuse_raptor and raptor_pim_dir is not None: + raptor_functional_pim_dir = raptor_pim_dir + if ( + not reuse_raptor + and functional_model_path != model_path + and hardware["core_count"] > 0 + ): + compiled_functional = try_stage( + failures, + "Compile Raptor functional PIM", + compile_raptor_target, + functional_model_path, + out_dir / "raptor_functional", + hardware, + args, + steps, + ) + raptor_functional_pim_dir = ( + compiled_functional[0] if compiled_functional is not None else None + ) + + if not reuse_raptor and raptor_functional_pim_dir is not None: wrote_inputs = try_stage_success( failures, "Write Raptor inputs", write_inputs_to_memory_bin, - raptor_pim_dir / "memory.bin", - raptor_pim_dir / "config.json", + raptor_functional_pim_dir / "memory.bin", + raptor_functional_pim_dir / "config.json", runtime_inputs, ) if wrote_inputs and reference_dirs and outputs_desc: @@ -1625,8 +1662,8 @@ def main(): "Functional Validation Raptor", run_functional_validation, "Functional Validation Raptor", - raptor_pim_dir, - raptor_pim_dir / "config.json", + raptor_functional_pim_dir, + raptor_functional_pim_dir / "config.json", out_dir / "simulation/out.bin", raptor_input_bins, outputs_desc, @@ -1847,6 +1884,7 @@ def main(): json_report = { "model": str(model_path), + "functional_model": str(functional_model_path), "hardware": hardware, "pimsim_mode": args.pimsim_mode, "pimsim_time_ms": args.pimsim_time_ms, @@ -1874,6 +1912,7 @@ def main(): "batch_outputs": optional_path(out_dir / "simulation/out_iterations"), "reference_runner": optional_path(runner_path), "raptor_pim": optional_path(raptor_pim_dir), + "raptor_functional_pim": optional_path(raptor_functional_pim_dir), "raptor_pimsim_nn": optional_path(raptor_pimsim_dir), "pimcomp_simulation_info": optional_path(simulation_info), "pimcomp_exported_pim": optional_path(pimcomp_export_dir), diff --git a/validation/tools/pim/pimcomp/compare/run_pimcomp_paper_latency.py b/validation/tools/pim/pimcomp/compare/run_pimcomp_paper_latency.py index 491bfef..b053e45 100755 --- a/validation/tools/pim/pimcomp/compare/run_pimcomp_paper_latency.py +++ b/validation/tools/pim/pimcomp/compare/run_pimcomp_paper_latency.py @@ -36,6 +36,10 @@ MODELS = { "googlenet": SUITE / "googlenet/googlenet-12-pimsim-nn.onnx", "yolo11n": SUITE / "yolo11n/yolo11n-pimsim-nn.onnx", } +FUNCTIONAL_MODELS = { + **MODELS, + "yolo11n": REPO / "validation/networks/yolo11n/depth_51/yolo11n_depth_51.onnx", +} COMPARISONS = ( ("latency", 1, "element"), ("throughput", 2, "batch"), @@ -48,6 +52,7 @@ COMPARISONS = ( class ComparisonSpec: label: str model: Path + functional_model: Path output_dir: Path common_dir: Path config: Path @@ -68,6 +73,11 @@ def result_dir(root: Path | None, name: str, arch: str, mode: str, pipeline: int return base / arch / suffix +def common_dir(root: Path | None, name: str) -> Path: + suffix = "common" if FUNCTIONAL_MODELS[name] == MODELS[name] else "common-functional" + return model_dir(root, name) / suffix + + def clean_artifacts(root: Path | None, models: list[str], arches: list[str]) -> int: removed = 0 for name in models: @@ -78,10 +88,10 @@ def clean_artifacts(root: Path | None, models: list[str], arches: list[str]) -> if path.is_dir() and not path.is_symlink(): shutil.rmtree(path) removed += 1 - common = base / "common" - if common.is_dir() and not common.is_symlink(): - shutil.rmtree(common) - removed += 1 + for common in (base / "common", base / "common-functional"): + if common.is_dir() and not common.is_symlink(): + shutil.rmtree(common) + removed += 1 for path in ( (root or SUITE) / "results.csv", (root or SUITE) / "results_latency.csv", @@ -316,6 +326,7 @@ def validate_pimcomp_source() -> None: def comparison_command( model: Path, + functional_model: Path, result_dir: Path, common_dir: Path, config: Path, @@ -343,6 +354,8 @@ def comparison_command( str(COMPARE), "--model", str(model), + "--functional-model", + str(functional_model), "--out-dir", str(result_dir), "--common-dir", @@ -394,6 +407,7 @@ def comparison_command_for( report = spec.output_dir / "pimcomp/comparison_report.json" return comparison_command( spec.model, + spec.functional_model, spec.output_dir, spec.common_dir, spec.config, @@ -586,7 +600,12 @@ def main() -> int: comparisons_by_arch[arch] = comparisons configs_by_arch[arch] = configs - missing = [str(MODELS[name]) for name in args.models if not MODELS[name].exists()] + missing = [ + str(path) + for name in args.models + for path in (MODELS[name], FUNCTIONAL_MODELS[name]) + if not path.exists() + ] if missing: parser.error(f"missing model(s): {', '.join(missing)}") @@ -631,8 +650,8 @@ def main() -> int: try: run( prepare_common_command( - MODELS[name], - model_dir(out_dir, name) / "common", + FUNCTIONAL_MODELS[name], + common_dir(out_dir, name), args.timeout_seconds, ), dry_run=args.dry_run, @@ -660,8 +679,9 @@ def main() -> int: ComparisonSpec( label=label, model=MODELS[name], + functional_model=FUNCTIONAL_MODELS[name], output_dir=model_result_dir, - common_dir=model_dir(out_dir, name) / "common", + common_dir=common_dir(out_dir, name), config=configs[mode], mode=mode, pipeline=pipeline,