From 8fa0984555f94a97db61cc704969656406616cab Mon Sep 17 00:00:00 2001 From: ShangkunLI Date: Tue, 12 Aug 2025 15:42:36 +0800 Subject: [PATCH 1/6] prototype award function --- include/NeuraDialect/Mapping/mapping_util.h | 5 ++ lib/NeuraDialect/Mapping/mapping_util.cpp | 51 ++++++++++++++++++- .../Transforms/MapToAcceleratorPass.cpp | 5 ++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/include/NeuraDialect/Mapping/mapping_util.h b/include/NeuraDialect/Mapping/mapping_util.h index 21af298a..b0ab09e3 100644 --- a/include/NeuraDialect/Mapping/mapping_util.h +++ b/include/NeuraDialect/Mapping/mapping_util.h @@ -77,6 +77,11 @@ llvm::SmallVector getCtrlMovUsers(Operation *op); bool placeAndRoute(Operation *op, const MappingLoc &target_loc, MappingState &mapping_state); +// Estimates the utilization of a given location in the mapping state. +// The utilization considers both routing congestion and tile utilization. +int estimateUtilization(const MappingLoc &loc, + const MappingState &mapping_state); + // Calculates the award of mapping locations for a given op, the returned // locations are sorted based on the award. std::vector calculateAward(Operation *op, diff --git a/lib/NeuraDialect/Mapping/mapping_util.cpp b/lib/NeuraDialect/Mapping/mapping_util.cpp index 0a0ea45a..baa8f5ba 100644 --- a/lib/NeuraDialect/Mapping/mapping_util.cpp +++ b/lib/NeuraDialect/Mapping/mapping_util.cpp @@ -1,6 +1,7 @@ #include #include +#include "NeuraDialect/Mapping/MappingState.h" #include "NeuraDialect/Mapping/mapping_util.h" #include "NeuraDialect/NeuraOps.h" #include "mlir/Dialect/Func/IR/FuncOps.h" @@ -654,6 +655,45 @@ void mlir::neura::updateAward(std::map &locs_with_award, } } +int mlir::neura::estimateUtilization(const MappingLoc &loc, + const MappingState &mapping_state) { + Tile *tile = dyn_cast(loc.resource); + if (!tile) { + return 0; + } + + int utilization = 0; + + // 1. Estimates the tile utilization. + int tile_utilization = mapping_state.countOpsAtResource(tile); + utilization += tile_utilization; + + // 2. Estimates the routing congestion. + std::vector out_links = mapping_state.getCurrentStepLinks(loc); + int occupied_links = 0; + for (const MappingLoc &out_link_loc : out_links) { + if (!mapping_state.isAvailableAcrossTime(out_link_loc)) { + occupied_links++; + } + } + + if (!out_links.empty()) { + float link_utilization = + static_cast(occupied_links) / out_links.size(); + utilization += static_cast(link_utilization * 10); + } + + // 3. Identifies the resource hot points. + for (Tile *neighbor : tile->getDstTiles()) { + int neighbor_utilization = mapping_state.countOpsAtResource(neighbor); + if (neighbor_utilization > 2) { + utilization += 1; + } + } + + return utilization; +} + std::vector mlir::neura::calculateAward(Operation *op, std::set &critical_ops, int target_level, const Architecture &architecture, @@ -769,7 +809,16 @@ mlir::neura::calculateAward(Operation *op, std::set &critical_ops, // getPhysicalHops(producers, tile, mapping_state) < 2) { // award += 1; // } - updateAward(locs_with_award, tile_loc_candidate, award); + int additional_award = 0; + + // Awards the location that is mapped earlier in the time domain. + additional_award += (latest_end_time_step - t) * 4; + + additional_award -= + estimateUtilization(tile_loc_candidate, mapping_state); + + updateAward(locs_with_award, tile_loc_candidate, + award + additional_award); } } // The mapping location with earlier time step is granted with a higher diff --git a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp index 43762599..318b14ae 100644 --- a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp +++ b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp @@ -208,6 +208,11 @@ struct MapToAcceleratorPass llvm::outs() << "[MapToAcceleratorPass] ALAP sorted op: " << *op << " (ALAP level: " << level << ")\n"; } + + llvm::outs() << "[MapToAcceleratorPass] Critical Ops: \n"; + for (Operation *op : critical_ops) { + llvm::outs() << " " << *op << "\n"; + } // assert(false); for (int ii = possibleMinII; ii <= maxII; ++ii) { llvm::errs() From 3c9f40740f37639439e9d9e73c486de0d87f90a0 Mon Sep 17 00:00:00 2001 From: ShangkunLI Date: Wed, 13 Aug 2025 18:55:16 +0800 Subject: [PATCH 2/6] add heuristic for no-producer operations --- .../HeuristicMapping/HeuristicMapping.h | 20 +- include/NeuraDialect/Mapping/mapping_util.h | 5 - .../HeuristicMapping/HeuristicMapping.cpp | 353 +++++++++++++++--- lib/NeuraDialect/Mapping/mapping_util.cpp | 97 ++--- .../Transforms/MapToAcceleratorPass.cpp | 1 - .../simple_loop/simple_loop.mlir | 79 ++-- .../simple_loop_reduction.mlir | 52 +-- test/mapping_quality/branch_for.mlir | 96 ++--- test/mapping_quality/tiny_loop.mlir | 92 ++--- test/neura/ctrl/branch_for.mlir | 98 ++--- 10 files changed, 556 insertions(+), 337 deletions(-) diff --git a/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h b/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h index f6a6d5ff..272430a7 100644 --- a/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h +++ b/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h @@ -40,8 +40,24 @@ class HeuristicMapping : public Mapping { std::set &critical_ops, const Architecture &architecture, MappingState &mapping_state); - // Gets the sorted candidate locations for a given operation based on spatial - // execution model. + // Checks if the current operation is after a no-producer operation. + bool + isAfterNoProducerOp(const std::unordered_set &no_producer_ops, + const std::vector> + &materialized_ops_with_levels, + int current_op_index); + + // Performs backtracking to restore the previous mapping state. + bool performBacktrack(const std::unordered_set &no_producer_ops, + const std::vector> + &materialized_ops_with_levels, + std::vector &snapshots, + std::vector &candidate_history, + std::vector &operation_index_history, + int current_op_index, MappingState &mapping_state); + + // Gets the sorted candidate locations for a given operation based on + // spatial execution model. std::vector calculateSpatialAward(Operation *op, std::set &critical_ops, int target_level, const Architecture &architecture, diff --git a/include/NeuraDialect/Mapping/mapping_util.h b/include/NeuraDialect/Mapping/mapping_util.h index b0ab09e3..21af298a 100644 --- a/include/NeuraDialect/Mapping/mapping_util.h +++ b/include/NeuraDialect/Mapping/mapping_util.h @@ -77,11 +77,6 @@ llvm::SmallVector getCtrlMovUsers(Operation *op); bool placeAndRoute(Operation *op, const MappingLoc &target_loc, MappingState &mapping_state); -// Estimates the utilization of a given location in the mapping state. -// The utilization considers both routing congestion and tile utilization. -int estimateUtilization(const MappingLoc &loc, - const MappingState &mapping_state); - // Calculates the award of mapping locations for a given op, the returned // locations are sorted based on the award. std::vector calculateAward(Operation *op, diff --git a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp index 113a55f2..2712a214 100644 --- a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp +++ b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp @@ -3,6 +3,8 @@ #include "NeuraDialect/Mapping/mapping_util.h" #include "NeuraDialect/NeuraOps.h" #include "llvm/Support/raw_ostream.h" +#include +#include namespace mlir { namespace neura { @@ -15,6 +17,94 @@ bool HeuristicMapping::map( mapping_state); } +// Temporary structure to hold the result of no-producer operation mapping. +struct NoProducerOpMappingResult { + MappingStateSnapshot state; + int mapped_ops_count; + bool fully_mapped; + int current_ii; + + // Calculates the quality score of the solution. + double getQualityScore() const { + // If it is not fully mapped, return the number of mapped operations. + if (!fully_mapped) { + return mapped_ops_count; + } + + // If it is fully mapped, return a score inversely proportional to II. + return 1000.0 - this->current_ii * 100.0; + } +}; + +bool HeuristicMapping::isAfterNoProducerOp( + const std::unordered_set &no_producer_ops, + const std::vector> + &materialized_ops_with_levels, + int current_op_index) { + if (current_op_index == 0) { + return false; + } + Operation *prev_op = materialized_ops_with_levels[current_op_index - 1].first; + return no_producer_ops.count(prev_op) > 0; +} + +bool HeuristicMapping::performBacktrack( + const std::unordered_set &no_producer_ops, + const std::vector> + &materialized_ops_with_levels, + std::vector &snapshots, + std::vector &candidate_history, + std::vector &operation_index_history, int current_op_index, + MappingState &mapping_state) { + // Removes the current mapping state snapshot. + snapshots.pop_back(); + candidate_history.pop_back(); + operation_index_history.pop_back(); + + if (snapshots.empty()) { + llvm::outs() << "[HeuristicMapping] No more snapshots to restore, " + << "mapping failed.\n"; + return false; // No more snapshots to restore, mapping failed. + } + + // Because we have already thoroughly iterated candidates of no-producer + // operations. If the current operation is after a no-producer operation, we + // need backtrack 2 depths. + if (this->isAfterNoProducerOp(no_producer_ops, materialized_ops_with_levels, + current_op_index)) { + llvm::outs() << "[HeuristicMapping] Failed after no-producer op, " + << "performing deep backtrack\n"; + + // Removes the mapping state snapshot of the no-producer operation. + snapshots.pop_back(); + candidate_history.pop_back(); + operation_index_history.pop_back(); + + // Checks if there are any operations left to backtrack. + if (operation_index_history.empty()) { + llvm::outs() << "[HeuristicMapping] No more operations available " + << "after deep backtrack.\n"; + return false; + } + + // Restores the state before the previous operation of the no-producer + // operation. + snapshots.back().restore(mapping_state); + candidate_history.back()++; + } else { + // Checks if there are any operations left to backtrack. + if (operation_index_history.empty()) { + llvm::outs() << "[HeuristicMapping] No more operations available " + << "after deep backtrack.\n"; + return false; + } + // Standard backtrack to the previous operation. + snapshots.back().restore(mapping_state); + candidate_history.back()++; + } + return true; // Successfully backtracked to a previous state. +} + bool HeuristicMapping::mapWithBacktrack( std::vector> &sorted_ops_with_levels, std::set &critical_ops, const Architecture &architecture, @@ -25,20 +115,40 @@ bool HeuristicMapping::mapWithBacktrack( llvm::outs() << "Configuration: MAX Backtrack Depth = " << this->max_backtrack_depth << ", MAX Candidate Locations = " << this->max_location_to_try - << "\n"; + << ", II = " << mapping_state.getII() << "\n"; - std::vector> materialized_ops; + std::vector> materialized_ops_with_levels; for (auto [op, level] : sorted_ops_with_levels) { if (!is_non_materialized(op)) { - materialized_ops.emplace_back(op, level); + materialized_ops_with_levels.emplace_back(op, level); } } llvm::outs() << "[HeuristicMapping] Filtered " - << sorted_ops_with_levels.size() - materialized_ops.size() - << " non-materialized operations, " << materialized_ops.size() + << sorted_ops_with_levels.size() - + materialized_ops_with_levels.size() + << " non-materialized operations, " + << materialized_ops_with_levels.size() << " operations require physical mapping." << "\n"; + std::unordered_set no_producer_ops; + for (auto [op, level] : materialized_ops_with_levels) { + bool has_producer = false; + for (Value operand : op->getOperands()) { + if (!isa(operand.getDefiningOp())) { + has_producer = true; + break; + } + } + if (!has_producer) { + no_producer_ops.insert(op); + } + } + + // Configures the max number of candidate locations for each no-producer + // operation. + const int no_producer_candidates_to_try = 16; + // Stores the mapping state snapshots for backtracking. std::vector snapshots; @@ -60,10 +170,11 @@ bool HeuristicMapping::mapWithBacktrack( // Gets the current operation index to map. int current_op_index = operation_index_history.back(); - if (current_op_index >= static_cast(materialized_ops.size())) { + if (current_op_index >= + static_cast(materialized_ops_with_levels.size())) { // All operations have been mapped successfully. llvm::outs() << "[HeuristicMapping] Successfully mapped all " - << materialized_ops.size() << " operations.\n"; + << materialized_ops_with_levels.size() << " operations.\n"; return true; } @@ -78,38 +189,198 @@ bool HeuristicMapping::mapWithBacktrack( return false; // Backtrack failed, max depth exceeded. } - Operation *current_op = materialized_ops[current_op_index].first; + Operation *current_op = + materialized_ops_with_levels[current_op_index].first; std::vector candidate_locs; - candidate_locs = calculateAward(current_op, critical_ops, - materialized_ops[current_op_index].second, - architecture, mapping_state); + candidate_locs = + calculateAward(current_op, critical_ops, + materialized_ops_with_levels[current_op_index].second, + architecture, mapping_state); if (candidate_locs.empty()) { llvm::outs() << "[HeuristicMapping] No candidate locations found " << "for operation: " << *current_op << "\n"; - // No candidate locations available, backtrack to the previous operation. - snapshots.pop_back(); // Restore the previous mapping state. - candidate_history.pop_back(); - operation_index_history.pop_back(); - - if (snapshots.empty()) { - llvm::outs() << "[HeuristicMapping] No more snapshots to restore, " - << "mapping failed.\n"; - return false; // No more snapshots to restore, mapping failed. + if (!this->performBacktrack(no_producer_ops, materialized_ops_with_levels, + snapshots, candidate_history, + operation_index_history, current_op_index, + mapping_state)) { + return false; } - - snapshots.back().restore(mapping_state); - candidate_history.back()++; - llvm::outs() << "[HeuristicMapping] Backtracking to operation " - << operation_index_history.back() << "(depth = " - << (max_op_reached - operation_index_history.back()) - << ")\n"; continue; // Backtrack to the previous operation. } llvm::outs() << "[HeuristicMapping] Found " << candidate_locs.size() << " candidate locations for operation: " << *current_op << "\n"; + + // Handles no-producer operations with global exploration. + if (no_producer_ops.count(current_op) > 0 && candidate_locs.size() > 1) { + llvm::outs() + << "[HeuristicMapping] Using global exploration for no-producer op: " + << *current_op << "\n"; + + // Stores the initial state before global exploration. + MappingStateSnapshot initial_state(mapping_state); + std::vector solutions; + + // Determines the number of candidate locations to try. + int candidates_to_try = std::min(static_cast(candidate_locs.size()), + no_producer_candidates_to_try); + + // Tries full mapping with greedy strategy (All candidate locations and + // zero backtrack) for each candidate location. And use the number of + // mapped operations as the score. + for (int i = 0; i < candidates_to_try; i++) { + MappingLoc candidate_loc = candidate_locs[i]; + + llvm::outs() << "[GlobalExploration] Trying candidate position " + << (i + 1) << "/" << candidates_to_try << " at " + << candidate_loc.resource->getType() << "#" + << candidate_loc.resource->getId() + << " @t=" << candidate_loc.time_step << " for " + << *current_op << "\n"; + + // Restores the initial mapping state for each candidate. + initial_state.restore(mapping_state); + + if (!placeAndRoute(current_op, candidate_loc, mapping_state)) { + llvm::outs() << "[GlobalExploration] Failed to map at position " + << (i + 1) << "\n"; + continue; + } + + // Creates a backup to save the mapping state for this position. + MappingStateSnapshot position_state(mapping_state); + // Indicates if we successfully map all the remaining operations. + bool success = true; + // Stores the number of mapped operations if we cannot map all the + // remaining operations. + int mapped_count = 1; // Current operation is mapped. + + // Tries to map the remaining operations. Starts from the next operation + // index. + for (int next_idx = current_op_index + 1; + next_idx < static_cast(materialized_ops_with_levels.size()); + next_idx++) { + + Operation *next_op = materialized_ops_with_levels[next_idx].first; + int next_level = materialized_ops_with_levels[next_idx].second; + + // Calculates the candidate locations for the next operation. + auto next_candidates = calculateAward( + next_op, critical_ops, next_level, architecture, mapping_state); + + if (next_candidates.empty()) { + success = false; + break; + } + + // Tries to place and route the next operation at each candidate + // location. + bool mapped = false; + for (const auto &next_loc : next_candidates) { + if (placeAndRoute(next_op, next_loc, mapping_state)) { + mapped = true; + mapped_count++; + break; + } + } + + if (!mapped) { + success = false; + break; + } + } + + // If we successfully mapped all the remaining operations, we create a + // new snapshot of the mapping state. We directly use it as a solution. + if (success) { + // Creates a final state snapshot after mapping all operations. + MappingStateSnapshot final_state(mapping_state); + + NoProducerOpMappingResult solution = { + final_state, // Use the final state after mapping all ops. + mapped_count, success, mapping_state.getII()}; + + solutions.push_back(solution); + + llvm::outs() + << "[GlobalExploration] Found complete mapping solution with " + << "mapped=" << mapped_count << "/" + << materialized_ops_with_levels.size() + << ", estimated_II=" << mapping_state.getII() + << ", score=" << solution.getQualityScore() << "\n"; + } else { + // If we cannot map all operations, we create a solution with the + // current position state. + NoProducerOpMappingResult solution = {position_state, mapped_count, + success, mapping_state.getII()}; + + solutions.push_back(solution); + + llvm::outs() << "[GlobalExploration] Solution quality: " + << "mapped=" << mapped_count << "/" + << materialized_ops_with_levels.size() + << ", fully_mapped=" << (success ? "yes" : "no") + << ", estimated_II=" << mapping_state.getII() + << ", score=" << solution.getQualityScore() << "\n"; + } + } + + // If we have no solutions, we need to backtrack. + if (solutions.empty()) { + llvm::outs() << "[GlobalExploration] No feasible solutions found, " + "backtracking\n"; + + snapshots.pop_back(); + candidate_history.pop_back(); + operation_index_history.pop_back(); + + if (snapshots.empty()) { + llvm::outs() << "[HeuristicMapping] No more snapshots to restore, " + "mapping failed.\n"; + return false; + } + + snapshots.back().restore(mapping_state); + candidate_history.back()++; + continue; + } + + // Selects the best solution for mapping this no-producer op based on the + // quality score. + NoProducerOpMappingResult best_solution = + *std::max_element(solutions.begin(), solutions.end(), + [](const NoProducerOpMappingResult &a, + const NoProducerOpMappingResult &b) { + return a.getQualityScore() < b.getQualityScore(); + }); + + best_solution.state.restore(mapping_state); + + llvm::outs() << "[GlobalExploration] Selected best solution with " + << "score=" << best_solution.getQualityScore() + << ", mapped=" << best_solution.mapped_ops_count + << ", fully_mapped=" + << (best_solution.fully_mapped ? "yes" : "no") + << ", estimated_II=" << best_solution.current_ii << "\n"; + + // If we have a fully mapped solution, we can finalize the mapping. + if (best_solution.fully_mapped) { + llvm::outs() + << "[HeuristicMapping] Found complete mapping solution through " + << "global exploration, finalizing...\n"; + return true; + } + + // Otherwise continues the normal mapping process from the current best + // state + snapshots.push_back(MappingStateSnapshot(mapping_state)); + candidate_history.push_back(0); + operation_index_history.push_back(current_op_index + 1); + continue; + } + // Limits the number of locations to try. if (candidate_locs.size() > static_cast(this->max_location_to_try)) { @@ -123,30 +394,12 @@ bool HeuristicMapping::mapWithBacktrack( llvm::outs() << "[HeuristicMapping] All " << candidate_locs.size() << " locations for " << current_op_index << " tried, backtracking...\n"; - - // Removes the last mapping state snapshot and candidate history. - snapshots.pop_back(); - candidate_history.pop_back(); - operation_index_history.pop_back(); - - // If no more operation indices to backtrack, mapping failed. - if (operation_index_history.empty()) { - llvm::outs() << "[HeuristicMapping] FAILURE: No more operations " - "available for backtracking.\n"; - return false; + if (!this->performBacktrack(no_producer_ops, materialized_ops_with_levels, + snapshots, candidate_history, + operation_index_history, current_op_index, + mapping_state)) { + return false; // Backtrack failed, no more snapshots to restore. } - - // Restores the previous state - snapshots.back().restore(mapping_state); - - // Increments the candidate location index for the previous decision point - candidate_history.back()++; - - llvm::outs() << "[HeuristicMapping] Backtracking to operation " - << operation_index_history.back() << " (depth = " - << (max_op_reached - operation_index_history.back()) - << ").\n"; - continue; } diff --git a/lib/NeuraDialect/Mapping/mapping_util.cpp b/lib/NeuraDialect/Mapping/mapping_util.cpp index baa8f5ba..dcd982dc 100644 --- a/lib/NeuraDialect/Mapping/mapping_util.cpp +++ b/lib/NeuraDialect/Mapping/mapping_util.cpp @@ -6,8 +6,10 @@ #include "NeuraDialect/NeuraOps.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/IR/Operation.h" +#include "mlir/Support/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/raw_ostream.h" #include @@ -655,45 +657,6 @@ void mlir::neura::updateAward(std::map &locs_with_award, } } -int mlir::neura::estimateUtilization(const MappingLoc &loc, - const MappingState &mapping_state) { - Tile *tile = dyn_cast(loc.resource); - if (!tile) { - return 0; - } - - int utilization = 0; - - // 1. Estimates the tile utilization. - int tile_utilization = mapping_state.countOpsAtResource(tile); - utilization += tile_utilization; - - // 2. Estimates the routing congestion. - std::vector out_links = mapping_state.getCurrentStepLinks(loc); - int occupied_links = 0; - for (const MappingLoc &out_link_loc : out_links) { - if (!mapping_state.isAvailableAcrossTime(out_link_loc)) { - occupied_links++; - } - } - - if (!out_links.empty()) { - float link_utilization = - static_cast(occupied_links) / out_links.size(); - utilization += static_cast(link_utilization * 10); - } - - // 3. Identifies the resource hot points. - for (Tile *neighbor : tile->getDstTiles()) { - int neighbor_utilization = mapping_state.countOpsAtResource(neighbor); - if (neighbor_utilization > 2) { - utilization += 1; - } - } - - return utilization; -} - std::vector mlir::neura::calculateAward(Operation *op, std::set &critical_ops, int target_level, const Architecture &architecture, @@ -748,16 +711,8 @@ mlir::neura::calculateAward(Operation *op, std::set &critical_ops, << " does not support operation: " << *op << "\n"; continue; // Skip tiles that cannot support the operation. } - int earliest_start_time_step = target_level; - for (Operation *producer : producers) { - std::vector producer_locs = - mapping_state.getAllLocsOfOp(producer); - assert(!producer_locs.empty() && "No locations found for producer"); - MappingLoc producer_loc = producer_locs.back(); - earliest_start_time_step = - std::max(earliest_start_time_step, producer_loc.time_step + 1); - } + int earliest_start_time_step = target_level; int latest_end_time_step = earliest_start_time_step + mapping_state.getII(); std::vector backward_users_locs; for (Operation *user : backward_users) { @@ -770,19 +725,18 @@ mlir::neura::calculateAward(Operation *op, std::set &critical_ops, backward_user_loc.time_step + mapping_state.getII()); backward_users_locs.push_back(backward_user_loc); } + int award = 2 * mapping_state.getII(); if (critical_ops.count(op)) { award += tile->getDstTiles().size(); award += op->getOperands().size() - getPhysicalHops(producers, tile, mapping_state); } - // llvm::errs() << "[DEBUG] checking range: " - // << earliest_start_time_step << " to " - // << latest_end_time_step << " for tile: " - // << tile->getType() << "#" << tile->getId() << "\n"; + for (int t = earliest_start_time_step; t < latest_end_time_step; t += 1) { MappingLoc tile_loc_candidate = {tile, t}; - // If the tile at time `t` is available, we can consider it for mapping. + // If the tile at time `t` is available, we can consider it for + // mapping. if (mapping_state.isAvailableAcrossTime(tile_loc_candidate)) { bool meet_producer_constraint = producers.empty() || @@ -804,26 +758,19 @@ mlir::neura::calculateAward(Operation *op, std::set &critical_ops, // we can consider it for mapping and grant reward. if (meet_producer_constraint && meet_backward_user_constraint) { // Grants higher award if the location is physically closed to - // producers. award += producers.size() - getPhysicalHops(producers, + // producers. award += producers.size() - + // getPhysicalHops(producers, // tile, mapping_state); if (op->getOperands().size() > 1 && // getPhysicalHops(producers, tile, mapping_state) < 2) { // award += 1; // } - int additional_award = 0; - - // Awards the location that is mapped earlier in the time domain. - additional_award += (latest_end_time_step - t) * 4; - additional_award -= - estimateUtilization(tile_loc_candidate, mapping_state); - - updateAward(locs_with_award, tile_loc_candidate, - award + additional_award); + // The mapping location with earlier time step is granted with a + // higher award. + award -= t; + updateAward(locs_with_award, tile_loc_candidate, award); } } - // The mapping location with earlier time step is granted with a higher - // award. - award -= 1; } // assert(award >= 0 && "Award should not be negative"); } @@ -837,16 +784,17 @@ mlir::neura::calculateAward(Operation *op, std::set &critical_ops, locs_award_vec.begin(), locs_award_vec.end(), [](const std::pair &a, const std::pair &b) { return a.second > b.second; }); - // TODO: Needs to handle tie case and prioritize lower resource utilization, - // however, compiled II becomes worse after adding this tie-breaker: - // https://github.com/coredac/dataflow/issues/59. + // TODO: Needs to handle tie case and prioritize lower resource + // utilization, however, compiled II becomes worse after adding this + // tie-breaker: https://github.com/coredac/dataflow/issues/59. // std::sort(locs_award_vec.begin(), locs_award_vec.end(), // [&](const std::pair &a, const // std::pair &b) { // if (a.second != b.second) { // return a.second > b.second; // } - // // Tie-breaker: prioritizes lower resource utilization and + // // Tie-breaker: prioritizes lower resource utilization + // and // // earlier time step. // if (a.first.time_step != b.first.time_step) { // return a.first.time_step > b.first.time_step; @@ -857,6 +805,15 @@ mlir::neura::calculateAward(Operation *op, std::set &critical_ops, // return is_resource_a_lower_utilized; // }); + // llvm::outs() << "[calculateAward] Locations with awards:\n"; + // for (const auto &pair : locs_award_vec) { + // llvm::outs() << " Loc: " << pair.first.resource->getType() << "#" + // << pair.first.resource->getId() + // << " @t=" << pair.first.time_step << ", Award: " << + // pair.second + // << "\n"; + // } + // Extracts just the MappingLocs, already sorted by award. std::vector sorted_locs; sorted_locs.reserve(locs_award_vec.size()); diff --git a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp index 318b14ae..e60ea4f5 100644 --- a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp +++ b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp @@ -227,7 +227,6 @@ struct MapToAcceleratorPass << func.getName() << "' with II = " << ii << "\n"; mapping_state.dumpOpToLocs(); // logs to stderr mapping_state.encodeMappingState(); - // Sets the mapping_info attribute on the function. auto ctx = func.getContext(); DictionaryAttr mapping_info = DictionaryAttr::get( diff --git a/test/controflow_fuse/simple_loop/simple_loop.mlir b/test/controflow_fuse/simple_loop/simple_loop.mlir index 4752c2f1..aca1b3aa 100644 --- a/test/controflow_fuse/simple_loop/simple_loop.mlir +++ b/test/controflow_fuse/simple_loop/simple_loop.mlir @@ -183,46 +183,45 @@ module attributes {} { // FUSE-NEXT: "neura.return"() : () -> () // FUSE-NEXT: } -// FUSE-MAPPING: func.func @_Z11simple_loopPiS_(%arg0: memref, %arg1: memref) attributes {accelerator = "neura", llvm.linkage = #llvm.linkage, mapping_info = {compiled_ii = 5 : i32, mapping_mode = "spatial-temporal", mapping_strategy = "heuristic", rec_mii = 1 : i32, res_mii = 2 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { -// FUSE-MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = "%arg0"}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 1 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %1 = "neura.grant_once"() <{constant_value = "%arg1"}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 4 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %2 = "neura.grant_always"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 0 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %3 = "neura.grant_always"() <{constant_value = 128 : i64}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %4 = "neura.grant_once"() <{constant_value = 1 : i32}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 3 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data +// FUSE-MAPPING: func.func @_Z11simple_loopPiS_(%arg0: memref, %arg1: memref) attributes {accelerator = "neura", llvm.linkage = #llvm.linkage, mapping_info = {compiled_ii = 4 : i32, mapping_mode = "spatial-temporal", mapping_strategy = "heuristic", rec_mii = 1 : i32, res_mii = 2 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { +// FUSE-MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = "%arg0"}> {mapping_locs = [{id = 3 : i32, resource = "tile", time_step = 1 : i32, x = 3 : i32, y = 0 : i32}]} : () -> !neura.data, i1> +// FUSE-MAPPING-NEXT: %1 = "neura.grant_once"() <{constant_value = "%arg1"}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 4 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data, i1> +// FUSE-MAPPING-NEXT: %2 = "neura.grant_always"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 13 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 3 : i32}]} : () -> !neura.data +// FUSE-MAPPING-NEXT: %3 = "neura.grant_always"() <{constant_value = 128 : i64}> {mapping_locs = [{id = 3 : i32, resource = "tile", time_step = 0 : i32, x = 3 : i32, y = 0 : i32}]} : () -> !neura.data +// FUSE-MAPPING-NEXT: %4 = "neura.grant_once"() <{constant_value = 1 : i32}> {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 3 : i32, x = 0 : i32, y = 3 : i32}]} : () -> !neura.data // FUSE-MAPPING-NEXT: %5 = "neura.grant_once"() <{constant_value = 2 : i32}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 2 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %6 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 1 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %7 = "neura.grant_always"() <{constant_value = true}> {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 1 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %8 = "neura.data_mov"(%7) {mapping_locs = [{id = 10 : i32, resource = "link", time_step = 0 : i32}, {id = 14 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %9 = "neura.data_mov"(%6) {mapping_locs = []} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %10 = "neura.data_mov"(%3) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 0 : i32}, {id = 33 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %11 = "neura.data_mov"(%2) {mapping_locs = [{id = 36 : i32, resource = "link", time_step = 0 : i32}, {id = 21 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %nextindex, %valid = neura.loop_control(parent_valid = %8, start = %9, end = %10, step = %11) {iterationType = "increment", mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 2 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data, !neura.data, !neura.data, !neura.data -> !neura.data, !neura.data +// FUSE-MAPPING-NEXT: %6 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 0 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data +// FUSE-MAPPING-NEXT: %7 = "neura.grant_always"() <{constant_value = true}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data +// FUSE-MAPPING-NEXT: %8 = "neura.data_mov"(%7) {mapping_locs = [{id = 29 : i32, resource = "link", time_step = 0 : i32}, {id = 20 : i32, resource = "register", time_step = 1 : i32}, {id = 20 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %9 = "neura.data_mov"(%6) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 0 : i32}, {id = 31 : i32, resource = "link", time_step = 1 : i32}, {id = 29 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %10 = "neura.data_mov"(%3) {mapping_locs = [{id = 8 : i32, resource = "link", time_step = 0 : i32}, {id = 5 : i32, resource = "link", time_step = 1 : i32}, {id = 4 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %11 = "neura.data_mov"(%2) {mapping_locs = [{id = 42 : i32, resource = "link", time_step = 0 : i32}, {id = 29 : i32, resource = "link", time_step = 1 : i32}, {id = 21 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %nextindex, %valid = neura.loop_control(parent_valid = %8, start = %9, end = %10, step = %11) {iterationType = "increment", mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data, !neura.data, !neura.data -> !neura.data, !neura.data // FUSE-MAPPING-NEXT: %12 = "neura.data_mov"(%valid) {mapping_locs = []} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %13 = "neura.not"(%12) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %14 = "neura.data_mov"(%0) {mapping_locs = [{id = 36 : i32, resource = "link", time_step = 1 : i32}, {id = 28 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = [{id = 18 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %16 = neura.grant_predicate %14, %15 {mapping_locs = [{id = 7 : i32, resource = "tile", time_step = 3 : i32, x = 3 : i32, y = 1 : i32}]} : !neura.data, i1>, !neura.data -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %17 = "neura.data_mov"(%5) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 2 : i32}, {id = 4 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %18 = "neura.data_mov"(%valid) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 2 : i32}, {id = 15 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 0 : i32}]} : !neura.data, !neura.data -> !neura.data -// FUSE-MAPPING-NEXT: %20 = "neura.data_mov"(%4) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %21 = "neura.data_mov"(%valid) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 2 : i32}, {id = 40 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %22 = neura.grant_predicate %20, %21 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// FUSE-MAPPING-NEXT: %23 = "neura.data_mov"(%1) {mapping_locs = [{id = 36 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %24 = "neura.data_mov"(%valid) {mapping_locs = [{id = 19 : i32, resource = "link", time_step = 2 : i32}, {id = 6 : i32, resource = "link", time_step = 3 : i32}, {id = 9 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %25 = neura.grant_predicate %23, %24 {mapping_locs = [{id = 7 : i32, resource = "tile", time_step = 5 : i32, x = 3 : i32, y = 1 : i32}]} : !neura.data, i1>, !neura.data -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %26 = "neura.data_mov"(%16) {mapping_locs = [{id = 21 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %27 = "neura.data_mov"(%nextindex) {mapping_locs = []} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %28 = neura.load_indexed %26[%27 : !neura.data] !neura.data, i1> {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data -// FUSE-MAPPING-NEXT: %29 = "neura.data_mov"(%28) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %30 = "neura.data_mov"(%19) {mapping_locs = [{id = 4 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %31 = "neura.mul"(%29, %30) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 5 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %32 = "neura.data_mov"(%31) {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %33 = "neura.data_mov"(%22) {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 4 : i32}, {id = 36 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %34 = "neura.add"(%32, %33) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %35 = "neura.data_mov"(%34) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 6 : i32}, {id = 33 : i32, resource = "link", time_step = 7 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %36 = "neura.data_mov"(%25) {mapping_locs = [{id = 21 : i32, resource = "link", time_step = 5 : i32}, {id = 24 : i32, resource = "register", time_step = 6 : i32}, {id = 24 : i32, resource = "register", time_step = 7 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> +// FUSE-MAPPING-NEXT: %13 = "neura.not"(%12) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 8 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %14 = "neura.data_mov"(%0) {mapping_locs = [{id = 8 : i32, resource = "link", time_step = 1 : i32}, {id = 5 : i32, resource = "link", time_step = 2 : i32}, {id = 4 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> +// FUSE-MAPPING-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %16 = neura.grant_predicate %14, %15 {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 0 : i32}]} : !neura.data, i1>, !neura.data -> !neura.data, i1> +// FUSE-MAPPING-NEXT: %17 = "neura.data_mov"(%5) {mapping_locs = [{id = 1 : i32, resource = "link", time_step = 2 : i32}, {id = 16 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %18 = "neura.data_mov"(%valid) {mapping_locs = [{id = 13 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 4 : i32, x = 0 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data +// FUSE-MAPPING-NEXT: %20 = "neura.data_mov"(%4) {mapping_locs = [{id = 39 : i32, resource = "link", time_step = 3 : i32}, {id = 32 : i32, resource = "register", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %21 = "neura.data_mov"(%valid) {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 3 : i32}, {id = 27 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %22 = neura.grant_predicate %20, %21 {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 5 : i32, x = 0 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// FUSE-MAPPING-NEXT: %23 = "neura.data_mov"(%1) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 4 : i32}, {id = 4 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> +// FUSE-MAPPING-NEXT: %24 = "neura.data_mov"(%valid) {mapping_locs = []} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %25 = neura.grant_predicate %23, %24 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, i1>, !neura.data -> !neura.data, i1> +// FUSE-MAPPING-NEXT: %26 = "neura.data_mov"(%16) {mapping_locs = [{id = 3 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> +// FUSE-MAPPING-NEXT: %27 = "neura.data_mov"(%nextindex) {mapping_locs = [{id = 14 : i32, resource = "link", time_step = 3 : i32}, {id = 19 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %28 = neura.load_indexed %26[%27 : !neura.data] !neura.data, i1> {mapping_locs = [{id = 2 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 0 : i32}]} : !neura.data +// FUSE-MAPPING-NEXT: %29 = "neura.data_mov"(%28) {mapping_locs = [{id = 7 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %30 = "neura.data_mov"(%19) {mapping_locs = [{id = 10 : i32, resource = "link", time_step = 4 : i32}, {id = 14 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %31 = "neura.mul"(%29, %30) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %32 = "neura.data_mov"(%31) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %33 = "neura.data_mov"(%22) {mapping_locs = [{id = 24 : i32, resource = "link", time_step = 5 : i32}, {id = 28 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %34 = "neura.add"(%32, %33) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 7 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %35 = "neura.data_mov"(%34) {mapping_locs = [{id = 33 : i32, resource = "link", time_step = 7 : i32}, {id = 17 : i32, resource = "link", time_step = 8 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %36 = "neura.data_mov"(%25) {mapping_locs = []} : (!neura.data, i1>) -> !neura.data, i1> // FUSE-MAPPING-NEXT: %37 = "neura.data_mov"(%nextindex) {mapping_locs = []} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: neura.store_indexed %35 to %36[%37 : !neura.data] !neura.data, i1> {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 8 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data -// FUSE-MAPPING-NEXT: "neura.return"() {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 6 : i32, x = 0 : i32, y = 0 : i32}]} : () -> () -// FUSE-MAPPING-NEXT: } \ No newline at end of file +// FUSE-MAPPING-NEXT: neura.store_indexed %35 to %36[%37 : !neura.data] !neura.data, i1> {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 9 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data +// FUSE-MAPPING-NEXT: "neura.return"() {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 6 : i32, x = 0 : i32, y = 3 : i32}]} : () -> () diff --git a/test/controflow_fuse/simple_loop_reduction/simple_loop_reduction.mlir b/test/controflow_fuse/simple_loop_reduction/simple_loop_reduction.mlir index 8b4044f6..b6929919 100644 --- a/test/controflow_fuse/simple_loop_reduction/simple_loop_reduction.mlir +++ b/test/controflow_fuse/simple_loop_reduction/simple_loop_reduction.mlir @@ -164,31 +164,31 @@ module attributes {} { // FUSE-MAPPING: func.func @_Z10simpleloopv() -> i32 attributes {accelerator = "neura", llvm.linkage = #llvm.linkage, mapping_info = {compiled_ii = 3 : i32, mapping_mode = "spatial-temporal", mapping_strategy = "heuristic", rec_mii = 3 : i32, res_mii = 1 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { // FUSE-MAPPING-NEXT: %0 = "neura.grant_always"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 1 : i32}]} : () -> !neura.data // FUSE-MAPPING-NEXT: %1 = "neura.grant_always"() <{constant_value = 128 : i64}> {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 3 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %2 = "neura.grant_once"() <{constant_value = 0 : i32}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 1 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %3 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %4 = "neura.grant_always"() <{constant_value = true}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %5 = "neura.data_mov"(%4) {mapping_locs = [{id = 27 : i32, resource = "link", time_step = 0 : i32}, {id = 32 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %6 = "neura.data_mov"(%3) {mapping_locs = [{id = 1 : i32, resource = "link", time_step = 0 : i32}, {id = 12 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %7 = "neura.data_mov"(%1) {mapping_locs = [{id = 39 : i32, resource = "link", time_step = 0 : i32}, {id = 33 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %8 = "neura.data_mov"(%0) {mapping_locs = [{id = 12 : i32, resource = "link", time_step = 0 : i32}, {id = 34 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %nextindex, %valid = neura.loop_control(parent_valid = %5, start = %6, end = %7, step = %8) {iterationType = "increment", mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 2 : i32, x = 0 : i32, y = 2 : i32}]} : !neura.data, !neura.data, !neura.data, !neura.data -> !neura.data, !neura.data -// FUSE-MAPPING-NEXT: %9 = "neura.data_mov"(%valid) {mapping_locs = []} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %10 = "neura.not"(%9) {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 3 : i32, x = 0 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %2 = "neura.grant_once"() <{constant_value = 0 : i32}> {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 1 : i32, x = 2 : i32, y = 2 : i32}]} : () -> !neura.data +// FUSE-MAPPING-NEXT: %3 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 2 : i32}]} : () -> !neura.data +// FUSE-MAPPING-NEXT: %4 = "neura.grant_always"() <{constant_value = true}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 0 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data +// FUSE-MAPPING-NEXT: %5 = "neura.data_mov"(%4) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 0 : i32}, {id = 31 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %6 = "neura.data_mov"(%3) {mapping_locs = [{id = 24 : i32, resource = "link", time_step = 0 : i32}, {id = 36 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %7 = "neura.data_mov"(%1) {mapping_locs = [{id = 38 : i32, resource = "link", time_step = 0 : i32}, {id = 42 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %8 = "neura.data_mov"(%0) {mapping_locs = [{id = 10 : i32, resource = "link", time_step = 0 : i32}, {id = 16 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %nextindex, %valid = neura.loop_control(parent_valid = %5, start = %6, end = %7, step = %8) {iterationType = "increment", mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 2 : i32}]} : !neura.data, !neura.data, !neura.data, !neura.data -> !neura.data, !neura.data +// FUSE-MAPPING-NEXT: %9 = "neura.data_mov"(%valid) {mapping_locs = [{id = 29 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %10 = "neura.not"(%9) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data // FUSE-MAPPING-NEXT: %11 = neura.reserve : !neura.data -// FUSE-MAPPING-NEXT: %12 = "neura.data_mov"(%2) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 1 : i32}, {id = 4 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %14 = "neura.data_mov"(%13) {mapping_locs = [{id = 4 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = [{id = 24 : i32, resource = "link", time_step = 2 : i32}, {id = 29 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %16 = neura.grant_predicate %14, %15 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// FUSE-MAPPING-NEXT: %17 = "neura.data_mov"(%13) {mapping_locs = [{id = 2 : i32, resource = "link", time_step = 3 : i32}, {id = 0 : i32, resource = "register", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %18 = "neura.data_mov"(%10) {mapping_locs = [{id = 25 : i32, resource = "link", time_step = 3 : i32}, {id = 11 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 5 : i32, x = 0 : i32, y = 0 : i32}]} : !neura.data, !neura.data -> !neura.data -// FUSE-MAPPING-NEXT: %20 = "neura.data_mov"(%nextindex) {mapping_locs = [{id = 25 : i32, resource = "link", time_step = 2 : i32}, {id = 16 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %21 = "neura.cast"(%20) <{cast_type = "i64_to_i32"}> {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 4 : i32, x = 0 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %22 = "neura.data_mov"(%16) {mapping_locs = []} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %23 = "neura.data_mov"(%21) {mapping_locs = [{id = 10 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %24 = "neura.add"(%22, %23) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 5 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: neura.ctrl_mov %24 -> %11 {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 5 : i32}]} : !neura.data !neura.data -// FUSE-MAPPING-NEXT: %25 = "neura.data_mov"(%19) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 5 : i32}, {id = 4 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: "neura.return"(%25) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 7 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data) -> () +// FUSE-MAPPING-NEXT: %12 = "neura.data_mov"(%2) {mapping_locs = []} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 2 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %14 = "neura.data_mov"(%13) {mapping_locs = []} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %16 = neura.grant_predicate %14, %15 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// FUSE-MAPPING-NEXT: %17 = "neura.data_mov"(%13) {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 2 : i32}, {id = 29 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %18 = "neura.data_mov"(%10) {mapping_locs = []} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data +// FUSE-MAPPING-NEXT: %20 = "neura.data_mov"(%nextindex) {mapping_locs = [{id = 30 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %21 = "neura.cast"(%20) <{cast_type = "i64_to_i32"}> {mapping_locs = [{id = 13 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 3 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %22 = "neura.data_mov"(%16) {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %23 = "neura.data_mov"(%21) {mapping_locs = [{id = 42 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: %24 = "neura.add"(%22, %23) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: neura.ctrl_mov %24 -> %11 {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 4 : i32}]} : !neura.data !neura.data +// FUSE-MAPPING-NEXT: %25 = "neura.data_mov"(%19) {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// FUSE-MAPPING-NEXT: "neura.return"(%25) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 5 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data) -> () // FUSE-MAPPING-NEXT: } \ No newline at end of file diff --git a/test/mapping_quality/branch_for.mlir b/test/mapping_quality/branch_for.mlir index 4817c572..d445369d 100644 --- a/test/mapping_quality/branch_for.mlir +++ b/test/mapping_quality/branch_for.mlir @@ -244,63 +244,63 @@ func.func @loop_test() -> f32 { // MOV-NEXT: "neura.return"(%49) : (!neura.data) -> () // MOV-NEXT: } -// MAPPING: func.func @loop_test() -> f32 attributes {accelerator = "neura", mapping_info = {compiled_ii = 6 : i32, mapping_mode = "spatial-temporal", mapping_strategy = "heuristic", rec_mii = 4 : i32, res_mii = 2 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { -// MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = 10 : i64}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 1 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %1 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 2 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 0 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %3 = "neura.grant_once"() <{constant_value = 3.000000e+00 : f32}> {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 2 : i32, x = 0 : i32, y = 1 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %4 = "neura.grant_once"() <{constant_value = 0.000000e+00 : f32}> {mapping_locs = [{id = 15 : i32, resource = "tile", time_step = 2 : i32, x = 3 : i32, y = 3 : i32}]} : () -> !neura.data +// MAPPING: func.func @loop_test() -> f32 attributes {accelerator = "neura", mapping_info = {compiled_ii = 5 : i32, mapping_mode = "spatial-temporal", mapping_strategy = "heuristic", rec_mii = 4 : i32, res_mii = 2 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { +// MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = 10 : i64}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 1 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %1 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 3 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %3 = "neura.grant_once"() <{constant_value = 3.000000e+00 : f32}> {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 2 : i32, x = 2 : i32, y = 1 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %4 = "neura.grant_once"() <{constant_value = 0.000000e+00 : f32}> {mapping_locs = [{id = 7 : i32, resource = "tile", time_step = 2 : i32, x = 3 : i32, y = 1 : i32}]} : () -> !neura.data // MAPPING-NEXT: %5 = neura.reserve : !neura.data -// MAPPING-NEXT: %6 = "neura.data_mov"(%0) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %7 = "neura.phi"(%5, %6) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %6 = "neura.data_mov"(%0) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %7 = "neura.phi"(%5, %6) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %8 = neura.reserve : !neura.data -// MAPPING-NEXT: %9 = "neura.data_mov"(%2) {mapping_locs = [{id = 7 : i32, resource = "link", time_step = 0 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %10 = "neura.phi"(%8, %9) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 1 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %9 = "neura.data_mov"(%2) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %10 = "neura.phi"(%8, %9) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %11 = neura.reserve : !neura.data -// MAPPING-NEXT: %12 = "neura.data_mov"(%3) {mapping_locs = [{id = 11 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 3 : i32, x = 0 : i32, y = 0 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %12 = "neura.data_mov"(%3) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %14 = neura.reserve : !neura.data -// MAPPING-NEXT: %15 = "neura.data_mov"(%4) {mapping_locs = [{id = 47 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %16 = "neura.phi"(%14, %15) {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 3 : i32, x = 3 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %15 = "neura.data_mov"(%4) {mapping_locs = [{id = 21 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %16 = "neura.phi"(%14, %15) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %17 = neura.reserve : !neura.data -// MAPPING-NEXT: %18 = "neura.data_mov"(%1) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 0 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %19 = "neura.phi"(%17, %18) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 1 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %20 = "neura.data_mov"(%16) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 3 : i32}, {id = 31 : i32, resource = "link", time_step = 4 : i32}, {id = 36 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %21 = "neura.data_mov"(%13) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 3 : i32}, {id = 4 : i32, resource = "link", time_step = 4 : i32}, {id = 16 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %22 = "neura.fadd"(%20, %21) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = [{id = 4 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %24 = "neura.data_mov"(%10) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %25 = "neura.add"(%23, %24) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %18 = "neura.data_mov"(%1) {mapping_locs = [{id = 45 : i32, resource = "link", time_step = 0 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %19 = "neura.phi"(%17, %18) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 1 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %20 = "neura.data_mov"(%16) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %21 = "neura.data_mov"(%13) {mapping_locs = [{id = 14 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %22 = "neura.fadd"(%20, %21) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %24 = "neura.data_mov"(%10) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %25 = "neura.add"(%23, %24) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %26 = "neura.data_mov"(%25) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %27 = "neura.data_mov"(%7) {mapping_locs = [{id = 4 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %28 = "neura.icmp"(%26, %27) <{cmpType = "slt"}> {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %27 = "neura.data_mov"(%7) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %28 = "neura.icmp"(%26, %27) <{cmpType = "slt"}> {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %29 = "neura.data_mov"(%25) {mapping_locs = []} : (!neura.data) -> !neura.data // MAPPING-NEXT: %30 = "neura.data_mov"(%28) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %31 = neura.grant_predicate %29, %30 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %31 -> %17 {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 4 : i32}, {id = 4 : i32, resource = "register", time_step = 5 : i32}, {id = 4 : i32, resource = "register", time_step = 6 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %32 = "neura.data_mov"(%22) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %33 = "neura.data_mov"(%28) {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 3 : i32}, {id = 37 : i32, resource = "register", time_step = 4 : i32}, {id = 37 : i32, resource = "register", time_step = 5 : i32}, {id = 37 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %34 = neura.grant_predicate %32, %33 {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 7 : i32, x = 1 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %34 -> %14 {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 7 : i32}, {id = 32 : i32, resource = "link", time_step = 8 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %35 = "neura.data_mov"(%3) {mapping_locs = [{id = 12 : i32, resource = "link", time_step = 2 : i32}, {id = 24 : i32, resource = "link", time_step = 3 : i32}, {id = 29 : i32, resource = "link", time_step = 4 : i32}, {id = 15 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %36 = "neura.data_mov"(%28) {mapping_locs = [{id = 13 : i32, resource = "link", time_step = 3 : i32}, {id = 11 : i32, resource = "link", time_step = 4 : i32}, {id = 0 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %37 = neura.grant_predicate %35, %36 {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 0 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %37 -> %11 {mapping_locs = [{id = 2 : i32, resource = "link", time_step = 6 : i32}, {id = 0 : i32, resource = "register", time_step = 7 : i32}, {id = 0 : i32, resource = "register", time_step = 8 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %38 = "neura.data_mov"(%2) {mapping_locs = [{id = 6 : i32, resource = "link", time_step = 0 : i32}, {id = 9 : i32, resource = "link", time_step = 1 : i32}, {id = 21 : i32, resource = "link", time_step = 2 : i32}, {id = 24 : i32, resource = "register", time_step = 3 : i32}, {id = 24 : i32, resource = "register", time_step = 4 : i32}, {id = 24 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %39 = "neura.data_mov"(%28) {mapping_locs = [{id = 14 : i32, resource = "link", time_step = 3 : i32}, {id = 25 : i32, resource = "register", time_step = 4 : i32}, {id = 25 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %40 = neura.grant_predicate %38, %39 {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %40 -> %8 {mapping_locs = []} : !neura.data !neura.data -// MAPPING-NEXT: %41 = "neura.data_mov"(%0) {mapping_locs = [{id = 1 : i32, resource = "link", time_step = 1 : i32}, {id = 10 : i32, resource = "link", time_step = 2 : i32}, {id = 20 : i32, resource = "register", time_step = 3 : i32}, {id = 20 : i32, resource = "register", time_step = 4 : i32}, {id = 20 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %31 = neura.grant_predicate %29, %30 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %31 -> %17 {mapping_locs = []} : !neura.data !neura.data +// MAPPING-NEXT: %32 = "neura.data_mov"(%22) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 4 : i32}, {id = 34 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %33 = "neura.data_mov"(%28) {mapping_locs = [{id = 34 : i32, resource = "link", time_step = 4 : i32}, {id = 56 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %34 = neura.grant_predicate %32, %33 {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 3 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %34 -> %14 {mapping_locs = [{id = 45 : i32, resource = "link", time_step = 6 : i32}, {id = 33 : i32, resource = "link", time_step = 7 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: %35 = "neura.data_mov"(%3) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 2 : i32}, {id = 31 : i32, resource = "link", time_step = 3 : i32}, {id = 27 : i32, resource = "link", time_step = 4 : i32}, {id = 32 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %36 = "neura.data_mov"(%28) {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 4 : i32}, {id = 27 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %37 = neura.grant_predicate %35, %36 {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 6 : i32, x = 0 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %37 -> %11 {mapping_locs = [{id = 24 : i32, resource = "link", time_step = 6 : i32}, {id = 29 : i32, resource = "link", time_step = 7 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: %38 = "neura.data_mov"(%2) {mapping_locs = [{id = 29 : i32, resource = "link", time_step = 0 : i32}, {id = 20 : i32, resource = "register", time_step = 1 : i32}, {id = 20 : i32, resource = "register", time_step = 2 : i32}, {id = 20 : i32, resource = "register", time_step = 3 : i32}, {id = 20 : i32, resource = "register", time_step = 4 : i32}, {id = 20 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %39 = "neura.data_mov"(%28) {mapping_locs = [{id = 33 : i32, resource = "link", time_step = 4 : i32}, {id = 17 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %40 = neura.grant_predicate %38, %39 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %40 -> %8 {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 6 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: %41 = "neura.data_mov"(%0) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 1 : i32}, {id = 40 : i32, resource = "register", time_step = 2 : i32}, {id = 40 : i32, resource = "register", time_step = 3 : i32}, {id = 40 : i32, resource = "register", time_step = 4 : i32}, {id = 40 : i32, resource = "register", time_step = 5 : i32}, {id = 40 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data) -> !neura.data // MAPPING-NEXT: %42 = "neura.data_mov"(%28) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %43 = neura.grant_predicate %41, %42 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %43 -> %5 {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 6 : i32}, {id = 4 : i32, resource = "register", time_step = 7 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %44 = "neura.data_mov"(%28) {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %45 = "neura.not"(%44) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %46 = "neura.data_mov"(%22) {mapping_locs = [{id = 27 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %47 = "neura.data_mov"(%45) {mapping_locs = [{id = 2 : i32, resource = "link", time_step = 4 : i32}, {id = 1 : i32, resource = "link", time_step = 5 : i32}, {id = 12 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %48 = neura.grant_predicate %46, %47 {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 7 : i32, x = 0 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: %49 = "neura.data_mov"(%48) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: "neura.return"(%49) {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 8 : i32, x = 0 : i32, y = 2 : i32}]} : (!neura.data) -> () +// MAPPING-NEXT: %43 = neura.grant_predicate %41, %42 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 7 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %43 -> %5 {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 7 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: %44 = "neura.data_mov"(%28) {mapping_locs = [{id = 32 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %45 = "neura.not"(%44) {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 5 : i32, x = 3 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %46 = "neura.data_mov"(%22) {mapping_locs = [{id = 18 : i32, resource = "link", time_step = 4 : i32}, {id = 23 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %47 = "neura.data_mov"(%45) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %48 = neura.grant_predicate %46, %47 {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 6 : i32, x = 3 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: %49 = "neura.data_mov"(%48) {mapping_locs = [{id = 37 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: "neura.return"(%49) {mapping_locs = [{id = 15 : i32, resource = "tile", time_step = 7 : i32, x = 3 : i32, y = 3 : i32}]} : (!neura.data) -> () // MAPPING-NEXT: } // INST: "name": "neura.fadd", diff --git a/test/mapping_quality/tiny_loop.mlir b/test/mapping_quality/tiny_loop.mlir index 87aae182..52570673 100644 --- a/test/mapping_quality/tiny_loop.mlir +++ b/test/mapping_quality/tiny_loop.mlir @@ -73,62 +73,62 @@ module { // CHECK-NEXT: "neura.return"(%14) : (i64) -> () // CHECK-NEXT: } -// SPATIAL: func.func @simple_add_loop() -> i64 attributes {accelerator = "neura", mapping_info = {compiled_ii = 7 : i32, mapping_mode = "spatial-only", mapping_strategy = "heuristic", rec_mii = 3 : i32, res_mii = 1 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { -// SPATIAL-NEXT: %0 = "neura.grant_always"() <{constant_value = 16 : i64}> {mapping_locs = [{id = 2 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 0 : i32}]} : () -> !neura.data -// SPATIAL-NEXT: %1 = "neura.grant_always"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// SPATIAL-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 1 : i32, x = 1 : i32, y = 0 : i32}]} : () -> !neura.data -// SPATIAL-NEXT: %3 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 0 : i32, x = 3 : i32, y = 2 : i32}]} : () -> !neura.data -// SPATIAL-NEXT: %4 = "neura.grant_always"() <{constant_value = true}> {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 2 : i32}]} : () -> !neura.data -// SPATIAL-NEXT: %5 = "neura.data_mov"(%4) {mapping_locs = [{id = 33 : i32, resource = "link", time_step = 0 : i32}, {id = 24 : i32, resource = "register", time_step = 1 : i32}, {id = 24 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %6 = "neura.data_mov"(%3) {mapping_locs = [{id = 36 : i32, resource = "link", time_step = 0 : i32}, {id = 21 : i32, resource = "link", time_step = 1 : i32}, {id = 25 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %7 = "neura.data_mov"(%0) {mapping_locs = [{id = 7 : i32, resource = "link", time_step = 0 : i32}, {id = 26 : i32, resource = "register", time_step = 1 : i32}, {id = 26 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %8 = "neura.data_mov"(%1) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 0 : i32}, {id = 4 : i32, resource = "link", time_step = 1 : i32}, {id = 14 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %nextindex, %valid = neura.loop_control(parent_valid = %5, start = %6, end = %7, step = %8) {iterationType = "increment", mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data, !neura.data, !neura.data, !neura.data -> !neura.data, !neura.data -// SPATIAL-NEXT: %9 = "neura.data_mov"(%valid) {mapping_locs = [{id = 18 : i32, resource = "link", time_step = 3 : i32}, {id = 22 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %10 = "neura.not"(%9) {mapping_locs = [{id = 3 : i32, resource = "tile", time_step = 5 : i32, x = 3 : i32, y = 0 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL: func.func @simple_add_loop() -> i64 attributes {accelerator = "neura", mapping_info = {compiled_ii = 5 : i32, mapping_mode = "spatial-only", mapping_strategy = "heuristic", rec_mii = 3 : i32, res_mii = 1 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { +// SPATIAL-NEXT: %0 = "neura.grant_always"() <{constant_value = 16 : i64}> {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 1 : i32}]} : () -> !neura.data +// SPATIAL-NEXT: %1 = "neura.grant_always"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 3 : i32}]} : () -> !neura.data +// SPATIAL-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 2 : i32, resource = "tile", time_step = 1 : i32, x = 2 : i32, y = 0 : i32}]} : () -> !neura.data +// SPATIAL-NEXT: %3 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 3 : i32}]} : () -> !neura.data +// SPATIAL-NEXT: %4 = "neura.grant_always"() <{constant_value = true}> {mapping_locs = [{id = 13 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 3 : i32}]} : () -> !neura.data +// SPATIAL-NEXT: %5 = "neura.data_mov"(%4) {mapping_locs = [{id = 42 : i32, resource = "link", time_step = 0 : i32}, {id = 36 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %6 = "neura.data_mov"(%3) {mapping_locs = [{id = 45 : i32, resource = "link", time_step = 0 : i32}, {id = 31 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %7 = "neura.data_mov"(%0) {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 0 : i32}, {id = 37 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %8 = "neura.data_mov"(%1) {mapping_locs = [{id = 39 : i32, resource = "link", time_step = 0 : i32}, {id = 24 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %nextindex, %valid = neura.loop_control(parent_valid = %5, start = %6, end = %7, step = %8) {iterationType = "increment", mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 2 : i32}]} : !neura.data, !neura.data, !neura.data, !neura.data -> !neura.data, !neura.data +// SPATIAL-NEXT: %9 = "neura.data_mov"(%valid) {mapping_locs = [{id = 27 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %10 = "neura.not"(%9) {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 3 : i32, x = 0 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data // SPATIAL-NEXT: %11 = neura.reserve : !neura.data -// SPATIAL-NEXT: %12 = "neura.data_mov"(%2) {mapping_locs = [{id = 2 : i32, resource = "link", time_step = 1 : i32}, {id = 1 : i32, resource = "link", time_step = 2 : i32}, {id = 10 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// SPATIAL-NEXT: %14 = "neura.data_mov"(%13) {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 4 : i32}, {id = 36 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 3 : i32}, {id = 31 : i32, resource = "link", time_step = 4 : i32}, {id = 37 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %16 = neura.grant_predicate %14, %15 {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// SPATIAL-NEXT: %17 = "neura.data_mov"(%13) {mapping_locs = [{id = 13 : i32, resource = "link", time_step = 4 : i32}, {id = 12 : i32, resource = "link", time_step = 5 : i32}, {id = 24 : i32, resource = "link", time_step = 6 : i32}, {id = 28 : i32, resource = "link", time_step = 7 : i32}, {id = 34 : i32, resource = "link", time_step = 8 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %18 = "neura.data_mov"(%10) {mapping_locs = [{id = 9 : i32, resource = "link", time_step = 5 : i32}, {id = 23 : i32, resource = "link", time_step = 6 : i32}, {id = 37 : i32, resource = "link", time_step = 7 : i32}, {id = 46 : i32, resource = "link", time_step = 8 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 9 : i32, x = 2 : i32, y = 3 : i32}]} : !neura.data, !neura.data -> !neura.data -// SPATIAL-NEXT: %20 = "neura.data_mov"(%16) {mapping_locs = [{id = 30 : i32, resource = "link", time_step = 6 : i32}, {id = 52 : i32, resource = "register", time_step = 7 : i32}, {id = 52 : i32, resource = "register", time_step = 8 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %21 = "neura.data_mov"(%16) {mapping_locs = [{id = 27 : i32, resource = "link", time_step = 6 : i32}, {id = 26 : i32, resource = "link", time_step = 7 : i32}, {id = 38 : i32, resource = "link", time_step = 8 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: %22 = "neura.add"(%20, %21) {mapping_locs = [{id = 13 : i32, resource = "tile", time_step = 9 : i32, x = 1 : i32, y = 3 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// SPATIAL-NEXT: neura.ctrl_mov %22 -> %11 {mapping_locs = [{id = 42 : i32, resource = "link", time_step = 9 : i32}, {id = 29 : i32, resource = "link", time_step = 10 : i32}]} : !neura.data !neura.data -// SPATIAL-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = [{id = 44 : i32, resource = "link", time_step = 9 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-NEXT: "neura.return"(%23) {mapping_locs = [{id = 15 : i32, resource = "tile", time_step = 10 : i32, x = 3 : i32, y = 3 : i32}]} : (!neura.data) -> () +// SPATIAL-NEXT: %12 = "neura.data_mov"(%2) {mapping_locs = [{id = 7 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 2 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// SPATIAL-NEXT: %14 = "neura.data_mov"(%13) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %16 = neura.grant_predicate %14, %15 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// SPATIAL-NEXT: %17 = "neura.data_mov"(%13) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 2 : i32}, {id = 13 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %18 = "neura.data_mov"(%10) {mapping_locs = [{id = 25 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 4 : i32, x = 0 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data +// SPATIAL-NEXT: %20 = "neura.data_mov"(%16) {mapping_locs = [{id = 32 : i32, resource = "link", time_step = 3 : i32}, {id = 36 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %21 = "neura.data_mov"(%16) {mapping_locs = [{id = 33 : i32, resource = "link", time_step = 3 : i32}, {id = 18 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: %22 = "neura.add"(%20, %21) {mapping_locs = [{id = 7 : i32, resource = "tile", time_step = 5 : i32, x = 3 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// SPATIAL-NEXT: neura.ctrl_mov %22 -> %11 {mapping_locs = [{id = 21 : i32, resource = "link", time_step = 5 : i32}, {id = 24 : i32, resource = "register", time_step = 6 : i32}]} : !neura.data !neura.data +// SPATIAL-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = [{id = 11 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-NEXT: "neura.return"(%23) {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 5 : i32, x = 0 : i32, y = 0 : i32}]} : (!neura.data) -> () // SPATIAL-NEXT: } // SPATIAL-TEMPORAL: func.func @simple_add_loop() -> i64 attributes {accelerator = "neura", mapping_info = {compiled_ii = 3 : i32, mapping_mode = "spatial-temporal", mapping_strategy = "heuristic", rec_mii = 3 : i32, res_mii = 1 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { -// SPATIAL-TEMPORAL-NEXT: %0 = "neura.grant_always"() <{constant_value = 16 : i64}> {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 1 : i32}]} : () -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %1 = "neura.grant_always"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 3 : i32}]} : () -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 1 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %3 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %4 = "neura.grant_always"() <{constant_value = true}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %5 = "neura.data_mov"(%4) {mapping_locs = [{id = 27 : i32, resource = "link", time_step = 0 : i32}, {id = 32 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %6 = "neura.data_mov"(%3) {mapping_locs = [{id = 1 : i32, resource = "link", time_step = 0 : i32}, {id = 12 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %7 = "neura.data_mov"(%0) {mapping_locs = [{id = 12 : i32, resource = "link", time_step = 0 : i32}, {id = 33 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %8 = "neura.data_mov"(%1) {mapping_locs = [{id = 39 : i32, resource = "link", time_step = 0 : i32}, {id = 34 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %nextindex, %valid = neura.loop_control(parent_valid = %5, start = %6, end = %7, step = %8) {iterationType = "increment", mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 2 : i32, x = 0 : i32, y = 2 : i32}]} : !neura.data, !neura.data, !neura.data, !neura.data -> !neura.data, !neura.data -// SPATIAL-TEMPORAL-NEXT: %9 = "neura.data_mov"(%valid) {mapping_locs = [{id = 25 : i32, resource = "link", time_step = 2 : i32}, {id = 16 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %10 = "neura.not"(%9) {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 4 : i32, x = 0 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %0 = "neura.grant_always"() <{constant_value = 16 : i64}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %1 = "neura.grant_always"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 3 : i32}]} : () -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 1 : i32, x = 0 : i32, y = 1 : i32}]} : () -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %3 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 2 : i32}]} : () -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %4 = "neura.grant_always"() <{constant_value = true}> {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 3 : i32}]} : () -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %5 = "neura.data_mov"(%4) {mapping_locs = [{id = 38 : i32, resource = "link", time_step = 0 : i32}, {id = 42 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %6 = "neura.data_mov"(%3) {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 0 : i32}, {id = 36 : i32, resource = "register", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %7 = "neura.data_mov"(%0) {mapping_locs = []} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %8 = "neura.data_mov"(%1) {mapping_locs = [{id = 45 : i32, resource = "link", time_step = 0 : i32}, {id = 31 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %nextindex, %valid = neura.loop_control(parent_valid = %5, start = %6, end = %7, step = %8) {iterationType = "increment", mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 2 : i32}]} : !neura.data, !neura.data, !neura.data, !neura.data -> !neura.data, !neura.data +// SPATIAL-TEMPORAL-NEXT: %9 = "neura.data_mov"(%valid) {mapping_locs = [{id = 29 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %10 = "neura.not"(%9) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data // SPATIAL-TEMPORAL-NEXT: %11 = neura.reserve : !neura.data -// SPATIAL-TEMPORAL-NEXT: %12 = "neura.data_mov"(%2) {mapping_locs = [{id = 1 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %12 = "neura.data_mov"(%2) {mapping_locs = []} : (!neura.data) -> !neura.data // SPATIAL-TEMPORAL-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 2 : i32, x = 0 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data // SPATIAL-TEMPORAL-NEXT: %14 = "neura.data_mov"(%13) {mapping_locs = [{id = 12 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = []} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = [{id = 27 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data // SPATIAL-TEMPORAL-NEXT: %16 = neura.grant_predicate %14, %15 {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 3 : i32, x = 0 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %17 = "neura.data_mov"(%13) {mapping_locs = [{id = 11 : i32, resource = "link", time_step = 2 : i32}, {id = 0 : i32, resource = "register", time_step = 3 : i32}, {id = 0 : i32, resource = "register", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %18 = "neura.data_mov"(%10) {mapping_locs = [{id = 11 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 5 : i32, x = 0 : i32, y = 0 : i32}]} : !neura.data, !neura.data -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %17 = "neura.data_mov"(%13) {mapping_locs = [{id = 10 : i32, resource = "link", time_step = 2 : i32}, {id = 20 : i32, resource = "register", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %18 = "neura.data_mov"(%10) {mapping_locs = []} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data // SPATIAL-TEMPORAL-NEXT: %20 = "neura.data_mov"(%16) {mapping_locs = []} : (!neura.data) -> !neura.data // SPATIAL-TEMPORAL-NEXT: %21 = "neura.data_mov"(%16) {mapping_locs = []} : (!neura.data) -> !neura.data // SPATIAL-TEMPORAL-NEXT: %22 = "neura.add"(%20, %21) {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 4 : i32, x = 0 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // SPATIAL-TEMPORAL-NEXT: neura.ctrl_mov %22 -> %11 {mapping_locs = [{id = 25 : i32, resource = "link", time_step = 4 : i32}]} : !neura.data !neura.data -// SPATIAL-TEMPORAL-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// SPATIAL-TEMPORAL-NEXT: "neura.return"(%23) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data) -> () +// SPATIAL-TEMPORAL-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// SPATIAL-TEMPORAL-NEXT: "neura.return"(%23) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 5 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data) -> () // SPATIAL-TEMPORAL-NEXT: } \ No newline at end of file diff --git a/test/neura/ctrl/branch_for.mlir b/test/neura/ctrl/branch_for.mlir index b7196a5a..7f998542 100644 --- a/test/neura/ctrl/branch_for.mlir +++ b/test/neura/ctrl/branch_for.mlir @@ -244,63 +244,63 @@ func.func @loop_test() -> f32 { // MOV-NEXT: "neura.return"(%49) : (!neura.data) -> () // MOV-NEXT: } -// MAPPING: func.func @loop_test() -> f32 attributes {accelerator = "neura", mapping_info = {compiled_ii = 6 : i32, mapping_mode = "spatial-temporal", mapping_strategy = "heuristic", rec_mii = 4 : i32, res_mii = 2 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { -// MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = 10 : i64}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 1 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %1 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 0 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 2 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 0 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %3 = "neura.grant_once"() <{constant_value = 3.000000e+00 : f32}> {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 2 : i32, x = 0 : i32, y = 1 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %4 = "neura.grant_once"() <{constant_value = 0.000000e+00 : f32}> {mapping_locs = [{id = 15 : i32, resource = "tile", time_step = 2 : i32, x = 3 : i32, y = 3 : i32}]} : () -> !neura.data +// MAPPING: func.func @loop_test() -> f32 attributes {accelerator = "neura", mapping_info = {compiled_ii = 5 : i32, mapping_mode = "spatial-temporal", mapping_strategy = "heuristic", rec_mii = 4 : i32, res_mii = 2 : i32, x_tiles = 4 : i32, y_tiles = 4 : i32}} { +// MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = 10 : i64}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 1 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %1 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 0 : i32, x = 2 : i32, y = 3 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 2 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %3 = "neura.grant_once"() <{constant_value = 3.000000e+00 : f32}> {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 2 : i32, x = 2 : i32, y = 1 : i32}]} : () -> !neura.data +// MAPPING-NEXT: %4 = "neura.grant_once"() <{constant_value = 0.000000e+00 : f32}> {mapping_locs = [{id = 7 : i32, resource = "tile", time_step = 2 : i32, x = 3 : i32, y = 1 : i32}]} : () -> !neura.data // MAPPING-NEXT: %5 = neura.reserve : !neura.data -// MAPPING-NEXT: %6 = "neura.data_mov"(%0) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %7 = "neura.phi"(%5, %6) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %6 = "neura.data_mov"(%0) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %7 = "neura.phi"(%5, %6) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %8 = neura.reserve : !neura.data -// MAPPING-NEXT: %9 = "neura.data_mov"(%2) {mapping_locs = [{id = 7 : i32, resource = "link", time_step = 0 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %10 = "neura.phi"(%8, %9) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 1 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %9 = "neura.data_mov"(%2) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %10 = "neura.phi"(%8, %9) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %11 = neura.reserve : !neura.data -// MAPPING-NEXT: %12 = "neura.data_mov"(%3) {mapping_locs = [{id = 11 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 3 : i32, x = 0 : i32, y = 0 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %12 = "neura.data_mov"(%3) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %13 = "neura.phi"(%11, %12) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %14 = neura.reserve : !neura.data -// MAPPING-NEXT: %15 = "neura.data_mov"(%4) {mapping_locs = [{id = 47 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %16 = "neura.phi"(%14, %15) {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 3 : i32, x = 3 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %15 = "neura.data_mov"(%4) {mapping_locs = [{id = 21 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %16 = "neura.phi"(%14, %15) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %17 = neura.reserve : !neura.data -// MAPPING-NEXT: %18 = "neura.data_mov"(%1) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 0 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %19 = "neura.phi"(%17, %18) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 1 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %20 = "neura.data_mov"(%16) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 3 : i32}, {id = 31 : i32, resource = "link", time_step = 4 : i32}, {id = 36 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %21 = "neura.data_mov"(%13) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 3 : i32}, {id = 4 : i32, resource = "link", time_step = 4 : i32}, {id = 16 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %22 = "neura.fadd"(%20, %21) {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = [{id = 4 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %24 = "neura.data_mov"(%10) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %25 = "neura.add"(%23, %24) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 2 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %18 = "neura.data_mov"(%1) {mapping_locs = [{id = 45 : i32, resource = "link", time_step = 0 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %19 = "neura.phi"(%17, %18) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 1 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %20 = "neura.data_mov"(%16) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %21 = "neura.data_mov"(%13) {mapping_locs = [{id = 14 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %22 = "neura.fadd"(%20, %21) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %24 = "neura.data_mov"(%10) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %25 = "neura.add"(%23, %24) {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 3 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %26 = "neura.data_mov"(%25) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %27 = "neura.data_mov"(%7) {mapping_locs = [{id = 4 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %28 = "neura.icmp"(%26, %27) <{cmpType = "slt"}> {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 3 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data +// MAPPING-NEXT: %27 = "neura.data_mov"(%7) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %28 = "neura.icmp"(%26, %27) <{cmpType = "slt"}> {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data // MAPPING-NEXT: %29 = "neura.data_mov"(%25) {mapping_locs = []} : (!neura.data) -> !neura.data // MAPPING-NEXT: %30 = "neura.data_mov"(%28) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %31 = neura.grant_predicate %29, %30 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %31 -> %17 {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 4 : i32}, {id = 4 : i32, resource = "register", time_step = 5 : i32}, {id = 4 : i32, resource = "register", time_step = 6 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %32 = "neura.data_mov"(%22) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %33 = "neura.data_mov"(%28) {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 3 : i32}, {id = 37 : i32, resource = "register", time_step = 4 : i32}, {id = 37 : i32, resource = "register", time_step = 5 : i32}, {id = 37 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %34 = neura.grant_predicate %32, %33 {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 7 : i32, x = 1 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %34 -> %14 {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 7 : i32}, {id = 32 : i32, resource = "link", time_step = 8 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %35 = "neura.data_mov"(%3) {mapping_locs = [{id = 12 : i32, resource = "link", time_step = 2 : i32}, {id = 24 : i32, resource = "link", time_step = 3 : i32}, {id = 29 : i32, resource = "link", time_step = 4 : i32}, {id = 15 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %36 = "neura.data_mov"(%28) {mapping_locs = [{id = 13 : i32, resource = "link", time_step = 3 : i32}, {id = 11 : i32, resource = "link", time_step = 4 : i32}, {id = 0 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %37 = neura.grant_predicate %35, %36 {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 0 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %37 -> %11 {mapping_locs = [{id = 2 : i32, resource = "link", time_step = 6 : i32}, {id = 0 : i32, resource = "register", time_step = 7 : i32}, {id = 0 : i32, resource = "register", time_step = 8 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %38 = "neura.data_mov"(%2) {mapping_locs = [{id = 6 : i32, resource = "link", time_step = 0 : i32}, {id = 9 : i32, resource = "link", time_step = 1 : i32}, {id = 21 : i32, resource = "link", time_step = 2 : i32}, {id = 24 : i32, resource = "register", time_step = 3 : i32}, {id = 24 : i32, resource = "register", time_step = 4 : i32}, {id = 24 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %39 = "neura.data_mov"(%28) {mapping_locs = [{id = 14 : i32, resource = "link", time_step = 3 : i32}, {id = 25 : i32, resource = "register", time_step = 4 : i32}, {id = 25 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %40 = neura.grant_predicate %38, %39 {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %40 -> %8 {mapping_locs = []} : !neura.data !neura.data -// MAPPING-NEXT: %41 = "neura.data_mov"(%0) {mapping_locs = [{id = 1 : i32, resource = "link", time_step = 1 : i32}, {id = 10 : i32, resource = "link", time_step = 2 : i32}, {id = 20 : i32, resource = "register", time_step = 3 : i32}, {id = 20 : i32, resource = "register", time_step = 4 : i32}, {id = 20 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %31 = neura.grant_predicate %29, %30 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %31 -> %17 {mapping_locs = []} : !neura.data !neura.data +// MAPPING-NEXT: %32 = "neura.data_mov"(%22) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 4 : i32}, {id = 34 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %33 = "neura.data_mov"(%28) {mapping_locs = [{id = 34 : i32, resource = "link", time_step = 4 : i32}, {id = 56 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %34 = neura.grant_predicate %32, %33 {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 3 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %34 -> %14 {mapping_locs = [{id = 45 : i32, resource = "link", time_step = 6 : i32}, {id = 33 : i32, resource = "link", time_step = 7 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: %35 = "neura.data_mov"(%3) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 2 : i32}, {id = 31 : i32, resource = "link", time_step = 3 : i32}, {id = 27 : i32, resource = "link", time_step = 4 : i32}, {id = 32 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %36 = "neura.data_mov"(%28) {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 4 : i32}, {id = 27 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %37 = neura.grant_predicate %35, %36 {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 6 : i32, x = 0 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %37 -> %11 {mapping_locs = [{id = 24 : i32, resource = "link", time_step = 6 : i32}, {id = 29 : i32, resource = "link", time_step = 7 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: %38 = "neura.data_mov"(%2) {mapping_locs = [{id = 29 : i32, resource = "link", time_step = 0 : i32}, {id = 20 : i32, resource = "register", time_step = 1 : i32}, {id = 20 : i32, resource = "register", time_step = 2 : i32}, {id = 20 : i32, resource = "register", time_step = 3 : i32}, {id = 20 : i32, resource = "register", time_step = 4 : i32}, {id = 20 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %39 = "neura.data_mov"(%28) {mapping_locs = [{id = 33 : i32, resource = "link", time_step = 4 : i32}, {id = 17 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %40 = neura.grant_predicate %38, %39 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %40 -> %8 {mapping_locs = [{id = 16 : i32, resource = "link", time_step = 6 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: %41 = "neura.data_mov"(%0) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 1 : i32}, {id = 40 : i32, resource = "register", time_step = 2 : i32}, {id = 40 : i32, resource = "register", time_step = 3 : i32}, {id = 40 : i32, resource = "register", time_step = 4 : i32}, {id = 40 : i32, resource = "register", time_step = 5 : i32}, {id = 40 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data) -> !neura.data // MAPPING-NEXT: %42 = "neura.data_mov"(%28) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %43 = neura.grant_predicate %41, %42 {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 6 : i32, x = 1 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %43 -> %5 {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 6 : i32}, {id = 4 : i32, resource = "register", time_step = 7 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %44 = "neura.data_mov"(%28) {mapping_locs = [{id = 15 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %45 = "neura.not"(%44) {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 4 : i32, x = 1 : i32, y = 0 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %46 = "neura.data_mov"(%22) {mapping_locs = [{id = 27 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %47 = "neura.data_mov"(%45) {mapping_locs = [{id = 2 : i32, resource = "link", time_step = 4 : i32}, {id = 1 : i32, resource = "link", time_step = 5 : i32}, {id = 12 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %48 = neura.grant_predicate %46, %47 {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 7 : i32, x = 0 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: %49 = "neura.data_mov"(%48) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: "neura.return"(%49) {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 8 : i32, x = 0 : i32, y = 2 : i32}]} : (!neura.data) -> () +// MAPPING-NEXT: %43 = neura.grant_predicate %41, %42 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 7 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: neura.ctrl_mov %43 -> %5 {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 7 : i32}]} : !neura.data !neura.data +// MAPPING-NEXT: %44 = "neura.data_mov"(%28) {mapping_locs = [{id = 32 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %45 = "neura.not"(%44) {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 5 : i32, x = 3 : i32, y = 2 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %46 = "neura.data_mov"(%22) {mapping_locs = [{id = 18 : i32, resource = "link", time_step = 4 : i32}, {id = 23 : i32, resource = "link", time_step = 5 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %47 = "neura.data_mov"(%45) {mapping_locs = []} : (!neura.data) -> !neura.data +// MAPPING-NEXT: %48 = neura.grant_predicate %46, %47 {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 6 : i32, x = 3 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data +// MAPPING-NEXT: %49 = "neura.data_mov"(%48) {mapping_locs = [{id = 37 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data +// MAPPING-NEXT: "neura.return"(%49) {mapping_locs = [{id = 15 : i32, resource = "tile", time_step = 7 : i32, x = 3 : i32, y = 3 : i32}]} : (!neura.data) -> () // MAPPING-NEXT: } // INST: "name": "neura.fadd", @@ -310,4 +310,4 @@ func.func @loop_test() -> f32 { // INST-NEXT: ], // INST-NEXT: "result_types": [ // INST-NEXT: "!neura.data" -// INST-NEXT: ] \ No newline at end of file +// INST-NEXT: ] From df5c459e255b48327b582de800507186a6c1a6f7 Mon Sep 17 00:00:00 2001 From: ShangkunLI Date: Thu, 14 Aug 2025 13:46:47 +0800 Subject: [PATCH 3/6] wrap the code to make it more readable --- .../HeuristicMapping/HeuristicMapping.h | 54 ++- include/NeuraDialect/Mapping/Mapping.h | 21 +- include/NeuraDialect/Mapping/mapping_util.h | 2 +- .../HeuristicMapping/HeuristicMapping.cpp | 435 +++++++++--------- lib/NeuraDialect/Mapping/Mapping.cpp | 20 +- lib/NeuraDialect/Mapping/mapping_util.cpp | 2 +- .../Transforms/MapToAcceleratorPass.cpp | 4 +- 7 files changed, 288 insertions(+), 250 deletions(-) diff --git a/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h b/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h index 272430a7..79334763 100644 --- a/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h +++ b/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h @@ -16,9 +16,7 @@ class HeuristicMapping : public Mapping { : max_location_to_try(max_location_to_try), max_backtrack_depth(max_backtrack_depth) {} - bool map(std::vector> &sorted_ops_with_levels, - std::set &critical_ops, - const Architecture &architecture, + bool map(const Architecture &architecture, MappingState &mapping_state) override; std::string getName() const override { @@ -34,34 +32,56 @@ class HeuristicMapping : public Mapping { } } + // Temporary structure to hold the result of no-producer operation mapping. + struct NoProducerOpCandidate { + MappingStateSnapshot state; + int mapped_ops_count; + bool fully_mapped; + int current_ii; + + // Calculates the quality score of the solution. + double getQualityScore() const { + // If it is not fully mapped, return the number of mapped operations. + if (!fully_mapped) { + return mapped_ops_count; + } + + // If it is fully mapped, return a score inversely proportional to II. + return 1000.0 - this->current_ii * 100.0; + } + }; + private: - bool mapWithBacktrack( - std::vector> &sorted_ops_with_levels, - std::set &critical_ops, const Architecture &architecture, - MappingState &mapping_state); + bool mapWithBacktrack(const Architecture &architecture, + MappingState &mapping_state); // Checks if the current operation is after a no-producer operation. bool isAfterNoProducerOp(const std::unordered_set &no_producer_ops, - const std::vector> - &materialized_ops_with_levels, int current_op_index); // Performs backtracking to restore the previous mapping state. bool performBacktrack(const std::unordered_set &no_producer_ops, - const std::vector> - &materialized_ops_with_levels, std::vector &snapshots, std::vector &candidate_history, std::vector &operation_index_history, int current_op_index, MappingState &mapping_state); - // Gets the sorted candidate locations for a given operation based on - // spatial execution model. - std::vector - calculateSpatialAward(Operation *op, std::set &critical_ops, - int target_level, const Architecture &architecture, - const MappingState &mapping_state); + // Attempts to map a no-producer operation with global exploration. + bool tryToMapNoProducerOp(Operation *current_op, int current_op_index, + const std::vector &candidate_locs, + std::vector &snapshots, + std::vector &candidate_history, + std::vector &operation_index_history, + const Architecture &architecture, + MappingState &mapping_state); + + // Evaluates a candidate location for a no-producer operation. + NoProducerOpCandidate evaluateNoProducerOpCandidate( + Operation *current_op, int current_op_index, + const MappingLoc &candidate_loc, int candidate_index, + int total_candidates, const Architecture &architecture, + MappingState &mapping_state, MappingStateSnapshot &initial_state); // Configuration parameters. // Maximum number of locations to try for each op. diff --git a/include/NeuraDialect/Mapping/Mapping.h b/include/NeuraDialect/Mapping/Mapping.h index 2054965c..bc39238f 100644 --- a/include/NeuraDialect/Mapping/Mapping.h +++ b/include/NeuraDialect/Mapping/Mapping.h @@ -14,15 +14,28 @@ class Mapping { virtual ~Mapping() = default; // Applies the mapping strategy to map operations onto hardware - virtual bool - map(std::vector> &sorted_ops_with_alap_levels, - std::set &critical_ops, const Architecture &architecture, - MappingState &mapping_state) = 0; + virtual bool map(const Architecture &architecture, + MappingState &mapping_state) = 0; // Gets the name of this strategy virtual std::string getName() const = 0; + void loadDFG( + const std::vector> &sorted_ops_with_levels, + const std::set &critical_ops); + std::vector> getSortedOpsWithLevels() const { + return this->sorted_ops_with_levels; + } + std::vector> + getMaterializedOpsWithLevels() const { + return this->materialized_ops_with_levels; + } + std::set getCriticalOps() const { return this->critical_ops; } + private: + std::vector> sorted_ops_with_levels; + std::vector> materialized_ops_with_levels; + std::set critical_ops; }; } // namespace neura diff --git a/include/NeuraDialect/Mapping/mapping_util.h b/include/NeuraDialect/Mapping/mapping_util.h index 21af298a..f7c014b6 100644 --- a/include/NeuraDialect/Mapping/mapping_util.h +++ b/include/NeuraDialect/Mapping/mapping_util.h @@ -80,7 +80,7 @@ bool placeAndRoute(Operation *op, const MappingLoc &target_loc, // Calculates the award of mapping locations for a given op, the returned // locations are sorted based on the award. std::vector calculateAward(Operation *op, - std::set &critical_ops, + std::set critical_ops, int target_level, const Architecture &architecture, const MappingState &mapping_state); diff --git a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp index 2712a214..067bea1b 100644 --- a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp +++ b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp @@ -8,50 +8,207 @@ namespace mlir { namespace neura { -bool HeuristicMapping::map( - std::vector> &sorted_ops_with_levels, - std::set &critical_ops, const Architecture &architecture, - MappingState &mapping_state) { +bool HeuristicMapping::map(const Architecture &architecture, + MappingState &mapping_state) { // Starts the backtracking mapping process. - return mapWithBacktrack(sorted_ops_with_levels, critical_ops, architecture, - mapping_state); + return mapWithBacktrack(architecture, mapping_state); } -// Temporary structure to hold the result of no-producer operation mapping. -struct NoProducerOpMappingResult { - MappingStateSnapshot state; - int mapped_ops_count; - bool fully_mapped; - int current_ii; - - // Calculates the quality score of the solution. - double getQualityScore() const { - // If it is not fully mapped, return the number of mapped operations. - if (!fully_mapped) { - return mapped_ops_count; - } - - // If it is fully mapped, return a score inversely proportional to II. - return 1000.0 - this->current_ii * 100.0; - } -}; - bool HeuristicMapping::isAfterNoProducerOp( const std::unordered_set &no_producer_ops, - const std::vector> - &materialized_ops_with_levels, int current_op_index) { if (current_op_index == 0) { return false; } - Operation *prev_op = materialized_ops_with_levels[current_op_index - 1].first; + Operation *prev_op = + getMaterializedOpsWithLevels()[current_op_index - 1].first; return no_producer_ops.count(prev_op) > 0; } +HeuristicMapping::NoProducerOpCandidate +HeuristicMapping::evaluateNoProducerOpCandidate( + Operation *current_op, int current_op_index, + const MappingLoc &candidate_loc, int candidate_index, int total_candidates, + const Architecture &architecture, MappingState &mapping_state, + MappingStateSnapshot &initial_state) { + llvm::outs() << "[GlobalExploration] Trying candidate position " + << candidate_index << "/" << total_candidates << " at " + << candidate_loc.resource->getType() << "#" + << candidate_loc.resource->getId() + << " @t=" << candidate_loc.time_step << " for " << *current_op + << "\n"; + // Restores the initial mapping state for each candidate. + initial_state.restore(mapping_state); + + if (!placeAndRoute(current_op, candidate_loc, mapping_state)) { + llvm::outs() << "[GlobalExploration] Failed to map at position " + << candidate_index << "\n"; + return {MappingStateSnapshot(mapping_state), 0, false, + mapping_state.getII()}; + } + + // Creates a backup to save the mapping state for this position. + MappingStateSnapshot position_state(mapping_state); + // Indicates if we successfully map all the remaining operations. + bool success = true; + // Stores the number of mapped operations if we cannot map all the remaining + // operations. + int mapped_count = 1; // Current operation is mapped. + + // Tries to map the remaining operations. Starts from the next operation + // index. + for (int next_idx = current_op_index + 1; + next_idx < static_cast(getMaterializedOpsWithLevels().size()); + next_idx++) { + + Operation *next_op = getMaterializedOpsWithLevels()[next_idx].first; + int next_level = getMaterializedOpsWithLevels()[next_idx].second; + + // Calculates the candidate locations for the next operation. + auto next_candidates = calculateAward(next_op, getCriticalOps(), next_level, + architecture, mapping_state); + + if (next_candidates.empty()) { + success = false; + break; + } + + // Tries to place and route the next operation at each candidate location. + bool mapped = false; + for (const auto &next_loc : next_candidates) { + if (placeAndRoute(next_op, next_loc, mapping_state)) { + mapped = true; + mapped_count++; + break; + } + } + + if (!mapped) { + success = false; + break; + } + } + + // Returns the candidate result. + if (success) { + // If fully mapped, creates the final state snapshot. + MappingStateSnapshot final_state(mapping_state); + return {final_state, mapped_count, true, mapping_state.getII()}; + } else { + // If not fully mapped, returns the position state. + return {position_state, mapped_count, false, mapping_state.getII()}; + } +} + +bool HeuristicMapping::tryToMapNoProducerOp( + Operation *current_op, int current_op_index, + const std::vector &candidate_locs, + std::vector &snapshots, + std::vector &candidate_history, + std::vector &operation_index_history, const Architecture &architecture, + MappingState &mapping_state) { + llvm::outs() + << "[HeuristicMapping] Using global exploration for no-producer op: " + << *current_op << "\n"; + + // Stores the initial state before global exploration. + MappingStateSnapshot initial_state(mapping_state); + std::vector solutions; + + // Configures the max number of candidate locations for each no-producer + // operation. We set it to a reasonable number based on the architecture size. + const int no_producer_candidates_to_try = + architecture.getHeight() * architecture.getWidth(); + + // Determines the number of candidate locations to try. + int candidates_to_try = std::min(static_cast(candidate_locs.size()), + no_producer_candidates_to_try); + + // Tries full mapping with greedy strategy (All candidate locations andzero + // backtrack) for each candidate location. And use the number of + // mapped operations as the score. + for (int i = 0; i < candidates_to_try; i++) { + // Gets the mapping results for each candidate location. + NoProducerOpCandidate result = evaluateNoProducerOpCandidate( + current_op, current_op_index, candidate_locs[i], i + 1, + candidates_to_try, architecture, mapping_state, initial_state); + + if (result.mapped_ops_count > 0) { + solutions.push_back(result); + + // Outputs the solution quality information. + if (result.fully_mapped) { + llvm::outs() + << "[GlobalExploration] Found complete mapping solution with " + << "mapped=" << result.mapped_ops_count << "/" + << getMaterializedOpsWithLevels().size() + << ", estimated_II=" << result.current_ii + << ", score=" << result.getQualityScore() << "\n"; + } else { + llvm::outs() << "[GlobalExploration] Solution quality: " + << "mapped=" << result.mapped_ops_count << "/" + << getMaterializedOpsWithLevels().size() + << ", fully_mapped=" + << (result.fully_mapped ? "yes" : "no") + << ", estimated_II=" << result.current_ii + << ", score=" << result.getQualityScore() << "\n"; + } + } + } + + // If we have no solutions, we need to backtrack. + if (solutions.empty()) { + llvm::outs() << "[GlobalExploration] No feasible solutions found, " + "backtracking\n"; + + snapshots.pop_back(); + candidate_history.pop_back(); + operation_index_history.pop_back(); + + if (snapshots.empty()) { + llvm::outs() << "[HeuristicMapping] No more snapshots to restore, " + "mapping failed.\n"; + return false; + } + snapshots.back().restore(mapping_state); + candidate_history.back()++; + return false; + } + + // Selects the best solution for mapping this no-producer op based on the + // quality score. + NoProducerOpCandidate best_solution = *std::max_element( + solutions.begin(), solutions.end(), + [](const NoProducerOpCandidate &a, const NoProducerOpCandidate &b) { + return a.getQualityScore() < b.getQualityScore(); + }); + + best_solution.state.restore(mapping_state); + + llvm::outs() << "[GlobalExploration] Selected best solution with " + << "score=" << best_solution.getQualityScore() + << ", mapped=" << best_solution.mapped_ops_count + << ", fully_mapped=" + << (best_solution.fully_mapped ? "yes" : "no") + << ", estimated_II=" << best_solution.current_ii << "\n"; + + // If we have a fully mapped solution, we can finalize the mapping. + if (best_solution.fully_mapped) { + llvm::outs() + << "[HeuristicMapping] Found complete mapping solution through " + << "global exploration, finalizing...\n"; + return true; + } + + // Otherwise continues the normal mapping process from the current best state. + snapshots.push_back(MappingStateSnapshot(mapping_state)); + candidate_history.push_back(0); + operation_index_history.push_back(current_op_index + 1); + return false; +} + bool HeuristicMapping::performBacktrack( const std::unordered_set &no_producer_ops, - const std::vector> - &materialized_ops_with_levels, std::vector &snapshots, std::vector &candidate_history, std::vector &operation_index_history, int current_op_index, @@ -70,8 +227,7 @@ bool HeuristicMapping::performBacktrack( // Because we have already thoroughly iterated candidates of no-producer // operations. If the current operation is after a no-producer operation, we // need backtrack 2 depths. - if (this->isAfterNoProducerOp(no_producer_ops, materialized_ops_with_levels, - current_op_index)) { + if (this->isAfterNoProducerOp(no_producer_ops, current_op_index)) { llvm::outs() << "[HeuristicMapping] Failed after no-producer op, " << "performing deep backtrack\n"; @@ -105,34 +261,25 @@ bool HeuristicMapping::performBacktrack( return true; // Successfully backtracked to a previous state. } -bool HeuristicMapping::mapWithBacktrack( - std::vector> &sorted_ops_with_levels, - std::set &critical_ops, const Architecture &architecture, - MappingState &mapping_state) { +bool HeuristicMapping::mapWithBacktrack(const Architecture &architecture, + MappingState &mapping_state) { llvm::outs() << "---------------------------------------------------------\n"; llvm::outs() << "[HeuristicMapping] Starting mapping with " - << sorted_ops_with_levels.size() << " operations.\n"; + << getSortedOpsWithLevels().size() << " operations.\n"; llvm::outs() << "Configuration: MAX Backtrack Depth = " << this->max_backtrack_depth << ", MAX Candidate Locations = " << this->max_location_to_try << ", II = " << mapping_state.getII() << "\n"; - std::vector> materialized_ops_with_levels; - for (auto [op, level] : sorted_ops_with_levels) { - if (!is_non_materialized(op)) { - materialized_ops_with_levels.emplace_back(op, level); - } - } - llvm::outs() << "[HeuristicMapping] Filtered " - << sorted_ops_with_levels.size() - - materialized_ops_with_levels.size() + << getSortedOpsWithLevels().size() - + getMaterializedOpsWithLevels().size() << " non-materialized operations, " - << materialized_ops_with_levels.size() + << getMaterializedOpsWithLevels().size() << " operations require physical mapping." << "\n"; std::unordered_set no_producer_ops; - for (auto [op, level] : materialized_ops_with_levels) { + for (auto [op, level] : getMaterializedOpsWithLevels()) { bool has_producer = false; for (Value operand : op->getOperands()) { if (!isa(operand.getDefiningOp())) { @@ -145,10 +292,6 @@ bool HeuristicMapping::mapWithBacktrack( } } - // Configures the max number of candidate locations for each no-producer - // operation. - const int no_producer_candidates_to_try = 16; - // Stores the mapping state snapshots for backtracking. std::vector snapshots; @@ -171,10 +314,10 @@ bool HeuristicMapping::mapWithBacktrack( int current_op_index = operation_index_history.back(); if (current_op_index >= - static_cast(materialized_ops_with_levels.size())) { + static_cast(getMaterializedOpsWithLevels().size())) { // All operations have been mapped successfully. llvm::outs() << "[HeuristicMapping] Successfully mapped all " - << materialized_ops_with_levels.size() << " operations.\n"; + << getMaterializedOpsWithLevels().size() << " operations.\n"; return true; } @@ -190,18 +333,17 @@ bool HeuristicMapping::mapWithBacktrack( } Operation *current_op = - materialized_ops_with_levels[current_op_index].first; + getMaterializedOpsWithLevels()[current_op_index].first; std::vector candidate_locs; candidate_locs = - calculateAward(current_op, critical_ops, - materialized_ops_with_levels[current_op_index].second, + calculateAward(current_op, getCriticalOps(), + getMaterializedOpsWithLevels()[current_op_index].second, architecture, mapping_state); if (candidate_locs.empty()) { llvm::outs() << "[HeuristicMapping] No candidate locations found " << "for operation: " << *current_op << "\n"; - if (!this->performBacktrack(no_producer_ops, materialized_ops_with_levels, - snapshots, candidate_history, + if (!this->performBacktrack(no_producer_ops, snapshots, candidate_history, operation_index_history, current_op_index, mapping_state)) { return false; @@ -215,170 +357,16 @@ bool HeuristicMapping::mapWithBacktrack( // Handles no-producer operations with global exploration. if (no_producer_ops.count(current_op) > 0 && candidate_locs.size() > 1) { - llvm::outs() - << "[HeuristicMapping] Using global exploration for no-producer op: " - << *current_op << "\n"; - - // Stores the initial state before global exploration. - MappingStateSnapshot initial_state(mapping_state); - std::vector solutions; - - // Determines the number of candidate locations to try. - int candidates_to_try = std::min(static_cast(candidate_locs.size()), - no_producer_candidates_to_try); - - // Tries full mapping with greedy strategy (All candidate locations and - // zero backtrack) for each candidate location. And use the number of - // mapped operations as the score. - for (int i = 0; i < candidates_to_try; i++) { - MappingLoc candidate_loc = candidate_locs[i]; - - llvm::outs() << "[GlobalExploration] Trying candidate position " - << (i + 1) << "/" << candidates_to_try << " at " - << candidate_loc.resource->getType() << "#" - << candidate_loc.resource->getId() - << " @t=" << candidate_loc.time_step << " for " - << *current_op << "\n"; - - // Restores the initial mapping state for each candidate. - initial_state.restore(mapping_state); - - if (!placeAndRoute(current_op, candidate_loc, mapping_state)) { - llvm::outs() << "[GlobalExploration] Failed to map at position " - << (i + 1) << "\n"; - continue; - } - - // Creates a backup to save the mapping state for this position. - MappingStateSnapshot position_state(mapping_state); - // Indicates if we successfully map all the remaining operations. - bool success = true; - // Stores the number of mapped operations if we cannot map all the - // remaining operations. - int mapped_count = 1; // Current operation is mapped. - - // Tries to map the remaining operations. Starts from the next operation - // index. - for (int next_idx = current_op_index + 1; - next_idx < static_cast(materialized_ops_with_levels.size()); - next_idx++) { - - Operation *next_op = materialized_ops_with_levels[next_idx].first; - int next_level = materialized_ops_with_levels[next_idx].second; - - // Calculates the candidate locations for the next operation. - auto next_candidates = calculateAward( - next_op, critical_ops, next_level, architecture, mapping_state); - - if (next_candidates.empty()) { - success = false; - break; - } - - // Tries to place and route the next operation at each candidate - // location. - bool mapped = false; - for (const auto &next_loc : next_candidates) { - if (placeAndRoute(next_op, next_loc, mapping_state)) { - mapped = true; - mapped_count++; - break; - } - } - - if (!mapped) { - success = false; - break; - } - } - - // If we successfully mapped all the remaining operations, we create a - // new snapshot of the mapping state. We directly use it as a solution. - if (success) { - // Creates a final state snapshot after mapping all operations. - MappingStateSnapshot final_state(mapping_state); - - NoProducerOpMappingResult solution = { - final_state, // Use the final state after mapping all ops. - mapped_count, success, mapping_state.getII()}; - - solutions.push_back(solution); - - llvm::outs() - << "[GlobalExploration] Found complete mapping solution with " - << "mapped=" << mapped_count << "/" - << materialized_ops_with_levels.size() - << ", estimated_II=" << mapping_state.getII() - << ", score=" << solution.getQualityScore() << "\n"; - } else { - // If we cannot map all operations, we create a solution with the - // current position state. - NoProducerOpMappingResult solution = {position_state, mapped_count, - success, mapping_state.getII()}; - - solutions.push_back(solution); - - llvm::outs() << "[GlobalExploration] Solution quality: " - << "mapped=" << mapped_count << "/" - << materialized_ops_with_levels.size() - << ", fully_mapped=" << (success ? "yes" : "no") - << ", estimated_II=" << mapping_state.getII() - << ", score=" << solution.getQualityScore() << "\n"; - } - } - - // If we have no solutions, we need to backtrack. - if (solutions.empty()) { - llvm::outs() << "[GlobalExploration] No feasible solutions found, " - "backtracking\n"; - - snapshots.pop_back(); - candidate_history.pop_back(); - operation_index_history.pop_back(); - - if (snapshots.empty()) { - llvm::outs() << "[HeuristicMapping] No more snapshots to restore, " - "mapping failed.\n"; - return false; - } - - snapshots.back().restore(mapping_state); - candidate_history.back()++; - continue; + bool fully_mapped = tryToMapNoProducerOp( + current_op, current_op_index, candidate_locs, snapshots, + candidate_history, operation_index_history, architecture, + mapping_state); + if (fully_mapped) { + llvm::outs() << "[HeuristicMapping] Found complete mapping solution " + "for no-producer op, finalizing...\n"; + return true; // Mapping completed successfully. } - - // Selects the best solution for mapping this no-producer op based on the - // quality score. - NoProducerOpMappingResult best_solution = - *std::max_element(solutions.begin(), solutions.end(), - [](const NoProducerOpMappingResult &a, - const NoProducerOpMappingResult &b) { - return a.getQualityScore() < b.getQualityScore(); - }); - - best_solution.state.restore(mapping_state); - - llvm::outs() << "[GlobalExploration] Selected best solution with " - << "score=" << best_solution.getQualityScore() - << ", mapped=" << best_solution.mapped_ops_count - << ", fully_mapped=" - << (best_solution.fully_mapped ? "yes" : "no") - << ", estimated_II=" << best_solution.current_ii << "\n"; - - // If we have a fully mapped solution, we can finalize the mapping. - if (best_solution.fully_mapped) { - llvm::outs() - << "[HeuristicMapping] Found complete mapping solution through " - << "global exploration, finalizing...\n"; - return true; - } - - // Otherwise continues the normal mapping process from the current best - // state - snapshots.push_back(MappingStateSnapshot(mapping_state)); - candidate_history.push_back(0); - operation_index_history.push_back(current_op_index + 1); - continue; + continue; // Continue to the next operation. } // Limits the number of locations to try. @@ -394,8 +382,7 @@ bool HeuristicMapping::mapWithBacktrack( llvm::outs() << "[HeuristicMapping] All " << candidate_locs.size() << " locations for " << current_op_index << " tried, backtracking...\n"; - if (!this->performBacktrack(no_producer_ops, materialized_ops_with_levels, - snapshots, candidate_history, + if (!this->performBacktrack(no_producer_ops, snapshots, candidate_history, operation_index_history, current_op_index, mapping_state)) { return false; // Backtrack failed, no more snapshots to restore. diff --git a/lib/NeuraDialect/Mapping/Mapping.cpp b/lib/NeuraDialect/Mapping/Mapping.cpp index d9328e9d..a550f2c3 100644 --- a/lib/NeuraDialect/Mapping/Mapping.cpp +++ b/lib/NeuraDialect/Mapping/Mapping.cpp @@ -1,5 +1,23 @@ #include "NeuraDialect/Mapping/Mapping.h" +#include "NeuraDialect/Mapping/mapping_util.h" #include // TODO: Move common functions from mapping_util.cpp to Mapping.cpp -// Issue Link: https://github.com/coredac/dataflow/issues/107 \ No newline at end of file +// Issue Link: https://github.com/coredac/dataflow/issues/107 + +namespace mlir { +namespace neura { +void Mapping::loadDFG( + const std::vector> &sorted_ops_with_levels, + const std::set &critical_ops) { + this->sorted_ops_with_levels = sorted_ops_with_levels; + this->critical_ops = critical_ops; + for (auto [op, level] : sorted_ops_with_levels) { + if (!is_non_materialized(op)) { + this->materialized_ops_with_levels.emplace_back(op, level); + } + } +} +} // namespace neura + +} // namespace mlir \ No newline at end of file diff --git a/lib/NeuraDialect/Mapping/mapping_util.cpp b/lib/NeuraDialect/Mapping/mapping_util.cpp index dcd982dc..6460af00 100644 --- a/lib/NeuraDialect/Mapping/mapping_util.cpp +++ b/lib/NeuraDialect/Mapping/mapping_util.cpp @@ -658,7 +658,7 @@ void mlir::neura::updateAward(std::map &locs_with_award, } std::vector -mlir::neura::calculateAward(Operation *op, std::set &critical_ops, +mlir::neura::calculateAward(Operation *op, std::set critical_ops, int target_level, const Architecture &architecture, const MappingState &mapping_state) { // Early exit if the operation is not supported by all the tiles. diff --git a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp index e60ea4f5..fe707913 100644 --- a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp +++ b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp @@ -213,6 +213,7 @@ struct MapToAcceleratorPass for (Operation *op : critical_ops) { llvm::outs() << " " << *op << "\n"; } + mapping_strategy->loadDFG(sorted_ops_with_alap_levels, critical_ops); // assert(false); for (int ii = possibleMinII; ii <= maxII; ++ii) { llvm::errs() @@ -220,8 +221,7 @@ struct MapToAcceleratorPass << "\n"; // Creates a mapping state for the current II. MappingState mapping_state(architecture, ii, is_spatial_only); - if (mapping_strategy->map(sorted_ops_with_alap_levels, critical_ops, - architecture, mapping_state)) { + if (mapping_strategy->map(architecture, mapping_state)) { // success llvm::errs() << "[MapToAcceleratorPass] Successfully mapped function " << func.getName() << "' with II = " << ii << "\n"; From 9950dc723fdec12f7f1d14bdad50d720bf9e7036 Mon Sep 17 00:00:00 2001 From: ShangkunLI Date: Thu, 14 Aug 2025 16:22:55 +0800 Subject: [PATCH 4/6] [fix] fix some typo --- include/NeuraDialect/Mapping/Mapping.h | 2 +- include/NeuraDialect/Mapping/mapping_util.h | 9 ++++----- .../Mapping/HeuristicMapping/HeuristicMapping.cpp | 3 +-- lib/NeuraDialect/Mapping/Mapping.cpp | 2 +- lib/NeuraDialect/Mapping/mapping_util.cpp | 7 +++---- lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/include/NeuraDialect/Mapping/Mapping.h b/include/NeuraDialect/Mapping/Mapping.h index bc39238f..3abd42de 100644 --- a/include/NeuraDialect/Mapping/Mapping.h +++ b/include/NeuraDialect/Mapping/Mapping.h @@ -20,7 +20,7 @@ class Mapping { // Gets the name of this strategy virtual std::string getName() const = 0; - void loadDFG( + void loadDfg( const std::vector> &sorted_ops_with_levels, const std::set &critical_ops); std::vector> getSortedOpsWithLevels() const { diff --git a/include/NeuraDialect/Mapping/mapping_util.h b/include/NeuraDialect/Mapping/mapping_util.h index f7c014b6..eb4a5261 100644 --- a/include/NeuraDialect/Mapping/mapping_util.h +++ b/include/NeuraDialect/Mapping/mapping_util.h @@ -79,11 +79,10 @@ bool placeAndRoute(Operation *op, const MappingLoc &target_loc, // Calculates the award of mapping locations for a given op, the returned // locations are sorted based on the award. -std::vector calculateAward(Operation *op, - std::set critical_ops, - int target_level, - const Architecture &architecture, - const MappingState &mapping_state); +std::vector +calculateAward(Operation *op, const std::set &critical_ops, + int target_level, const Architecture &architecture, + const MappingState &mapping_state); void updateAward(std::map &locs_with_award, MappingLoc loc, int award); diff --git a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp index 067bea1b..0cc419a6 100644 --- a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp +++ b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp @@ -4,7 +4,6 @@ #include "NeuraDialect/NeuraOps.h" #include "llvm/Support/raw_ostream.h" #include -#include namespace mlir { namespace neura { @@ -124,7 +123,7 @@ bool HeuristicMapping::tryToMapNoProducerOp( int candidates_to_try = std::min(static_cast(candidate_locs.size()), no_producer_candidates_to_try); - // Tries full mapping with greedy strategy (All candidate locations andzero + // Tries full mapping with greedy strategy (all candidate locations and zero // backtrack) for each candidate location. And use the number of // mapped operations as the score. for (int i = 0; i < candidates_to_try; i++) { diff --git a/lib/NeuraDialect/Mapping/Mapping.cpp b/lib/NeuraDialect/Mapping/Mapping.cpp index a550f2c3..33b6923a 100644 --- a/lib/NeuraDialect/Mapping/Mapping.cpp +++ b/lib/NeuraDialect/Mapping/Mapping.cpp @@ -7,7 +7,7 @@ namespace mlir { namespace neura { -void Mapping::loadDFG( +void Mapping::loadDfg( const std::vector> &sorted_ops_with_levels, const std::set &critical_ops) { this->sorted_ops_with_levels = sorted_ops_with_levels; diff --git a/lib/NeuraDialect/Mapping/mapping_util.cpp b/lib/NeuraDialect/Mapping/mapping_util.cpp index 6460af00..8db25c09 100644 --- a/lib/NeuraDialect/Mapping/mapping_util.cpp +++ b/lib/NeuraDialect/Mapping/mapping_util.cpp @@ -657,10 +657,9 @@ void mlir::neura::updateAward(std::map &locs_with_award, } } -std::vector -mlir::neura::calculateAward(Operation *op, std::set critical_ops, - int target_level, const Architecture &architecture, - const MappingState &mapping_state) { +std::vector mlir::neura::calculateAward( + Operation *op, const std::set &critical_ops, int target_level, + const Architecture &architecture, const MappingState &mapping_state) { // Early exit if the operation is not supported by all the tiles. bool op_can_be_supported = false; for (Tile *tile : architecture.getAllTiles()) { diff --git a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp index fe707913..8c677c4d 100644 --- a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp +++ b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp @@ -213,7 +213,7 @@ struct MapToAcceleratorPass for (Operation *op : critical_ops) { llvm::outs() << " " << *op << "\n"; } - mapping_strategy->loadDFG(sorted_ops_with_alap_levels, critical_ops); + mapping_strategy->loadDfg(sorted_ops_with_alap_levels, critical_ops); // assert(false); for (int ii = possibleMinII; ii <= maxII; ++ii) { llvm::errs() From 5e1c50b7af92f54971b25c23e3f92e8ca9babbf2 Mon Sep 17 00:00:00 2001 From: ShangkunLI Date: Fri, 15 Aug 2025 01:22:55 +0800 Subject: [PATCH 5/6] add descriptions on how new backtrack works --- .../HeuristicMapping/HeuristicMapping.h | 15 +-- .../HeuristicMapping/HeuristicMapping.cpp | 106 ++++++++++++------ 2 files changed, 81 insertions(+), 40 deletions(-) diff --git a/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h b/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h index 79334763..489e4af4 100644 --- a/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h +++ b/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h @@ -68,13 +68,14 @@ class HeuristicMapping : public Mapping { int current_op_index, MappingState &mapping_state); // Attempts to map a no-producer operation with global exploration. - bool tryToMapNoProducerOp(Operation *current_op, int current_op_index, - const std::vector &candidate_locs, - std::vector &snapshots, - std::vector &candidate_history, - std::vector &operation_index_history, - const Architecture &architecture, - MappingState &mapping_state); + NoProducerOpCandidate + tryToMapNoProducerOp(Operation *current_op, int current_op_index, + const std::vector &candidate_locs, + std::vector &snapshots, + std::vector &candidate_history, + std::vector &operation_index_history, + const Architecture &architecture, + MappingState &mapping_state); // Evaluates a candidate location for a no-producer operation. NoProducerOpCandidate evaluateNoProducerOpCandidate( diff --git a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp index 0cc419a6..bdaecf12 100644 --- a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp +++ b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp @@ -3,6 +3,7 @@ #include "NeuraDialect/Mapping/mapping_util.h" #include "NeuraDialect/NeuraOps.h" #include "llvm/Support/raw_ostream.h" +#include #include namespace mlir { @@ -99,7 +100,7 @@ HeuristicMapping::evaluateNoProducerOpCandidate( } } -bool HeuristicMapping::tryToMapNoProducerOp( +HeuristicMapping::NoProducerOpCandidate HeuristicMapping::tryToMapNoProducerOp( Operation *current_op, int current_op_index, const std::vector &candidate_locs, std::vector &snapshots, @@ -160,18 +161,22 @@ bool HeuristicMapping::tryToMapNoProducerOp( llvm::outs() << "[GlobalExploration] No feasible solutions found, " "backtracking\n"; - snapshots.pop_back(); - candidate_history.pop_back(); - operation_index_history.pop_back(); - - if (snapshots.empty()) { - llvm::outs() << "[HeuristicMapping] No more snapshots to restore, " - "mapping failed.\n"; - return false; - } - snapshots.back().restore(mapping_state); - candidate_history.back()++; - return false; + // snapshots.pop_back(); + // candidate_history.pop_back(); + // operation_index_history.pop_back(); + + // if (snapshots.empty()) { + // llvm::outs() << "[HeuristicMapping] No more snapshots to restore, " + // "mapping failed.\n"; + // return false; + // } + // snapshots.back().restore(mapping_state); + // candidate_history.back()++; + + // performBacktrack(no_producer_ops, snapshots, candidate_history, + // operation_index_history, current_op_index, + // mapping_state); + return {mapping_state, 0, false, mapping_state.getII()}; } // Selects the best solution for mapping this no-producer op based on the @@ -196,14 +201,14 @@ bool HeuristicMapping::tryToMapNoProducerOp( llvm::outs() << "[HeuristicMapping] Found complete mapping solution through " << "global exploration, finalizing...\n"; - return true; + return best_solution; } // Otherwise continues the normal mapping process from the current best state. snapshots.push_back(MappingStateSnapshot(mapping_state)); candidate_history.push_back(0); operation_index_history.push_back(current_op_index + 1); - return false; + return best_solution; } bool HeuristicMapping::performBacktrack( @@ -225,25 +230,51 @@ bool HeuristicMapping::performBacktrack( // Because we have already thoroughly iterated candidates of no-producer // operations. If the current operation is after a no-producer operation, we - // need backtrack 2 depths. + // need backtrack until we find an operation with a producer. + // This is to ensure we do not get stuck in a loop of no-producer operations + // without making progress. + + // Example: + // + + // | | | | | + + // | loc_0 | | loc_3 | ... + // | loc_1 | | loc_4 | ... + // | loc_2 | | loc_5 | ... + + // 1. If we fail to map op4, we can backtrack to op3 using this + // performBacktrack function. + // 2. If we fail to map op3, we need to backtrack to op0 to avoid getting + // stuck in a loop of no-producer operations + // (no_producer_op2->op3->no_producer_op2->...>). + // 3. If we fail to map no_producer_op2, we will also backtrack to op0 to + // avoid getting stuck in similar loop. if (this->isAfterNoProducerOp(no_producer_ops, current_op_index)) { llvm::outs() << "[HeuristicMapping] Failed after no-producer op, " << "performing deep backtrack\n"; - // Removes the mapping state snapshot of the no-producer operation. - snapshots.pop_back(); - candidate_history.pop_back(); - operation_index_history.pop_back(); + bool is_op_with_producer = false; + while (!is_op_with_producer) { + snapshots.pop_back(); + candidate_history.pop_back(); + operation_index_history.pop_back(); - // Checks if there are any operations left to backtrack. - if (operation_index_history.empty()) { - llvm::outs() << "[HeuristicMapping] No more operations available " - << "after deep backtrack.\n"; - return false; + if (snapshots.empty() || operation_index_history.empty()) { + llvm::outs() << "[HeuristicMapping] No more operations available.\n"; + return false; + } + int op_index = operation_index_history.back(); + + if (op_index == 0) { + return true; + } else { + Operation *op = getMaterializedOpsWithLevels()[op_index].first; + is_op_with_producer = !(no_producer_ops.count(op) > 0); + } } - // Restores the state before the previous operation of the no-producer - // operation. + // Restores the state to the last operation with a producer. snapshots.back().restore(mapping_state); candidate_history.back()++; } else { @@ -356,16 +387,25 @@ bool HeuristicMapping::mapWithBacktrack(const Architecture &architecture, // Handles no-producer operations with global exploration. if (no_producer_ops.count(current_op) > 0 && candidate_locs.size() > 1) { - bool fully_mapped = tryToMapNoProducerOp( + NoProducerOpCandidate no_producer_candidate = tryToMapNoProducerOp( current_op, current_op_index, candidate_locs, snapshots, candidate_history, operation_index_history, architecture, mapping_state); - if (fully_mapped) { - llvm::outs() << "[HeuristicMapping] Found complete mapping solution " - "for no-producer op, finalizing...\n"; - return true; // Mapping completed successfully. + if (no_producer_candidate.mapped_ops_count > 0) { + if (no_producer_candidate.fully_mapped) { + llvm::outs() << "[HeuristicMapping] Found complete mapping solution " + "for no-producer op, finalizing...\n"; + return true; // Mapping completed successfully. + } + continue; + } else { + if (!this->performBacktrack(no_producer_ops, snapshots, + candidate_history, operation_index_history, + current_op_index, mapping_state)) { + return false; // Backtrack failed, no more snapshots to restore. + } + continue; } - continue; // Continue to the next operation. } // Limits the number of locations to try. From 3299ca6824eea4c34ad60e4ac6c4053ddc34b082 Mon Sep 17 00:00:00 2001 From: ShangkunLI Date: Fri, 15 Aug 2025 01:27:08 +0800 Subject: [PATCH 6/6] [clean] remove redundant comments --- .../HeuristicMapping/HeuristicMapping.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp index bdaecf12..f5e35b73 100644 --- a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp +++ b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp @@ -160,22 +160,6 @@ HeuristicMapping::NoProducerOpCandidate HeuristicMapping::tryToMapNoProducerOp( if (solutions.empty()) { llvm::outs() << "[GlobalExploration] No feasible solutions found, " "backtracking\n"; - - // snapshots.pop_back(); - // candidate_history.pop_back(); - // operation_index_history.pop_back(); - - // if (snapshots.empty()) { - // llvm::outs() << "[HeuristicMapping] No more snapshots to restore, " - // "mapping failed.\n"; - // return false; - // } - // snapshots.back().restore(mapping_state); - // candidate_history.back()++; - - // performBacktrack(no_producer_ops, snapshots, candidate_history, - // operation_index_history, current_op_index, - // mapping_state); return {mapping_state, 0, false, mapping_state.getII()}; }