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
2 changes: 1 addition & 1 deletion include/NeuraDialect/Architecture/Architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ class Architecture {
// specific tiles are valid:
// std::vector<TileOverride> overrides;
// // First mark all tiles as non-existent, then mark valid ones existent.
// // (see MapToAcceleratorPass for the full valid_tiles parsing logic)
// // (see MapOperationOnTilePass for the full valid_tiles parsing logic)
// auto arch_T = getArchitecture().cloneWithNewDimensions(8, 12, overrides);
std::unique_ptr<Architecture> cloneWithNewDimensions(
int new_per_cgra_rows, int new_per_cgra_columns,
Expand Down
6 changes: 3 additions & 3 deletions include/NeuraDialect/NeuraPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ std::unique_ptr<mlir::Pass> createInsertCtrlMovPass();
std::unique_ptr<mlir::Pass> createAssignAcceleratorPass();
std::unique_ptr<mlir::Pass> createTransformCtrlToDataFlowPass();
std::unique_ptr<mlir::Pass> createLeveragePredicatedValuePass();
// Creates the MapToAccelerator pass. Tile dimensions default to 0 (use
// Creates the MapOperationOnTile pass. Tile dimensions default to 0 (use
// architecture singleton) when not specified via options.
std::unique_ptr<mlir::Pass> createMapToAcceleratorPass(
const MapToAcceleratorOptions &options = MapToAcceleratorOptions{});
std::unique_ptr<mlir::Pass> createMapOperationOnTilePass(
const MapOperationOnTileOptions &options = MapOperationOnTileOptions{});
std::unique_ptr<mlir::Pass> createGenerateCodePass();
std::unique_ptr<mlir::Pass> createCanonicalizeReturnPass();
std::unique_ptr<mlir::Pass> createCanonicalizeLiveInPass();
Expand Down
10 changes: 5 additions & 5 deletions include/NeuraDialect/NeuraPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def LeveragePredicatedValue : Pass<"leverage-predicated-value", "ModuleOp"> {
let constructor = "neura::createLeveragePredicatedValuePass()";
}

def MapToAccelerator : Pass<"map-to-accelerator", "ModuleOp"> {
def MapOperationOnTile : Pass<"map-operation-on-tile", "ModuleOp"> {
let summary = "Map Neura operations onto a given accelerator";
let description = [{
This pass performs mapping from Neura operations to accelerator.
Expand All @@ -65,11 +65,11 @@ def MapToAccelerator : Pass<"map-to-accelerator", "ModuleOp"> {

Examples:
Single CGRA (default):
--map-to-accelerator
--map-operation-on-tile
1×3 rectangular (3 CGRAs in a row):
--map-to-accelerator x-tiles=12 y-tiles=4
--map-operation-on-tile x-tiles=12 y-tiles=4
T-shape (4 CGRAs: top row of 3 + centre below):
--map-to-accelerator x-tiles=12 y-tiles=8 \
--map-operation-on-tile x-tiles=12 y-tiles=8 \
valid-tiles="0_0,1_0,2_0,3_0,4_0,5_0,6_0,7_0,8_0,9_0,10_0,11_0,\
4_1,5_1,6_1,7_1,4_4,5_4,6_4,7_4,4_5,5_5,6_5,7_5"
}];
Expand All @@ -89,7 +89,7 @@ def MapToAccelerator : Pass<"map-to-accelerator", "ModuleOp"> {
"x-tiles x y-tiles rectangle are valid. "
"Example: 0_0,1_0,0_1 selects three tiles forming an L-shape.">
];
let constructor = "neura::createMapToAcceleratorPass()";
let constructor = "neura::createMapOperationOnTilePass()";
}

def GenerateCode : Pass<"generate-code", "ModuleOp"> {
Expand Down
9 changes: 8 additions & 1 deletion include/TaskflowDialect/TaskflowPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "TaskflowDialect/TaskflowDialect.h"
#include "TaskflowDialect/TaskflowOps.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Pass/PassRegistry.h"
Expand All @@ -21,9 +22,15 @@ void registerTosaToAffineConversionPassPipeline();
#include "TaskflowDialect/TaskflowPasses.h.inc"
std::unique_ptr<mlir::Pass> createConstructHyperblockFromTaskPass();
std::unique_ptr<mlir::Pass> createClassifyCountersPass();
std::unique_ptr<mlir::Pass> createMapTaskOnCgraPass();
std::unique_ptr<mlir::Pass> createAllocateCgraToTaskPass();
std::unique_ptr<mlir::Pass> createFuseTaskPass();


// Runs the CGRA task placement logic directly on a function.
// grid_rows/grid_cols default to 4x4 (kCgraGridRows/kCgraGridCols).
void runAllocateCgraToTask(mlir::func::FuncOp func,
int grid_rows = 4, int grid_cols = 4);

//=========================================================//
// Optimization Passes
//=========================================================//
Expand Down
4 changes: 2 additions & 2 deletions include/TaskflowDialect/TaskflowPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def ClassifyCounters : Pass<"classify-counters", "ModuleOp">{
let constructor = "taskflow::createClassifyCountersPass()";
}

def MapTaskOnCgra : Pass<"map-task-on-cgra", "func::FuncOp"> {
def AllocateCgraToTask : Pass<"allocate-cgra-to-task", "func::FuncOp"> {
let summary = "Maps Taskflow tasks onto a 2D CGRA grid array";
let description = [{
This pass maps Taskflow tasks onto a 2D CGRA grid array.
Expand All @@ -70,7 +70,7 @@ def MapTaskOnCgra : Pass<"map-task-on-cgra", "func::FuncOp"> {

Uses a default 3x3 CGRA grid.
}];
let constructor = "taskflow::createMapTaskOnCgraPass()";
let constructor = "taskflow::createAllocateCgraToTaskPass()";
}

def FuseTask : Pass<"fuse-task", "func::FuncOp"> {
Expand Down
2 changes: 1 addition & 1 deletion lib/NeuraDialect/NeuraPasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void mlir::neura::registerNeuraConversionPassPipeline() {
pm.addPass(mlir::neura::createInsertDataMovPass());
pm.addPass(mlir::createPrintOpGraphPass(os));

pm.addPass(mlir::neura::createMapToAcceleratorPass());
pm.addPass(mlir::neura::createMapOperationOnTilePass());
pm.addPass(mlir::neura::createGenerateCodePass());
});
}
2 changes: 1 addition & 1 deletion lib/NeuraDialect/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ add_mlir_library(
AssignAcceleratorPass.cpp
TransformCtrlToDataFlowPass.cpp
LeveragePredicatedValuePass.cpp
MapToAcceleratorPass.cpp
MapOperationOnTilePass.cpp
GenerateCodePass.cpp
CanonicalizeReturnPass.cpp
CanonicalizeLiveInPass.cpp
Expand Down
22 changes: 22 additions & 0 deletions lib/NeuraDialect/Transforms/CanonicalizeLiveInPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,28 @@ identifyDirectDominatingLiveIns(Region &region, DominanceInfo &dom_info,
continue;
}

// If the using block is a loop header (has a back-edge from itself or
// other blocks), we must NOT treat any live-in as a direct dominating
// live-in. In the dataflow model, loop headers operate at the inner
// loop rate, so live-in values from outer blocks must be promoted to
// block arguments to get proper rate-matched PHI_START operations
// during the ctrl-to-data-flow transformation.
// See: https://github.com/coredac/dataflow/issues/270
bool using_block_is_loop_header = false;
for (Block *pred : block.getPredecessors()) {
if (dom_info.dominates(&block, pred)) {
using_block_is_loop_header = true;
break;
}
}

if (using_block_is_loop_header) {
// Skips direct dominating live-in optimization for loop headers.
// The value must be promoted to a block argument so that the
// transform-ctrl-to-data-flow pass creates an inner-rate PHI_START.
continue;
}

// Pattern 1: Single-Source-Single-Sink with one conditional branch.
if (isSingleSourceSingleSinkPattern(defining_block, &block, dom_info,
post_dom_info)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ using namespace mlir::neura::yamlkeys;
#include "NeuraDialect/NeuraPasses.h.inc"

namespace {
struct MapToAcceleratorPass
: public PassWrapper<MapToAcceleratorPass, OperationPass<ModuleOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(MapToAcceleratorPass)
struct MapOperationOnTilePass
: public PassWrapper<MapOperationOnTilePass, OperationPass<ModuleOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(MapOperationOnTilePass)

StringRef getArgument() const override { return "map-to-accelerator"; }
StringRef getArgument() const override { return "map-operation-on-tile"; }
StringRef getDescription() const override {
return "Maps IR to the target accelerator.";
}
Expand All @@ -45,14 +45,14 @@ struct MapToAcceleratorPass
registry.insert<mlir::neura::NeuraDialect>();
}

MapToAcceleratorPass() = default;
MapToAcceleratorPass(const MapToAcceleratorOptions &options) : MapToAcceleratorPass() {
MapOperationOnTilePass() = default;
MapOperationOnTilePass(const MapOperationOnTileOptions &options) : MapOperationOnTilePass() {
this->x_tiles = options.x_tiles;
this->y_tiles = options.y_tiles;
this->valid_tiles = options.valid_tiles;
}
MapToAcceleratorPass(const MapToAcceleratorPass &pass)
: PassWrapper<MapToAcceleratorPass, OperationPass<ModuleOp>>(pass) {}
MapOperationOnTilePass(const MapOperationOnTilePass &pass)
: PassWrapper<MapOperationOnTilePass, OperationPass<ModuleOp>>(pass) {}
Option<std::string> mappingStrategy{
*this, "mapping-strategy",
llvm::cl::desc("Mapping strategy to use for mapping operations to the "
Expand Down Expand Up @@ -104,10 +104,10 @@ struct MapToAcceleratorPass
}
if (mapping_mode_str == attr::val::kSpatialOnly ||
mapping_mode_str == attr::val::kSpatialTemporal) {
llvm::errs() << "[MapToAcceleratorPass] Using Mapping Mode: "
llvm::errs() << "[MapOperationOnTilePass] Using Mapping Mode: "
<< mapping_mode_str << "\n";
} else {
llvm::errs() << "[MapToAcceleratorPass] Unsupported mapping mode: "
llvm::errs() << "[MapOperationOnTilePass] Unsupported mapping mode: "
<< mapping_mode_str << "\n";
return false;
}
Expand Down Expand Up @@ -144,29 +144,29 @@ struct MapToAcceleratorPass
mapping_strategy =
std::make_unique<HeuristicMapping>(max_loc, max_depth);
llvm::errs()
<< "[MapToAcceleratorPass] Use custom backtrack parameters: "
<< "[MapOperationOnTilePass] Use custom backtrack parameters: "
<< "max_location_to_try=" << max_loc
<< ", max_backtrack_depth=" << max_depth << "\n";
} else {
llvm::errs() << "[MapToAcceleratorPass] Illegal customized "
llvm::errs() << "[MapOperationOnTilePass] Illegal customized "
"parameters format: "
<< backtrack_str << "\n";
return false;
}
} else {
llvm::errs() << "[MapToAcceleratorPass] Illegal customized "
llvm::errs() << "[MapOperationOnTilePass] Illegal customized "
"parameters format: "
<< backtrack_str << "\n";
return false;
}
} else {
llvm::errs() << "[MapToAcceleratorPass] Unsupported backtrack config: "
llvm::errs() << "[MapOperationOnTilePass] Unsupported backtrack config: "
<< backtrack_str << "\n";
return false;
}
resolved_mapping_strategy = mapping_strategy_str.str();
} else {
llvm::errs() << "[MapToAcceleratorPass] Unsupported mapping strategy: "
llvm::errs() << "[MapOperationOnTilePass] Unsupported mapping strategy: "
<< mapping_strategy_str << "\n";
return false;
}
Expand All @@ -184,12 +184,12 @@ struct MapToAcceleratorPass
for (Operation *op : sorted_ops) {
op->setAttr(attr::kDfgId,
IntegerAttr::get(IntegerType::get(ctx, 32), next_id));
llvm::errs() << "[MapToAcceleratorPass] Assigned dfg_id=" << next_id
llvm::errs() << "[MapOperationOnTilePass] Assigned dfg_id=" << next_id
<< " to " << *op << "\n";
next_id++;
}

llvm::errs() << "[MapToAcceleratorPass] Assigned " << next_id
llvm::errs() << "[MapOperationOnTilePass] Assigned " << next_id
<< " dfg_id(s) in total\n";
}

Expand Down Expand Up @@ -231,7 +231,7 @@ struct MapToAcceleratorPass
}

if (longest) {
llvm::outs() << "[MapToAcceleratorPass] Longest recurrence cycle (length "
llvm::outs() << "[MapOperationOnTilePass] Longest recurrence cycle (length "
<< longest->length << "):\n";
for (Operation *op : longest->operations) {
op->print(llvm::outs()), llvm::outs() << "\n";
Expand All @@ -241,7 +241,7 @@ struct MapToAcceleratorPass
rec_mii = 1; // No recurrence cycles found, set MII to 1.
}

llvm::errs() << "[MapToAcceleratorPass] Calculated Recurrence MII: "
llvm::errs() << "[MapOperationOnTilePass] Calculated Recurrence MII: "
<< rec_mii << "\n";

int res_mii = calculateResMii(region, architecture);
Expand All @@ -265,7 +265,7 @@ struct MapToAcceleratorPass
if (parent_op &&
parent_op->getName().getStringRef().contains(attr::val::kOpFused)) {
// Skips operations inside a fused_op region.
llvm::outs() << "[MapToAcceleratorPass] Skipping op inside fused_op: "
llvm::outs() << "[MapOperationOnTilePass] Skipping op inside fused_op: "
<< *op << "\n";
skipped_count++;
continue;
Expand All @@ -275,19 +275,19 @@ struct MapToAcceleratorPass
topologically_sorted_ops = std::move(filtered_ops);

if (skipped_count > 0) {
llvm::errs() << "[MapToAcceleratorPass] Filtered out " << skipped_count
llvm::errs() << "[MapOperationOnTilePass] Filtered out " << skipped_count
<< " operations inside fused_op regions\n";
}

for (Operation *op : topologically_sorted_ops) {
llvm::outs() << "[MapToAcceleratorPass] Topologically sorted op: " << *op
llvm::outs() << "[MapOperationOnTilePass] Topologically sorted op: " << *op
<< "\n";
}
std::vector<std::vector<Operation *>> level_buckets =
getOpsInAlapLevels(topologically_sorted_ops, critical_ops);
for (int level = 0; level < static_cast<int>(level_buckets.size());
++level) {
llvm::outs() << "[MapToAcceleratorPass] ALAP Bucket Level " << level
llvm::outs() << "[MapOperationOnTilePass] ALAP Bucket Level " << level
<< ": " << level_buckets[level].size() << " ops\n";
for (Operation *op : level_buckets[level]) {
llvm::outs() << " " << *op << "\n";
Expand All @@ -296,12 +296,12 @@ struct MapToAcceleratorPass
std::vector<std::pair<Operation *, int>> sorted_ops_with_alap_levels =
flatten_level_buckets(level_buckets, critical_ops);
for (const auto &[op, level] : sorted_ops_with_alap_levels) {
llvm::outs() << "[MapToAcceleratorPass] ALAP sorted op: " << *op
llvm::outs() << "[MapOperationOnTilePass] ALAP sorted op: " << *op
<< " (ALAP level: " << level << ")\n";
}
// assert(false);
for (int ii = possible_min_ii; ii <= max_ii; ++ii) {
llvm::errs() << "[MapToAcceleratorPass] Start mapping with target II of "
llvm::errs() << "[MapOperationOnTilePass] Start mapping with target II of "
<< ii << "\n";
// Creates a mapping state for the current II.
MappingState mapping_state(architecture, ii, is_spatial_only);
Expand Down Expand Up @@ -349,18 +349,18 @@ struct MapToAcceleratorPass
op->setAttr(attr::kMappingInfo, mapping_info);
return true;
}
llvm::errs() << "[MapToAcceleratorPass] Mapping failed for target II of "
llvm::errs() << "[MapOperationOnTilePass] Mapping failed for target II of "
<< ii << "\n";
mapping_state.dumpOpToLocs();
}
llvm::errs()
<< "[MapToAcceleratorPass] Mapping failed for all target II values.\n";
<< "[MapOperationOnTilePass] Mapping failed for all target II values.\n";
return false;
}

void runOnOperation() override {
ModuleOp module = getOperation();
llvm::errs() << "[MapToAcceleratorPass] Starting mapping pass...\n";
llvm::errs() << "[MapOperationOnTilePass] Starting mapping pass...\n";
std::unique_ptr<Mapping> mapping_strategy;
std::string resolved_mapping_mode;
std::string resolved_mapping_strategy;
Expand Down Expand Up @@ -414,7 +414,7 @@ struct MapToAcceleratorPass
custom_arch = global_arch.cloneWithNewDimensions(
y_tiles.getValue(), x_tiles.getValue(), additional_overrides);
target_arch = custom_arch.get();
llvm::errs() << "[MapToAcceleratorPass] Overriding architecture dimensions to "
llvm::errs() << "[MapOperationOnTilePass] Overriding architecture dimensions to "
<< y_tiles.getValue() << "x" << x_tiles.getValue() << " tiles.\n";
}

Expand All @@ -432,7 +432,7 @@ struct MapToAcceleratorPass
if (!mapRegion(kernel_op, kernel_region, architecture,
mapping_strategy.get(), is_spatial_only,
resolved_mapping_mode, resolved_mapping_strategy)) {
llvm::errs() << "[MapToAcceleratorPass] Mapping failed for kernel.\n";
llvm::errs() << "[MapOperationOnTilePass] Mapping failed for kernel.\n";
signalPassFailure();
}
});
Expand All @@ -450,7 +450,7 @@ struct MapToAcceleratorPass
if (!mapRegion(func_op, func_region, architecture, mapping_strategy.get(),
is_spatial_only, resolved_mapping_mode,
resolved_mapping_strategy)) {
llvm::errs() << "[MapToAcceleratorPass] Failed to map function.\n";
llvm::errs() << "[MapOperationOnTilePass] Failed to map function.\n";
signalPassFailure();
}
});
Expand All @@ -461,9 +461,9 @@ struct MapToAcceleratorPass

namespace mlir::neura {

std::unique_ptr<Pass> createMapToAcceleratorPass(
const MapToAcceleratorOptions &options) {
return std::make_unique<MapToAcceleratorPass>(options);
std::unique_ptr<Pass> createMapOperationOnTilePass(
const MapOperationOnTileOptions &options) {
return std::make_unique<MapOperationOnTilePass>(options);
}

} // namespace mlir::neura
3 changes: 1 addition & 2 deletions lib/TaskflowDialect/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ add_mlir_dialect_library(MLIRTaskflow
MLIRInferTypeOpInterface
)

add_subdirectory(Transforms)
add_subdirectory(Transforms/Optimizations)
add_subdirectory(Transforms)
Loading
Loading