Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ inline constexpr llvm::StringLiteral kLoadStoreBufCount =
"ssbuffer.load_store_buf_count";
inline constexpr llvm::StringLiteral kAnalyzeFlagId =
"ssbuffer.analyze_flag_id";
inline constexpr llvm::StringLiteral kLoopId = "ssbuffer.loop_id";
inline constexpr llvm::StringLiteral kLoopCarriedL0C =
"ssbuffer.loop_carried_l0c";
inline constexpr llvm::StringLiteral kCrossCoreDeps = "ssbuffer.crossCoreDeps";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,14 @@ class InterCoreTransferAndSyncPass
int markAllocIndex = 0;
int intraDepsGroupId = 0;

llvm::DenseMap<int, llvm::SmallVector<LoopLikeOpInterface>> loopInclusions;
llvm::DenseSet<int> singleLoopSet;

llvm::DenseMap<mlir::Value, mlir::Value> ndnzValueMapping;
SSBufferManager ssbufferManager;

void analyzeLoopInclusion();
void moveStartEndSync(mlir::OpBuilder &builder);
mlir::LogicalResult
processDependencies(FlagIdManager &flagManager,
FlagIdReuseManager &flagIdReuseManager);
Expand Down
34 changes: 22 additions & 12 deletions third_party/ascend/lib/DynamicCVPipeline/RemoveAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,28 @@ static constexpr const char *DEBUG_TYPE = "RemoveAttributes";

// if extra attr is needed, add to ut @
// third_party/ascend/unittest/Conversion/General/DynamicCVPipeline/test-remove-attrs.mlir
static constexpr llvm::StringLiteral kAttrsToRemove[]{
kBlockId, kCoreType,
kTransferId, kMainLoop,
kCubeFirst, kVectorFirst,
kAddFromMatmul, kIntraDeps,
kIntraBuffer, kAnalyzeFlagId,
kLoopCarriedL0C, kCrossCoreDeps,
kMemCrossDeps, kClone,
kIntraBufCount, kInterCoreBufCount,
kLoadStoreBufCount, kInsertionOptimization,
kDepMark, kIntraDeps,
kSubBlock};
static constexpr llvm::StringLiteral kAttrsToRemove[]{kBlockId,
kCoreType,
kTransferId,
kMainLoop,
kCubeFirst,
kVectorFirst,
kAddFromMatmul,
kIntraDeps,
kIntraBuffer,
kAnalyzeFlagId,
kLoopId,
kLoopCarriedL0C,
kCrossCoreDeps,
kMemCrossDeps,
kClone,
kIntraBufCount,
kInterCoreBufCount,
kLoadStoreBufCount,
kInsertionOptimization,
kDepMark,
kIntraDeps,
kSubBlock};

void RemoveSsbufAttrPass::runOnOperation() {
auto module = getOperation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ static void attachTransferTags(Operation *op, int blockId, StringRef coreType,
IntegerAttr::get(IntegerType::get(ctx, kIntegerBitWidth), transferId));
}

static void attachLoopIdTag(Operation *op, int loopId) {
MLIRContext *ctx = op->getContext();
op->setAttr(
CVPipeline::kLoopId,
IntegerAttr::get(IntegerType::get(ctx, kIntegerBitWidth), loopId));
}

static void attachMemCrossDeps(Operation *op, int tid, int seqId,
OpBuilder &builder) {
op->setAttr(CVPipeline::kMemCrossDeps,
Expand Down Expand Up @@ -1077,6 +1084,11 @@ void InterCoreTransferAndSyncPass::insertInterCoreSync(
attachAnalyzeFlagIdTag(setOpForWrite);
attachAnalyzeFlagIdTag(setOpForStart);
attachAnalyzeFlagIdTag(waitOpForEnd);

auto loopId =
mainLoopOp->getAttrOfType<IntegerAttr>(CVPipeline::kLoopId).getInt();
attachLoopIdTag(setOpForStart, loopId);
attachLoopIdTag(waitOpForEnd, loopId);
// E2: register every set->wait pair of this transfer, not just the
// loop start/end pair. Each pair is the only proof of cross-core
// ordering for the sync ops it connects.
Expand Down Expand Up @@ -2024,6 +2036,89 @@ void InterCoreTransferAndSyncPass::sortDependencies(
});
}

void InterCoreTransferAndSyncPass::analyzeLoopInclusion() {
loopInclusions.clear();
int maxLoopId = -1;
module.walk<WalkOrder::PreOrder>([&](Operation *op) {
auto loopOp = dyn_cast<LoopLikeOpInterface>(op);
if (!loopOp) {
return;
}

int loopId = 0;
Operation *parentLoop =
loopOp.getOperation()->getParentOfType<LoopLikeOpInterface>();
while (parentLoop) {
++loopId;
parentLoop = parentLoop->getParentOfType<LoopLikeOpInterface>();
}
loopOp->setAttr(
CVPipeline::kLoopId,
IntegerAttr::get(
IntegerType::get(loopOp->getContext(), kIntegerBitWidth), loopId));
loopInclusions[loopId].push_back(loopOp);
maxLoopId = std::max(maxLoopId, loopId);
});
for (int loopId = 0; loopId <= maxLoopId; ++loopId) {
if (loopInclusions[loopId].size() != 1) {
continue;
}
bool allSingle = true;
for (int outerId = loopId - 1; outerId >= 0; --outerId) {
if (loopInclusions[outerId].size() != 1) {
allSingle = false;
break;
}
}
if (allSingle) {
singleLoopSet.insert(loopId);
}
}
}

void InterCoreTransferAndSyncPass::moveStartEndSync(OpBuilder &builder) {
llvm::SmallVector<Operation *> startSyncOps;
llvm::SmallVector<Operation *> endSyncOps;
module.walk<WalkOrder::PreOrder>([&](Operation *op) {
if (!op->hasAttr(CVPipeline::kLoopId) ||
!(isa<hivm::SyncBlockSetOp, hivm::SyncBlockWaitOp>(op))) {
return;
}
auto loopId = op->getAttrOfType<IntegerAttr>(CVPipeline::kLoopId).getInt();
auto it = singleLoopSet.find(loopId);
if (it != singleLoopSet.end()) {
if (isa<hivm::SyncBlockSetOp>(op)) {
startSyncOps.push_back(op);
} else if (isa<hivm::SyncBlockWaitOp>(op)) {
endSyncOps.push_back(op);
}
}
});

if (loopInclusions.count(0) == 0 || loopInclusions[0].empty()) {
return;
}
Operation *outerLoop = loopInclusions[0][0];
if (!outerLoop) {
return;
}
// move startSyncOps and endSyncOps to the outer loop
builder.setInsertionPoint(outerLoop);
for (auto it = startSyncOps.begin(); it != startSyncOps.end(); ++it) {
builder.clone(**it);
}
builder.setInsertionPointAfter(outerLoop);
for (auto op : endSyncOps) {
builder.clone(*op);
}
for (auto op : startSyncOps) {
op->erase();
}
for (auto op : endSyncOps) {
op->erase();
}
}

// Main Processing
LogicalResult InterCoreTransferAndSyncPass::processDependencies(
FlagIdManager &flagManager, FlagIdReuseManager &flagIdReuseManager) {
Expand All @@ -2036,6 +2131,9 @@ LogicalResult InterCoreTransferAndSyncPass::processDependencies(
return failure();
}

// Analyze loop nesting before inserting inter-core transfer/sync.
analyzeLoopInclusion();

llvm::SmallVector<DependencyInfo> &V2CDependencies =
info.getV2CDependencies();
sortDependencies(V2CDependencies, module);
Expand Down Expand Up @@ -2149,6 +2247,9 @@ LogicalResult InterCoreTransferAndSyncPass::processDependencies(
// tensor computation occurs between the transfer and the store.
processCubeToVectorDirectStoreSync(builder, flagManager, flagIdReuseManager);

// move start/end sync ops
moveStartEndSync(builder);

LOG_DEBUG("InterCoreTransferAndSyncPass success!\n");

return success();
Expand Down
Loading