diff --git a/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h b/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h index f58758de..9c233828 100644 --- a/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h +++ b/include/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h @@ -1,18 +1,20 @@ -#ifndef NEURA_BACKTRACK_MAPPING_H -#define NEURA_BACKTRACK_MAPPING_H +#ifndef NEURA_HEURISTIC_MAPPING_H +#define NEURA_HEURISTIC_MAPPING_H +#include "NeuraDialect/Mapping/Mapping.h" #include "NeuraDialect/Mapping/MappingState.h" -#include "NeuraDialect/Mapping/MappingStrategy.h" +#include "NeuraDialect/Mapping/mapping_util.h" #include #include #include namespace mlir { namespace neura { -class HeuristicMapping : public MappingStrategy { +class HeuristicMapping : public Mapping { public: HeuristicMapping(int max_location_to_try = 5, int max_backtrack_depth = 3) - : max_location_to_try(max_location_to_try), max_backtrack_depth(3) {} + : 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, @@ -20,26 +22,23 @@ class HeuristicMapping : public MappingStrategy { MappingState &mapping_state) override; std::string getName() const override { - if (max_location_to_try == 1 && - max_backtrack_depth == 1) { + if (max_location_to_try == 1 && max_backtrack_depth == 1) { return "simple"; - } else if (max_location_to_try == INT_MAX && - max_backtrack_depth == 1) { + } else if (max_location_to_try == INT_MAX && max_backtrack_depth == 1) { return "greedy"; } else if (max_location_to_try == INT_MAX && max_backtrack_depth == INT_MAX) { return "exhaustive"; } else { - return "heuristic"; + return "customized"; } } private: - bool mapWithBacktrack(std::vector> &sorted_ops_with_levels, - std::set &critical_ops, - const Architecture &architecture, - MappingState &mapping_state, size_t current_index, - int backtrack_depth); + bool mapWithBacktrack( + std::vector> &sorted_ops_with_levels, + std::set &critical_ops, const Architecture &architecture, + MappingState &mapping_state); // Configuration parameters. int max_location_to_try; // Maximum number of locations to try for @@ -49,24 +48,4 @@ class HeuristicMapping : public MappingStrategy { } // namespace neura } // namespace mlir -namespace mlir { -namespace neura { -class MappingStateSnapshot { -public: - MappingStateSnapshot(const MappingState &mapping_state); - - void restore(MappingState &mapping_state); - - std::map> getOpToLocs() { - return this->op_to_locs; - } - -private: - std::set occupied_locs; - std::map loc_to_op; - std::map> op_to_locs; -}; -} // namespace neura -} // namespace mlir - -#endif // NEURA_BACKTRACK_MAPPING_H \ No newline at end of file +#endif // NEURA_HEURISTIC_MAPPING_H \ No newline at end of file diff --git a/include/NeuraDialect/Mapping/Mapping.h b/include/NeuraDialect/Mapping/Mapping.h new file mode 100644 index 00000000..16b9148c --- /dev/null +++ b/include/NeuraDialect/Mapping/Mapping.h @@ -0,0 +1,29 @@ +#ifndef NEURA_MAPPING_H +#define NEURA_MAPPING_H + +#include "NeuraDialect/Architecture/Architecture.h" +#include "NeuraDialect/Mapping/MappingState.h" +#include + +namespace mlir { +namespace neura { + +// Abstract base class for different mapping strategies. +class Mapping { +public: + 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; + + // Gets the name of this strategy + virtual std::string getName() const = 0; +}; + +} // namespace neura +} // namespace mlir + +#endif // NEURA_MAPPING_H \ No newline at end of file diff --git a/include/NeuraDialect/Mapping/MappingState.h b/include/NeuraDialect/Mapping/MappingState.h index dc439770..1ec75ab8 100644 --- a/include/NeuraDialect/Mapping/MappingState.h +++ b/include/NeuraDialect/Mapping/MappingState.h @@ -40,7 +40,8 @@ struct MappingLoc { namespace std { template <> struct hash { std::size_t operator()(const mlir::neura::MappingLoc &loc) const { - std::size_t h1 = std::hash()(static_cast(loc.resource->getKind())); + std::size_t h1 = + std::hash()(static_cast(loc.resource->getKind())); std::size_t h2 = std::hash()(loc.resource->getId()); std::size_t h3 = std::hash()(loc.time_step); return h1 ^ (h2 << 1) ^ (h3 << 2); @@ -71,8 +72,7 @@ class MappingState { // Checks if a hardware resource is available across a time range. // This function leverages the isAvailableAcrossTime function in each // time step. - bool isAvailableAcrossTimeInRange(BasicResource *resource, - int start_time, + bool isAvailableAcrossTimeInRange(BasicResource *resource, int start_time, int exclusive_end_time) const; // Gets the operation at a specific (tile/link, time_step) location. @@ -130,7 +130,8 @@ class MappingState { void setLocToOp(const std::map &loc_to_op) { this->loc_to_op = loc_to_op; } - void setOpToLocs(const std::map> &op_to_locs) { + void setOpToLocs( + const std::map> &op_to_locs) { this->op_to_locs = op_to_locs; } @@ -147,4 +148,24 @@ class MappingState { } // namespace neura } // namespace mlir +namespace mlir { +namespace neura { +class MappingStateSnapshot { +public: + MappingStateSnapshot(const MappingState &mapping_state); + + void restore(MappingState &mapping_state); + + std::map> getOpToLocs() { + return this->op_to_locs; + } + +private: + std::set occupied_locs; + std::map loc_to_op; + std::map> op_to_locs; +}; +} // namespace neura +} // namespace mlir + #endif // NEURA_MAPPING_STATE_H diff --git a/include/NeuraDialect/Mapping/MappingStrategy.h b/include/NeuraDialect/Mapping/MappingStrategy.h deleted file mode 100644 index 52af40e1..00000000 --- a/include/NeuraDialect/Mapping/MappingStrategy.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef NEURA_MAPPING_STRATEGY_H -#define NEURA_MAPPING_STRATEGY_H - -#include "NeuraDialect/Architecture/Architecture.h" -#include "NeuraDialect/Mapping/MappingState.h" -#include - -namespace mlir { -namespace neura { - -// Abstract base class for different mapping strategies. -class MappingStrategy { -public: - virtual ~MappingStrategy() = 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; - - // Gets the name of this strategy - virtual std::string getName() const = 0; -}; - -} // namespace neura -} // namespace mlir - -#endif // NEURA_MAPPING_STRATEGY_H \ No newline at end of file diff --git a/lib/NeuraDialect/CMakeLists.txt b/lib/NeuraDialect/CMakeLists.txt index c1faae04..71f7ccb6 100644 --- a/lib/NeuraDialect/CMakeLists.txt +++ b/lib/NeuraDialect/CMakeLists.txt @@ -5,7 +5,7 @@ add_mlir_dialect_library(MLIRNeura NeuraPasses.cpp Mapping/mapping_util.cpp Mapping/MappingState.cpp - Mapping/MappingStrategy.cpp + Mapping/Mapping.cpp Mapping/HeuristicMapping/HeuristicMapping.cpp Architecture/Architecture.cpp diff --git a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp index c0990182..d7777938 100644 --- a/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp +++ b/lib/NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.cpp @@ -1,4 +1,5 @@ #include "NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h" +#include "NeuraDialect/Mapping/MappingState.h" #include "NeuraDialect/Mapping/mapping_util.h" #include "NeuraDialect/NeuraOps.h" #include "llvm/Support/raw_ostream.h" @@ -6,116 +7,192 @@ namespace mlir { namespace neura { -bool HeuristicMapping::map(std::vector> &sorted_ops_with_levels, - std::set &critical_ops, - const Architecture &architecture, - MappingState &mapping_state) { +// Returns true if the operation does not need CGRA tile placement. +inline bool is_non_materialized(Operation *op) { + // Returns true if the operation does not need CGRA tile placement. + return mlir::isa(op); +} + +bool HeuristicMapping::map( + std::vector> &sorted_ops_with_levels, + std::set &critical_ops, const Architecture &architecture, + MappingState &mapping_state) { // Start the backtracking mapping process from the first operation. - return mapWithBacktrack(sorted_ops_with_levels, - critical_ops, - architecture, - mapping_state, - 0, - 0); + return mapWithBacktrack(sorted_ops_with_levels, critical_ops, architecture, + mapping_state); } bool HeuristicMapping::mapWithBacktrack( std::vector> &sorted_ops_with_levels, - std::set &critical_ops, - const Architecture &architecture, - MappingState &mapping_state, - size_t op_index, int backtrack_depth) { - // Checks if the backtrack depth exceeds the maximum allowed. - if (backtrack_depth > this->max_backtrack_depth) { - llvm::errs() << "[BacktrackMapping] Max backtrack depth reached\n"; - return false; // Backtrack failed, max depth reached. + std::set &critical_ops, const Architecture &architecture, + MappingState &mapping_state) { + llvm::outs() << "---------------------------------------------------------\n"; + llvm::outs() << "[HeuristicMapping] Starting mapping with " + << sorted_ops_with_levels.size() << " operations.\n"; + llvm::outs() << "Configuration: MAX Backtrack Depth = " + << this->max_backtrack_depth + << ", MAX Candidate Locations = " << this->max_location_to_try + << "\n"; + + std::vector> materialized_ops; + for (auto [op, level] : sorted_ops_with_levels) { + if (!is_non_materialized(op)) { + materialized_ops.emplace_back(op, level); + } } - // Success condition: all operations are mapped (The op_index is larger than - // or equal to the number of operations). - if (op_index >= sorted_ops_with_levels.size()) { - llvm::errs() << "[BacktrackMapping] Successfully mapped all operations.\n"; - return true; - } + llvm::outs() << "[HeuristicMapping] Filtered " + << sorted_ops_with_levels.size() - materialized_ops.size() + << " non-materialized operations, " << materialized_ops.size() + << " operations require physical mapping." << "\n"; - // Gets the current operation with expected ALAP level (time step) to map. - Operation *target_op = sorted_ops_with_levels[op_index].first; - int target_level = sorted_ops_with_levels[op_index].second; - - // Skips non-materialized operations. - if (isa(target_op)) { - // Increments the op_index to skip non-materialized operations. - return mapWithBacktrack(sorted_ops_with_levels, - critical_ops, - architecture, - mapping_state, - op_index + 1, - backtrack_depth); - } + // Stores the mapping state snapshots for backtracking. + std::vector snapshots; - // Gets candidate locations sorted by award. - std::vector loc_candidates = - calculateAward(target_op, critical_ops, target_level, architecture, mapping_state); + // For each operation, stores the candidate locations. + std::vector candidate_history; - if (loc_candidates.empty()) { - llvm::errs() << "No locations found for op: " << *target_op << "\n"; - return false; // No locations available for this operation. - } - assert(!loc_candidates.empty() && "No locations found for the operation to map"); - - // Limits the number of locations to try. - int locations_to_try = - std::min(static_cast(loc_candidates.size()), this->max_location_to_try); - - // Tries each candicate location in order of decreasing award. - for (int i = 0; i < locations_to_try; ++i) { - MappingLoc target_loc = loc_candidates[i]; - // Creates a mapping snapshot of current state before attempting to map. - MappingStateSnapshot mappingstate_snapshot(mapping_state); - - // Attempts to place and route the operation at the target location. - if (placeAndRoute(target_op, target_loc, mapping_state)) { - // Successfully placed and routed current operation, tries to map the next - // operation. - if (mapWithBacktrack(sorted_ops_with_levels, - critical_ops, - architecture, - mapping_state, - op_index + 1, - backtrack_depth)) { - return true; // Successfully mapped all operations. + // Stores the mapping history for each operation. + std::vector operation_index_history; + + // Starts from the initial mapping state. + snapshots.push_back(MappingStateSnapshot(mapping_state)); + candidate_history.push_back(0); + operation_index_history.push_back(0); + + // Tracks the maximum depth of operations reached during mapping. + int max_op_reached = 0; + + while (!operation_index_history.empty()) { + // Gets the current operation index to map. + int current_op_index = operation_index_history.back(); + + if (current_op_index >= static_cast(materialized_ops.size())) { + // All operations have been mapped successfully. + llvm::outs() << "[HeuristicMapping] Successfully mapped all " + << materialized_ops.size() << " operations.\n"; + return true; + } + + max_op_reached = + std::max(max_op_reached, + current_op_index); // Updates the max operation reached. + + if (max_op_reached - current_op_index > this->max_backtrack_depth) { + llvm::outs() << "[HeuristicMapping] Max backtrack depth exceeded: " + << (max_op_reached - current_op_index) << " > " + << this->max_backtrack_depth << ".\n"; + return false; // Backtrack failed, max depth exceeded. + } + + Operation *current_op = materialized_ops[current_op_index].first; + std::vector candidate_locs = calculateAward( + current_op, critical_ops, materialized_ops[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. } - // Failed to place next operation, restores the mapping state and try next - // location. - llvm::errs() << "[BACKTRACK] Failed to map in current location, " - << "restoring mapping state and trying next location.\n"; - llvm::errs() << "[BACKTRACK] Backtracking from op: " << *target_op << "\n"; - mappingstate_snapshot.restore(mapping_state); - // Increments backtrack depth. - backtrack_depth++; + 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"; + // Limits the number of locations to try. + if (candidate_locs.size() > + static_cast(this->max_location_to_try)) { + candidate_locs.resize(static_cast(this->max_location_to_try)); + } + + int ¤t_candidate_index = candidate_history.back(); + + if (current_candidate_index >= static_cast(candidate_locs.size())) { + // Needs to backtrack since all candidate locations have been tried. + 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; + } + + // 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; + } + + MappingLoc candidate_loc = candidate_locs[current_candidate_index]; + + llvm::outs() << "[HeuristicMapping] Trying candidate " + << (current_candidate_index + 1) << "/" + << candidate_locs.size() << " at " + << candidate_loc.resource->getType() << "#" + << candidate_loc.resource->getId() + << " @t=" << candidate_loc.time_step << "\n"; + + // Saves the current mapping state snapshot before attempting to map. + MappingStateSnapshot snapshot(mapping_state); + + // Attempts to place and route the operation at the candidate location. + if (placeAndRoute(current_op, candidate_loc, mapping_state)) { + llvm::outs() << "[HeuristicMapping] Successfully mapped operation " + << *current_op << "\n"; + + // Adds a new decision point for the next operation. + snapshots.push_back(MappingStateSnapshot(mapping_state)); + candidate_history.push_back(0); + operation_index_history.push_back(current_op_index + 1); + } else { + // Mapping failed, restores state and tries the next candidate. + llvm::outs() << "[HeuristicMapping] Failed to map operation " + << *current_op << " to candidate location " + << (current_candidate_index + 1) << "/" + << candidate_locs.size() << "\n"; + + snapshot.restore(mapping_state); + current_candidate_index++; } } - // All candidate locations failed. + // If we reach here, it means we have exhausted all possibilities. + llvm::errs() << "[HeuristicMapping] FAILURE: Exhausted all possibilities\n"; return false; } } // namespace neura } // namespace mlir - -namespace mlir { -namespace neura { -MappingStateSnapshot::MappingStateSnapshot(const MappingState &mapping_state) { - this->occupied_locs = mapping_state.getOccupiedLocs(); - this->loc_to_op = mapping_state.getLocToOp(); - this->op_to_locs = mapping_state.getOpToLocs(); -} - -void MappingStateSnapshot::restore(MappingState &mapping_state) { - mapping_state.setOccupiedLocs(this->occupied_locs); - mapping_state.setLocToOp(this->loc_to_op); - mapping_state.setOpToLocs(this->op_to_locs); -} -} // namespace neura -} // namespace mlir \ No newline at end of file diff --git a/lib/NeuraDialect/Mapping/Mapping.cpp b/lib/NeuraDialect/Mapping/Mapping.cpp new file mode 100644 index 00000000..7e8c4004 --- /dev/null +++ b/lib/NeuraDialect/Mapping/Mapping.cpp @@ -0,0 +1,2 @@ +#include "NeuraDialect/Mapping/Mapping.h" +#include \ No newline at end of file diff --git a/lib/NeuraDialect/Mapping/MappingState.cpp b/lib/NeuraDialect/Mapping/MappingState.cpp index c80f5866..d918602e 100644 --- a/lib/NeuraDialect/Mapping/MappingState.cpp +++ b/lib/NeuraDialect/Mapping/MappingState.cpp @@ -63,7 +63,8 @@ std::optional MappingState::getOpAt(MappingLoc loc) const { return it->second; } -std::optional MappingState::getOpAtLocAcrossTime(MappingLoc loc) const { +std::optional +MappingState::getOpAtLocAcrossTime(MappingLoc loc) const { for (int t = loc.time_step % II; t < II * kMaxSteps; t += II) { MappingLoc check_loc = {loc.resource, t}; auto it = loc_to_op.find(check_loc); @@ -84,7 +85,8 @@ int MappingState::countOpsAtResource(BasicResource *resource) const { return count; } -const std::vector &MappingState::getAllLocsOfOp(Operation *op) const { +const std::vector & +MappingState::getAllLocsOfOp(Operation *op) const { auto it = op_to_locs.find(op); if (it != op_to_locs.end()) { return it->second; @@ -130,7 +132,8 @@ std::vector MappingState::getNextStepTiles(MappingLoc loc) const { // return it != current_step_tiles.end() ? it->second : empty; // } -std::vector MappingState::getCurrentStepLinks(MappingLoc loc) const { +std::vector +MappingState::getCurrentStepLinks(MappingLoc loc) const { assert((loc.resource->getKind() == ResourceKind::Tile) && "Current step links can only be queried for tiles"); std::vector current_step_links; @@ -276,4 +279,16 @@ void MappingState::encodeMappingState() { } op->setAttr("mapping_locs", mlir::ArrayAttr::get(ctx, mapping_entries)); } -} \ No newline at end of file +} + +MappingStateSnapshot::MappingStateSnapshot(const MappingState &mapping_state) { + this->occupied_locs = mapping_state.getOccupiedLocs(); + this->loc_to_op = mapping_state.getLocToOp(); + this->op_to_locs = mapping_state.getOpToLocs(); +} + +void MappingStateSnapshot::restore(MappingState &mapping_state) { + mapping_state.setOccupiedLocs(this->occupied_locs); + mapping_state.setLocToOp(this->loc_to_op); + mapping_state.setOpToLocs(this->op_to_locs); +} diff --git a/lib/NeuraDialect/Mapping/MappingStrategy.cpp b/lib/NeuraDialect/Mapping/MappingStrategy.cpp deleted file mode 100644 index 6718b431..00000000 --- a/lib/NeuraDialect/Mapping/MappingStrategy.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "NeuraDialect/Mapping/MappingStrategy.h" -#include \ No newline at end of file diff --git a/lib/NeuraDialect/Mapping/mapping_util.cpp b/lib/NeuraDialect/Mapping/mapping_util.cpp index 1640e5ec..c65aebe5 100644 --- a/lib/NeuraDialect/Mapping/mapping_util.cpp +++ b/lib/NeuraDialect/Mapping/mapping_util.cpp @@ -89,7 +89,7 @@ void traverseAlongPath(Operation *op, Value reserve_value, } // namespace SmallVector - mlir::neura::collectRecurrenceCycles(Operation *func_op) { +mlir::neura::collectRecurrenceCycles(Operation *func_op) { SmallVector recurrence_cycles; func_op->walk([&](neura::CtrlMovOp ctrl_mov_op) { @@ -147,7 +147,7 @@ int mlir::neura::calculateResMii(Operation *func_op, } std::vector - mlir::neura::getTopologicallySortedOps(Operation *func_op) { +mlir::neura::getTopologicallySortedOps(Operation *func_op) { std::vector sorted_ops; llvm::DenseMap pending_deps; std::deque ready_queue; @@ -209,8 +209,8 @@ std::vector } std::vector> - mlir::neura::getOpsInAlapLevels(const std::vector &sorted_ops, - const std::set &critical_ops) { +mlir::neura::getOpsInAlapLevels(const std::vector &sorted_ops, + const std::set &critical_ops) { llvm::DenseMap op_level; int max_level = 0; @@ -221,7 +221,8 @@ std::vector> int level = 0; for (Value result : op->getResults()) { for (Operation *user : result.getUsers()) { - if (!op_level.count(user)) continue; + if (!op_level.count(user)) + continue; int user_level = op_level[user]; @@ -245,14 +246,19 @@ std::vector> op_level[op] = normalized_level; } - // Step 3: Overwrites critical ops with ASAP schedule: shortest path from source. + // Step 3: Overwrites critical ops with ASAP schedule: shortest path from + // source. for (Operation *op : sorted_ops) { - if (!critical_ops.count(op)) continue; + if (!critical_ops.count(op)) { + continue; + } int level = -1; for (Value operand : op->getOperands()) { Operation *def = operand.getDefiningOp(); - if (!def || !op_level.count(def)) continue; + if (!def || !op_level.count(def)) { + continue; + } int def_level = op_level[def]; @@ -272,7 +278,6 @@ std::vector> } } - // Step 4: Assembles the ops into level buckets. std::vector> level_buckets(max_level + 1); @@ -283,8 +288,8 @@ std::vector> return level_buckets; } -std::vector> - mlir::neura::flatten_level_buckets(const std::vector> &level_buckets) { +std::vector> mlir::neura::flatten_level_buckets( + const std::vector> &level_buckets) { std::vector> result; for (int level = 0; level < static_cast(level_buckets.size()); ++level) { @@ -319,7 +324,7 @@ mlir::Operation *mlir::neura::getMaterializedBackwardUser(Operation *op) { } llvm::SmallVector - mlir::neura::getMaterializedUserOps(Operation *op) { +mlir::neura::getMaterializedUserOps(Operation *op) { llvm::SmallVector result; llvm::DenseSet visited; visited.insert(op); @@ -565,8 +570,7 @@ bool mlir::neura::canReachLocInTime(const MappingLoc &src_loc, // Checks if the destination is reachable from the source within the given // time window. if (src_loc.resource == dst_loc.resource && - src_loc.time_step < deadline_step && - dst_loc.time_step <= deadline_step) { + src_loc.time_step < deadline_step && dst_loc.time_step <= deadline_step) { return true; } @@ -646,11 +650,10 @@ 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, 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()) { @@ -688,7 +691,7 @@ std::vector mlir::neura::calculateAward(Operation *op, mlir::Operation *materialized_backward_op = getMaterializedBackwardUser(ctrl_mov); assert(isa(materialized_backward_op) && - "Expected materialized operation of ctrl_mov to be a PhiOp"); + "Expected materialized operation of ctrl_mov to be a PhiOp"); backward_users.push_back(materialized_backward_op); } @@ -708,14 +711,13 @@ std::vector mlir::neura::calculateAward(Operation *op, 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); + earliest_start_time_step = + std::max(earliest_start_time_step, producer_loc.time_step + 1); } int latest_end_time_step = earliest_start_time_step + mapping_state.getII(); std::vector backward_users_locs; for (Operation *user : backward_users) { - std::vector user_locs = - mapping_state.getAllLocsOfOp(user); + std::vector user_locs = mapping_state.getAllLocsOfOp(user); assert(!user_locs.empty() && "No locations found for backward user"); MappingLoc backward_user_loc = user_locs.back(); @@ -727,7 +729,8 @@ std::vector mlir::neura::calculateAward(Operation *op, int award = 2 * mapping_state.getII(); if (critical_ops.count(op)) { award += tile->getDstTiles().size(); - award += op->getOperands().size() - getPhysicalHops(producers, tile, mapping_state); + award += op->getOperands().size() - + getPhysicalHops(producers, tile, mapping_state); } // llvm::errs() << "[DEBUG] checking range: " // << earliest_start_time_step << " to " @@ -737,15 +740,16 @@ std::vector mlir::neura::calculateAward(Operation *op, MappingLoc tile_loc_candidate = {tile, t}; // 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() || + bool meet_producer_constraint = + producers.empty() || canReachLocInTime(producers, tile_loc_candidate, t, mapping_state); bool meet_backward_user_constraint = true; for (auto &backward_user_loc : backward_users_locs) { // If there is no backward user, we can consider it for mapping. // Otherwise, check if the location can reach all backward users. - if (!canReachLocInTime(tile_loc_candidate, - backward_user_loc, - backward_user_loc.time_step + mapping_state.getII(), + if (!canReachLocInTime(tile_loc_candidate, backward_user_loc, + backward_user_loc.time_step + + mapping_state.getII(), mapping_state)) { meet_backward_user_constraint = false; break; // No need to check further. @@ -755,9 +759,10 @@ std::vector mlir::neura::calculateAward(Operation *op, // no backward user or the location can reach all backward users, // 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, tile, mapping_state); - // if (op->getOperands().size() > 1 && getPhysicalHops(producers, tile, mapping_state) < 2) { + // Grants higher award if the location is physically closed to + // producers. award += producers.size() - getPhysicalHops(producers, + // tile, mapping_state); if (op->getOperands().size() > 1 && + // getPhysicalHops(producers, tile, mapping_state) < 2) { // award += 1; // } updateAward(locs_with_award, tile_loc_candidate, award); diff --git a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp index ee2c4a5e..ed4416b6 100644 --- a/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp +++ b/lib/NeuraDialect/Transforms/MapToAcceleratorPass.cpp @@ -1,4 +1,5 @@ #include +#include #include "NeuraDialect/Architecture/Architecture.h" #include "NeuraDialect/Mapping/HeuristicMapping/HeuristicMapping.h" @@ -12,6 +13,7 @@ #include "mlir/IR/PatternMatch.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" using namespace mlir; @@ -41,62 +43,70 @@ struct MapToAcceleratorPass Option mappingStrategy{ *this, "mapping-strategy", llvm::cl::desc("Mapping strategy to use for mapping operations to the " - "accelerator. Options: greedy, exhaustive, " - "heuristic=max_loc,max_depth (default " - "max_loc=5, max_depth=3)"), + "accelerator. Options: heuristic (default)."), + llvm::cl::init("heuristic")}; + Option backtrackConfig{ + *this, "backtrack-config", + llvm::cl::desc( + "Backtrack configuration used for mapping operations to the " + "accelerator. Options: simple, greedy, exhaustive, " + "customized=max_loc,max_depth (default " + "max_loc=5, max_depth=3)"), llvm::cl::init("heuristic")}; void runOnOperation() override { ModuleOp module = getOperation(); - + std::unique_ptr mapping_strategy; StringRef mappingStrategy_stringRef(mappingStrategy.getValue()); - // Creates a mapping strategy based on the provided option. - std::unique_ptr mapping_strategy; - if (mappingStrategy_stringRef == "simple") { - mapping_strategy = std::make_unique(1, 1); - } else if (mappingStrategy_stringRef == "greedy") { - mapping_strategy = std::make_unique(INT_MAX, 1); - } else if (mappingStrategy_stringRef == "exhaustive") { - mapping_strategy = std::make_unique(INT_MAX, INT_MAX); - } else if (mappingStrategy_stringRef == "heuristic") { - mapping_strategy = std::make_unique( - 5, 3); // Randomly picked default values for max_loc and max_depth - } else if (mappingStrategy_stringRef.starts_with("heuristic=")) { - // Used for custom backtrack parameters. - // Example: "heuristic=5,3" means max_loc=5, max_depth=3 - // Extracts the parameters after "heuristic=". - StringRef paramsRef = - mappingStrategy_stringRef.substr(strlen("heuristic=")); - size_t comma_pos = paramsRef.find(','); - - if (comma_pos != StringRef::npos) { - StringRef max_loc_str = paramsRef.substr(0, comma_pos); - StringRef max_depth_str = paramsRef.substr(comma_pos + 1); - - int max_loc, max_depth; - if (!max_loc_str.getAsInteger(10, max_loc) && - !max_depth_str.getAsInteger(10, max_depth)) { - mapping_strategy = - std::make_unique(max_loc, max_depth); - llvm::errs() - << "[MapToAcceleratorPass] Use custom backtrack parameters: " - << "max_location_to_try=" << max_loc - << ", max_backtrack_depth=" << max_depth << "\n"; + StringRef backtrackConfig_stringRef(backtrackConfig.getValue()); + if (mappingStrategy_stringRef == "heuristic" || + mappingStrategy_stringRef.empty()) { + + if (backtrackConfig_stringRef == "simple") { + mapping_strategy = std::make_unique(1, 1); + } else if (backtrackConfig_stringRef == "greedy") { + mapping_strategy = std::make_unique(INT_MAX, 1); + } else if (backtrackConfig_stringRef == "exhaustive") { + mapping_strategy = std::make_unique(INT_MAX, INT_MAX); + } else if (backtrackConfig_stringRef == "customized") { + mapping_strategy = std::make_unique(5, 3); + } else if (backtrackConfig_stringRef.starts_with("customized=")) { + // Used for custom backtrack parameters. + // Example: "customized=5,3" means max_loc=5, max_depth=3 + // Extracts the parameters after "customized=". + StringRef paramsRef = + backtrackConfig_stringRef.substr(strlen("customized=")); + size_t comma_pos = paramsRef.find(','); + + if (comma_pos != StringRef::npos) { + StringRef max_loc_str = paramsRef.substr(0, comma_pos); + StringRef max_depth_str = paramsRef.substr(comma_pos + 1); + + int max_loc, max_depth; + if (!max_loc_str.getAsInteger(10, max_loc) && + !max_depth_str.getAsInteger(10, max_depth)) { + mapping_strategy = + std::make_unique(max_loc, max_depth); + llvm::errs() + << "[MapToAcceleratorPass] Use custom backtrack parameters: " + << "max_location_to_try=" << max_loc + << ", max_backtrack_depth=" << max_depth << "\n"; + } else { + llvm::errs() << "[MapToAcceleratorPass] Illegal customized " + "parameters format: " + << backtrackConfig_stringRef << "\n"; + return; + } } else { llvm::errs() - << "[MapToAcceleratorPass] Illegal backtrack parameters format: " - << mappingStrategy << "\n"; + << "[MapToAcceleratorPass] Illegal customized parameters format: " + << backtrackConfig_stringRef << "\n"; return; } - } else { - llvm::errs() - << "[MapToAcceleratorPass] Illegal backtrack parameters format: " - << mappingStrategy << "\n"; - return; } } else { llvm::errs() << "[MapToAcceleratorPass] Unsupported mapping strategy: " - << mappingStrategy << "\n"; + << mappingStrategy_stringRef << "\n"; return; } diff --git a/test/controflow_fuse/simple_loop/simple_loop.mlir b/test/controflow_fuse/simple_loop/simple_loop.mlir index d58671b4..a1851f43 100644 --- a/test/controflow_fuse/simple_loop/simple_loop.mlir +++ b/test/controflow_fuse/simple_loop/simple_loop.mlir @@ -58,7 +58,7 @@ // RUN: --fuse-control-flow \ // RUN: --fold-constant \ // RUN: --insert-data-mov \ -// RUN: --map-to-accelerator="mapping-strategy=heuristic" | FileCheck %s -check-prefix=FUSE-MAPPING +// RUN: --map-to-accelerator="mapping-strategy=heuristic backtrack-config=customized" | FileCheck %s -check-prefix=FUSE-MAPPING module attributes {} { func.func @_Z11simple_loopPiS_(%arg0: memref, %arg1: memref) attributes {llvm.linkage = #llvm.linkage} { @@ -183,46 +183,46 @@ module attributes {} { // FUSE-NEXT: "neura.return"() : () -> () // FUSE-NEXT: } -// FUSE-MAPPING: func.func @_Z11simple_loopPiS_(%arg0: memref, %arg1: memref) attributes {CompiledII = 4 : i32, RecMII = 1 : i32, ResMII = 2 : i32, accelerator = "neura", llvm.linkage = #llvm.linkage} { -// FUSE-MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = "%arg0"}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 1 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %1 = "neura.grant_once"() <{constant_value = "%arg1"}> {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 4 : i32, x = 0 : i32, y = 3 : i32}]} : () -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %2 = "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 -// FUSE-MAPPING-NEXT: %3 = "neura.grant_always"() <{constant_value = 128 : i64}> {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 1 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %4 = "neura.grant_once"() <{constant_value = 1 : i32}> {mapping_locs = [{id = 0 : i32, resource = "tile", time_step = 3 : i32, x = 0 : i32, y = 0 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %5 = "neura.grant_once"() <{constant_value = 2 : i32}> {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 2 : i32, x = 0 : i32, y = 3 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %6 = "neura.grant_once"() <{constant_value = 0 : i64}> {mapping_locs = [{id = 13 : i32, resource = "tile", time_step = 0 : i32, x = 1 : i32, y = 3 : i32}]} : () -> !neura.data -// FUSE-MAPPING-NEXT: %7 = "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: %8 = "neura.data_mov"(%7) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 0 : i32}, {id = 33 : i32, resource = "link", time_step = 1 : i32}, {id = 24 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %9 = "neura.data_mov"(%6) {mapping_locs = [{id = 41 : i32, resource = "link", time_step = 0 : i32}, {id = 45 : i32, resource = "link", time_step = 1 : i32}, {id = 33 : i32, resource = "link", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %10 = "neura.data_mov"(%3) {mapping_locs = [{id = 14 : i32, resource = "link", time_step = 0 : i32}, {id = 25 : i32, resource = "register", time_step = 1 : i32}, {id = 25 : i32, resource = "register", time_step = 2 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %11 = "neura.data_mov"(%2) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 0 : i32}, {id = 3 : i32, resource = "link", time_step = 1 : i32}, {id = 7 : i32, resource = "link", 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 = 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 +// FUSE-MAPPING: func.func @_Z11simple_loopPiS_(%arg0: memref, %arg1: memref) attributes {CompiledII = 5 : i32, RecMII = 1 : i32, ResMII = 2 : i32, accelerator = "neura", llvm.linkage = #llvm.linkage} { +// 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-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: %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 = 0 : i32, resource = "link", time_step = 1 : i32}, {id = 3 : i32, resource = "link", time_step = 2 : i32}, {id = 7 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %15 = "neura.data_mov"(%valid) {mapping_locs = []} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %16 = neura.grant_predicate %14, %15 {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 4 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data, i1>, !neura.data -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %17 = "neura.data_mov"(%5) {mapping_locs = [{id = 38 : i32, resource = "link", time_step = 2 : i32}, {id = 41 : i32, resource = "link", time_step = 3 : i32}, {id = 56 : i32, resource = "register", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %18 = "neura.data_mov"(%valid) {mapping_locs = [{id = 20 : i32, resource = "link", time_step = 3 : i32}, {id = 34 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %19 = neura.grant_predicate %17, %18 {mapping_locs = [{id = 14 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 3 : i32}]} : !neura.data, !neura.data -> !neura.data -// FUSE-MAPPING-NEXT: %20 = "neura.data_mov"(%4) {mapping_locs = [{id = 0 : i32, resource = "link", time_step = 3 : i32}, {id = 4 : i32, resource = "register", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %21 = "neura.data_mov"(%valid) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 3 : i32}, {id = 15 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %22 = neura.grant_predicate %20, %21 {mapping_locs = [{id = 1 : i32, resource = "tile", time_step = 5 : i32, x = 1 : i32, y = 0 : i32}]} : !neura.data, !neura.data -> !neura.data -// FUSE-MAPPING-NEXT: %23 = "neura.data_mov"(%1) {mapping_locs = [{id = 38 : i32, resource = "link", time_step = 4 : i32}, {id = 42 : i32, resource = "link", time_step = 5 : i32}, {id = 36 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %24 = "neura.data_mov"(%valid) {mapping_locs = [{id = 18 : i32, resource = "link", time_step = 3 : i32}, {id = 23 : i32, resource = "link", time_step = 4 : i32}, {id = 35 : i32, resource = "link", time_step = 5 : i32}, {id = 31 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %25 = neura.grant_predicate %23, %24 {mapping_locs = [{id = 9 : i32, resource = "tile", time_step = 7 : i32, x = 1 : i32, y = 2 : i32}]} : !neura.data, i1>, !neura.data -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %26 = "neura.data_mov"(%16) {mapping_locs = [{id = 19 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> -// FUSE-MAPPING-NEXT: %27 = "neura.data_mov"(%nextindex) {mapping_locs = [{id = 19 : i32, resource = "link", time_step = 3 : i32}, {id = 8 : i32, resource = "register", 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 = 6 : i32, resource = "link", time_step = 5 : i32}, {id = 9 : i32, resource = "link", time_step = 6 : i32}, {id = 28 : i32, resource = "register", time_step = 7 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %30 = "neura.data_mov"(%19) {mapping_locs = [{id = 44 : i32, resource = "link", time_step = 5 : i32}, {id = 47 : i32, resource = "link", time_step = 6 : i32}, {id = 36 : i32, resource = "link", time_step = 7 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %31 = "neura.mul"(%29, %30) {mapping_locs = [{id = 7 : i32, resource = "tile", time_step = 8 : i32, x = 3 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %32 = "neura.data_mov"(%31) {mapping_locs = [{id = 21 : i32, resource = "link", time_step = 8 : i32}, {id = 17 : i32, resource = "link", time_step = 9 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %33 = "neura.data_mov"(%22) {mapping_locs = [{id = 4 : i32, resource = "link", time_step = 5 : i32}, {id = 20 : i32, resource = "register", time_step = 6 : i32}, {id = 20 : i32, resource = "register", time_step = 7 : i32}, {id = 20 : i32, resource = "register", time_step = 8 : i32}, {id = 20 : i32, resource = "register", time_step = 9 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %34 = "neura.add"(%32, %33) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 10 : i32, x = 1 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %35 = "neura.data_mov"(%34) {mapping_locs = [{id = 14 : i32, resource = "link", time_step = 10 : i32}, {id = 24 : i32, resource = "register", time_step = 11 : i32}, {id = 24 : i32, resource = "register", time_step = 12 : i32}]} : (!neura.data) -> !neura.data -// FUSE-MAPPING-NEXT: %36 = "neura.data_mov"(%25) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 7 : i32}, {id = 33 : i32, resource = "link", time_step = 8 : i32}, {id = 26 : i32, resource = "register", time_step = 9 : i32}, {id = 26 : i32, resource = "register", time_step = 10 : i32}, {id = 26 : i32, resource = "register", time_step = 11 : i32}, {id = 26 : i32, resource = "register", time_step = 12 : i32}]} : (!neura.data, i1>) -> !neura.data, i1> +// 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: %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 = 13 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data -// FUSE-MAPPING-NEXT: "neura.return"() {mapping_locs = [{id = 15 : i32, resource = "tile", time_step = 6 : i32, x = 3 : i32, y = 3 : i32}]} : () -> () +// 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 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 50e189fb..679f5497 100644 --- a/test/controflow_fuse/simple_loop_reduction/simple_loop_reduction.mlir +++ b/test/controflow_fuse/simple_loop_reduction/simple_loop_reduction.mlir @@ -57,7 +57,7 @@ // RUN: --fuse-control-flow \ // RUN: --fold-constant \ // RUN: --insert-data-mov \ -// RUN: --map-to-accelerator="mapping-strategy=heuristic" | FileCheck %s -check-prefix=FUSE-MAPPING +// RUN: --map-to-accelerator="mapping-strategy=heuristic backtrack-config=customized=4,5" | FileCheck %s -check-prefix=FUSE-MAPPING module attributes {} { func.func @_Z10simpleloopv() -> i32 attributes {llvm.linkage = #llvm.linkage} { diff --git a/test/mapping_quality/branch_for.mlir b/test/mapping_quality/branch_for.mlir new file mode 100644 index 00000000..670e7459 --- /dev/null +++ b/test/mapping_quality/branch_for.mlir @@ -0,0 +1,313 @@ +// RUN: mlir-neura-opt %s \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --leverage-predicated-value \ +// RUN: | FileCheck %s + +// RUN: mlir-neura-opt %s \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --canonicalize-live-in \ +// RUN: --leverage-predicated-value \ +// RUN: | FileCheck %s -check-prefix=CANONICALIZE + +// RUN: mlir-neura-opt %s \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --canonicalize-live-in \ +// RUN: --leverage-predicated-value \ +// RUN: --transform-ctrl-to-data-flow \ +// RUN: | FileCheck %s -check-prefix=CTRL2DATA + +// RUN: mlir-neura-opt %s \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --canonicalize-live-in \ +// RUN: --leverage-predicated-value \ +// RUN: --transform-ctrl-to-data-flow \ +// RUN: --fold-constant \ +// RUN: | FileCheck %s -check-prefix=FUSE + +// RUN: mlir-neura-opt %s \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --canonicalize-live-in \ +// RUN: --leverage-predicated-value \ +// RUN: --transform-ctrl-to-data-flow \ +// RUN: --fold-constant \ +// RUN: --insert-data-mov \ +// RUN: | FileCheck %s -check-prefix=MOV + +// RUN: mlir-neura-opt %s \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --canonicalize-live-in \ +// RUN: --leverage-predicated-value \ +// RUN: --transform-ctrl-to-data-flow \ +// RUN: --fold-constant \ +// RUN: --insert-data-mov \ +// RUN: --map-to-accelerator="mapping-strategy=heuristic backtrack-config=customized" \ +// RUN: | FileCheck %s -check-prefix=MAPPING + +// RUN: mlir-neura-opt %s \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --canonicalize-live-in \ +// RUN: --leverage-predicated-value \ +// RUN: --transform-ctrl-to-data-flow \ +// RUN: --fold-constant \ +// RUN: --insert-data-mov \ +// RUN: --map-to-accelerator="mapping-strategy=heuristic backtrack-config=customized" \ +// RUN: --generate-code +// RUN: FileCheck %s --input-file=generated-instructions.json -check-prefix=INST + +func.func @loop_test() -> f32 { + %n = llvm.mlir.constant(10 : i64) : i64 + %c0 = llvm.mlir.constant(0 : i64) : i64 + %c1 = llvm.mlir.constant(1 : i64) : i64 + %c1f = llvm.mlir.constant(3.0 : f32) : f32 + %acc_init = llvm.mlir.constant(0.0 : f32) : f32 + + llvm.br ^bb1(%c0, %acc_init : i64, f32) + +^bb1(%i: i64, %acc: f32): // loop body + check + increment + %next_acc = llvm.fadd %acc, %c1f : f32 + %i_next = llvm.add %i, %c1 : i64 + %cmp = llvm.icmp "slt" %i_next, %n : i64 + llvm.cond_br %cmp, ^bb1(%i_next, %next_acc : i64, f32), ^exit(%next_acc : f32) + +^exit(%result: f32): + return %result : f32 +} + +// CHECK: func.func @loop_test() -> f32 attributes {accelerator = "neura"} { +// CHECK-NEXT: %0 = "neura.constant"() <{predicate = true, value = 10 : i64}> : () -> !neura.data +// CHECK-NEXT: %1 = "neura.constant"() <{predicate = true, value = 0 : i64}> : () -> !neura.data +// CHECK-NEXT: %2 = "neura.constant"() <{predicate = true, value = 1 : i64}> : () -> !neura.data +// CHECK-NEXT: %3 = "neura.constant"() <{predicate = true, value = 3.000000e+00 : f32}> : () -> !neura.data +// CHECK-NEXT: %4 = "neura.constant"() <{predicate = true, value = 0.000000e+00 : f32}> : () -> !neura.data +// CHECK-NEXT: neura.br %1, %4 : !neura.data, !neura.data to ^bb1 +// CHECK-NEXT: ^bb1(%5: !neura.data, %6: !neura.data): // 2 preds: ^bb0, ^bb1 +// CHECK-NEXT: %7 = "neura.fadd"(%6, %3) : (!neura.data, !neura.data) -> !neura.data +// CHECK-NEXT: %8 = "neura.add"(%5, %2) : (!neura.data, !neura.data) -> !neura.data +// CHECK-NEXT: %9 = "neura.icmp"(%8, %0) <{cmpType = "slt"}> : (!neura.data, !neura.data) -> !neura.data +// CHECK-NEXT: neura.cond_br %9 : !neura.data then %8, %7 : !neura.data, !neura.data to ^bb1 else %7 : !neura.data to ^bb2 +// CHECK-NEXT: ^bb2(%10: !neura.data): // pred: ^bb1 +// CHECK-NEXT: "neura.return"(%10) : (!neura.data) -> () +// CHECK-NEXT: } + +// CANONICALIZE: func.func @loop_test() -> f32 attributes {accelerator = "neura"} { +// CANONICALIZE-NEXT: %0 = "neura.constant"() <{predicate = true, value = 10 : i64}> : () -> !neura.data +// CANONICALIZE-NEXT: %1 = "neura.constant"() <{predicate = true, value = 0 : i64}> : () -> !neura.data +// CANONICALIZE-NEXT: %2 = "neura.constant"() <{predicate = true, value = 1 : i64}> : () -> !neura.data +// CANONICALIZE-NEXT: %3 = "neura.constant"() <{predicate = true, value = 3.000000e+00 : f32}> : () -> !neura.data +// CANONICALIZE-NEXT: %4 = "neura.constant"() <{predicate = true, value = 0.000000e+00 : f32}> : () -> !neura.data +// CANONICALIZE-NEXT: neura.br %1, %4, %3, %2, %0 : !neura.data, !neura.data, !neura.data, !neura.data, !neura.data to ^bb1 +// CANONICALIZE-NEXT: ^bb1(%5: !neura.data, %6: !neura.data, %7: !neura.data, %8: !neura.data, %9: !neura.data): // 2 preds: ^bb0, ^bb1 +// CANONICALIZE-NEXT: %10 = "neura.fadd"(%6, %7) : (!neura.data, !neura.data) -> !neura.data +// CANONICALIZE-NEXT: %11 = "neura.add"(%5, %8) : (!neura.data, !neura.data) -> !neura.data +// CANONICALIZE-NEXT: %12 = "neura.icmp"(%11, %9) <{cmpType = "slt"}> : (!neura.data, !neura.data) -> !neura.data +// CANONICALIZE-NEXT: neura.cond_br %12 : !neura.data then %11, %10, %3, %2, %0 : !neura.data, !neura.data, !neura.data, !neura.data, !neura.data to ^bb1 else %10 : !neura.data to ^bb2 +// CANONICALIZE-NEXT: ^bb2(%13: !neura.data): // pred: ^bb1 +// CANONICALIZE-NEXT: "neura.return"(%13) : (!neura.data) -> () +// CANONICALIZE-NEXT: } + +// CTRL2DATA: func.func @loop_test() -> f32 attributes {accelerator = "neura"} { +// CTRL2DATA-NEXT: %0 = "neura.constant"() <{predicate = true, value = 10 : i64}> : () -> !neura.data +// CTRL2DATA-NEXT: %1 = "neura.grant_once"(%0) : (!neura.data) -> !neura.data +// CTRL2DATA-NEXT: %2 = "neura.constant"() <{predicate = true, value = 0 : i64}> : () -> !neura.data +// CTRL2DATA-NEXT: %3 = "neura.grant_once"(%2) : (!neura.data) -> !neura.data +// CTRL2DATA-NEXT: %4 = "neura.constant"() <{predicate = true, value = 1 : i64}> : () -> !neura.data +// CTRL2DATA-NEXT: %5 = "neura.grant_once"(%4) : (!neura.data) -> !neura.data +// CTRL2DATA-NEXT: %6 = "neura.constant"() <{predicate = true, value = 3.000000e+00 : f32}> : () -> !neura.data +// CTRL2DATA-NEXT: %7 = "neura.grant_once"(%6) : (!neura.data) -> !neura.data +// CTRL2DATA-NEXT: %8 = "neura.constant"() <{predicate = true, value = 0.000000e+00 : f32}> : () -> !neura.data +// CTRL2DATA-NEXT: %9 = "neura.grant_once"(%8) : (!neura.data) -> !neura.data +// CTRL2DATA-NEXT: %10 = neura.reserve : !neura.data +// CTRL2DATA-NEXT: %11 = "neura.phi"(%10, %1) : (!neura.data, !neura.data) -> !neura.data +// CTRL2DATA-NEXT: %12 = neura.reserve : !neura.data +// CTRL2DATA-NEXT: %13 = "neura.phi"(%12, %5) : (!neura.data, !neura.data) -> !neura.data +// CTRL2DATA-NEXT: %14 = neura.reserve : !neura.data +// CTRL2DATA-NEXT: %15 = "neura.phi"(%14, %7) : (!neura.data, !neura.data) -> !neura.data +// CTRL2DATA-NEXT: %16 = neura.reserve : !neura.data +// CTRL2DATA-NEXT: %17 = "neura.phi"(%16, %9) : (!neura.data, !neura.data) -> !neura.data +// CTRL2DATA-NEXT: %18 = neura.reserve : !neura.data +// CTRL2DATA-NEXT: %19 = "neura.phi"(%18, %3) : (!neura.data, !neura.data) -> !neura.data +// CTRL2DATA-NEXT: %20 = "neura.fadd"(%17, %15) : (!neura.data, !neura.data) -> !neura.data +// CTRL2DATA-NEXT: %21 = "neura.add"(%19, %13) : (!neura.data, !neura.data) -> !neura.data +// CTRL2DATA-NEXT: %22 = "neura.icmp"(%21, %11) <{cmpType = "slt"}> : (!neura.data, !neura.data) -> !neura.data +// CTRL2DATA-NEXT: %23 = neura.grant_predicate %21, %22 : !neura.data, !neura.data -> !neura.data +// CTRL2DATA-NEXT: neura.ctrl_mov %23 -> %18 : !neura.data !neura.data +// CTRL2DATA-NEXT: %24 = neura.grant_predicate %20, %22 : !neura.data, !neura.data -> !neura.data +// CTRL2DATA-NEXT: neura.ctrl_mov %24 -> %16 : !neura.data !neura.data +// CTRL2DATA-NEXT: %25 = neura.grant_predicate %7, %22 : !neura.data, !neura.data -> !neura.data +// CTRL2DATA-NEXT: neura.ctrl_mov %25 -> %14 : !neura.data !neura.data +// CTRL2DATA-NEXT: %26 = neura.grant_predicate %5, %22 : !neura.data, !neura.data -> !neura.data +// CTRL2DATA-NEXT: neura.ctrl_mov %26 -> %12 : !neura.data !neura.data +// CTRL2DATA-NEXT: %27 = neura.grant_predicate %1, %22 : !neura.data, !neura.data -> !neura.data +// CTRL2DATA-NEXT: neura.ctrl_mov %27 -> %10 : !neura.data !neura.data +// CTRL2DATA-NEXT: %28 = "neura.not"(%22) : (!neura.data) -> !neura.data +// CTRL2DATA-NEXT: %29 = neura.grant_predicate %20, %28 : !neura.data, !neura.data -> !neura.data +// CTRL2DATA-NEXT: "neura.return"(%29) : (!neura.data) -> () +// CTRL2DATA-NEXT: } + +// FUSE: func.func @loop_test() -> f32 attributes {accelerator = "neura"} { +// FUSE-NEXT: %0 = "neura.grant_once"() <{constant_value = 10 : i64}> : () -> !neura.data +// FUSE-NEXT: %1 = "neura.grant_once"() <{constant_value = 0 : i64}> : () -> !neura.data +// FUSE-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> : () -> !neura.data +// FUSE-NEXT: %3 = "neura.grant_once"() <{constant_value = 3.000000e+00 : f32}> : () -> !neura.data +// FUSE-NEXT: %4 = "neura.grant_once"() <{constant_value = 0.000000e+00 : f32}> : () -> !neura.data +// FUSE-NEXT: %5 = neura.reserve : !neura.data +// FUSE-NEXT: %6 = "neura.phi"(%5, %0) : (!neura.data, !neura.data) -> !neura.data +// FUSE-NEXT: %7 = neura.reserve : !neura.data +// FUSE-NEXT: %8 = "neura.phi"(%7, %2) : (!neura.data, !neura.data) -> !neura.data +// FUSE-NEXT: %9 = neura.reserve : !neura.data +// FUSE-NEXT: %10 = "neura.phi"(%9, %3) : (!neura.data, !neura.data) -> !neura.data +// FUSE-NEXT: %11 = neura.reserve : !neura.data +// FUSE-NEXT: %12 = "neura.phi"(%11, %4) : (!neura.data, !neura.data) -> !neura.data +// FUSE-NEXT: %13 = neura.reserve : !neura.data +// FUSE-NEXT: %14 = "neura.phi"(%13, %1) : (!neura.data, !neura.data) -> !neura.data +// FUSE-NEXT: %15 = "neura.fadd"(%12, %10) : (!neura.data, !neura.data) -> !neura.data +// FUSE-NEXT: %16 = "neura.add"(%14, %8) : (!neura.data, !neura.data) -> !neura.data +// FUSE-NEXT: %17 = "neura.icmp"(%16, %6) <{cmpType = "slt"}> : (!neura.data, !neura.data) -> !neura.data +// FUSE-NEXT: %18 = neura.grant_predicate %16, %17 : !neura.data, !neura.data -> !neura.data +// FUSE-NEXT: neura.ctrl_mov %18 -> %13 : !neura.data !neura.data +// FUSE-NEXT: %19 = neura.grant_predicate %15, %17 : !neura.data, !neura.data -> !neura.data +// FUSE-NEXT: neura.ctrl_mov %19 -> %11 : !neura.data !neura.data +// FUSE-NEXT: %20 = neura.grant_predicate %3, %17 : !neura.data, !neura.data -> !neura.data +// FUSE-NEXT: neura.ctrl_mov %20 -> %9 : !neura.data !neura.data +// FUSE-NEXT: %21 = neura.grant_predicate %2, %17 : !neura.data, !neura.data -> !neura.data +// FUSE-NEXT: neura.ctrl_mov %21 -> %7 : !neura.data !neura.data +// FUSE-NEXT: %22 = neura.grant_predicate %0, %17 : !neura.data, !neura.data -> !neura.data +// FUSE-NEXT: neura.ctrl_mov %22 -> %5 : !neura.data !neura.data +// FUSE-NEXT: %23 = "neura.not"(%17) : (!neura.data) -> !neura.data +// FUSE-NEXT: %24 = neura.grant_predicate %15, %23 : !neura.data, !neura.data -> !neura.data +// FUSE-NEXT: "neura.return"(%24) : (!neura.data) -> () +// FUSE-NEXT: } + +// MOV: func.func @loop_test() -> f32 attributes {accelerator = "neura"} { +// MOV-NEXT: %0 = "neura.grant_once"() <{constant_value = 10 : i64}> : () -> !neura.data +// MOV-NEXT: %1 = "neura.grant_once"() <{constant_value = 0 : i64}> : () -> !neura.data +// MOV-NEXT: %2 = "neura.grant_once"() <{constant_value = 1 : i64}> : () -> !neura.data +// MOV-NEXT: %3 = "neura.grant_once"() <{constant_value = 3.000000e+00 : f32}> : () -> !neura.data +// MOV-NEXT: %4 = "neura.grant_once"() <{constant_value = 0.000000e+00 : f32}> : () -> !neura.data +// MOV-NEXT: %5 = neura.reserve : !neura.data +// MOV-NEXT: %6 = "neura.data_mov"(%0) : (!neura.data) -> !neura.data +// MOV-NEXT: %7 = "neura.phi"(%5, %6) : (!neura.data, !neura.data) -> !neura.data +// MOV-NEXT: %8 = neura.reserve : !neura.data +// MOV-NEXT: %9 = "neura.data_mov"(%2) : (!neura.data) -> !neura.data +// MOV-NEXT: %10 = "neura.phi"(%8, %9) : (!neura.data, !neura.data) -> !neura.data +// MOV-NEXT: %11 = neura.reserve : !neura.data +// MOV-NEXT: %12 = "neura.data_mov"(%3) : (!neura.data) -> !neura.data +// MOV-NEXT: %13 = "neura.phi"(%11, %12) : (!neura.data, !neura.data) -> !neura.data +// MOV-NEXT: %14 = neura.reserve : !neura.data +// MOV-NEXT: %15 = "neura.data_mov"(%4) : (!neura.data) -> !neura.data +// MOV-NEXT: %16 = "neura.phi"(%14, %15) : (!neura.data, !neura.data) -> !neura.data +// MOV-NEXT: %17 = neura.reserve : !neura.data +// MOV-NEXT: %18 = "neura.data_mov"(%1) : (!neura.data) -> !neura.data +// MOV-NEXT: %19 = "neura.phi"(%17, %18) : (!neura.data, !neura.data) -> !neura.data +// MOV-NEXT: %20 = "neura.data_mov"(%16) : (!neura.data) -> !neura.data +// MOV-NEXT: %21 = "neura.data_mov"(%13) : (!neura.data) -> !neura.data +// MOV-NEXT: %22 = "neura.fadd"(%20, %21) : (!neura.data, !neura.data) -> !neura.data +// MOV-NEXT: %23 = "neura.data_mov"(%19) : (!neura.data) -> !neura.data +// MOV-NEXT: %24 = "neura.data_mov"(%10) : (!neura.data) -> !neura.data +// MOV-NEXT: %25 = "neura.add"(%23, %24) : (!neura.data, !neura.data) -> !neura.data +// MOV-NEXT: %26 = "neura.data_mov"(%25) : (!neura.data) -> !neura.data +// MOV-NEXT: %27 = "neura.data_mov"(%7) : (!neura.data) -> !neura.data +// MOV-NEXT: %28 = "neura.icmp"(%26, %27) <{cmpType = "slt"}> : (!neura.data, !neura.data) -> !neura.data +// MOV-NEXT: %29 = "neura.data_mov"(%25) : (!neura.data) -> !neura.data +// MOV-NEXT: %30 = "neura.data_mov"(%28) : (!neura.data) -> !neura.data +// MOV-NEXT: %31 = neura.grant_predicate %29, %30 : !neura.data, !neura.data -> !neura.data +// MOV-NEXT: neura.ctrl_mov %31 -> %17 : !neura.data !neura.data +// MOV-NEXT: %32 = "neura.data_mov"(%22) : (!neura.data) -> !neura.data +// MOV-NEXT: %33 = "neura.data_mov"(%28) : (!neura.data) -> !neura.data +// MOV-NEXT: %34 = neura.grant_predicate %32, %33 : !neura.data, !neura.data -> !neura.data +// MOV-NEXT: neura.ctrl_mov %34 -> %14 : !neura.data !neura.data +// MOV-NEXT: %35 = "neura.data_mov"(%3) : (!neura.data) -> !neura.data +// MOV-NEXT: %36 = "neura.data_mov"(%28) : (!neura.data) -> !neura.data +// MOV-NEXT: %37 = neura.grant_predicate %35, %36 : !neura.data, !neura.data -> !neura.data +// MOV-NEXT: neura.ctrl_mov %37 -> %11 : !neura.data !neura.data +// MOV-NEXT: %38 = "neura.data_mov"(%2) : (!neura.data) -> !neura.data +// MOV-NEXT: %39 = "neura.data_mov"(%28) : (!neura.data) -> !neura.data +// MOV-NEXT: %40 = neura.grant_predicate %38, %39 : !neura.data, !neura.data -> !neura.data +// MOV-NEXT: neura.ctrl_mov %40 -> %8 : !neura.data !neura.data +// MOV-NEXT: %41 = "neura.data_mov"(%0) : (!neura.data) -> !neura.data +// MOV-NEXT: %42 = "neura.data_mov"(%28) : (!neura.data) -> !neura.data +// MOV-NEXT: %43 = neura.grant_predicate %41, %42 : !neura.data, !neura.data -> !neura.data +// MOV-NEXT: neura.ctrl_mov %43 -> %5 : !neura.data !neura.data +// MOV-NEXT: %44 = "neura.data_mov"(%28) : (!neura.data) -> !neura.data +// MOV-NEXT: %45 = "neura.not"(%44) : (!neura.data) -> !neura.data +// MOV-NEXT: %46 = "neura.data_mov"(%22) : (!neura.data) -> !neura.data +// MOV-NEXT: %47 = "neura.data_mov"(%45) : (!neura.data) -> !neura.data +// MOV-NEXT: %48 = neura.grant_predicate %46, %47 : !neura.data, !neura.data -> !neura.data +// MOV-NEXT: %49 = "neura.data_mov"(%48) : (!neura.data) -> !neura.data +// MOV-NEXT: "neura.return"(%49) : (!neura.data) -> () +// MOV-NEXT: } + +// MAPPING: func.func @loop_test() -> f32 attributes {CompiledII = 6 : i32, RecMII = 4 : i32, ResMII = 2 : i32, accelerator = "neura"} { +// 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-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: %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: %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: %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: %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: %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: %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: %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: } + +// INST: "name": "neura.fadd", +// INST-NEXT: "operands": [ +// INST-NEXT: "neura.data_mov", +// INST-NEXT: "neura.data_mov" +// INST-NEXT: ], +// INST-NEXT: "result_types": [ +// INST-NEXT: "!neura.data" +// INST-NEXT: ] \ No newline at end of file diff --git a/test/neura/ctrl/branch_for.mlir b/test/neura/ctrl/branch_for.mlir index bd7e649e..c35211e6 100644 --- a/test/neura/ctrl/branch_for.mlir +++ b/test/neura/ctrl/branch_for.mlir @@ -46,7 +46,7 @@ // RUN: --transform-ctrl-to-data-flow \ // RUN: --fold-constant \ // RUN: --insert-data-mov \ -// RUN: --map-to-accelerator="mapping-strategy=heuristic" \ +// RUN: --map-to-accelerator="mapping-strategy=heuristic backtrack-config=simple" \ // RUN: | FileCheck %s -check-prefix=MAPPING // RUN: mlir-neura-opt %s \ @@ -57,7 +57,7 @@ // RUN: --transform-ctrl-to-data-flow \ // RUN: --fold-constant \ // RUN: --insert-data-mov \ -// RUN: --map-to-accelerator="mapping-strategy=heuristic" \ +// RUN: --map-to-accelerator="mapping-strategy=heuristic backtrack-config=simple" \ // RUN: --generate-code // RUN: FileCheck %s --input-file=generated-instructions.json -check-prefix=INST @@ -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 {CompiledII = 5 : i32, RecMII = 4 : i32, ResMII = 2 : i32, accelerator = "neura"} { -// MAPPING-NEXT: %0 = "neura.grant_once"() <{constant_value = 10 : i64}> {mapping_locs = [{id = 8 : i32, resource = "tile", time_step = 1 : i32, x = 0 : i32, y = 2 : i32}]} : () -> !neura.data -// MAPPING-NEXT: %1 = "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 -// 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: func.func @loop_test() -> f32 attributes {CompiledII = 6 : i32, RecMII = 4 : i32, ResMII = 2 : i32, accelerator = "neura"} { +// 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 = 8 : i32, resource = "tile", time_step = 2 : i32, x = 0 : i32, y = 2 : 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-NEXT: %5 = neura.reserve : !neura.data -// MAPPING-NEXT: %6 = "neura.data_mov"(%0) {mapping_locs = [{id = 24 : i32, resource = "link", time_step = 1 : i32}, {id = 36 : i32, resource = "register", time_step = 2 : i32}]} : (!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: %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: %8 = neura.reserve : !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: %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: %11 = neura.reserve : !neura.data -// MAPPING-NEXT: %12 = "neura.data_mov"(%3) {mapping_locs = [{id = 10 : 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: %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: %14 = neura.reserve : !neura.data -// MAPPING-NEXT: %15 = "neura.data_mov"(%4) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %16 = "neura.phi"(%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 +// 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: %17 = neura.reserve : !neura.data -// MAPPING-NEXT: %18 = "neura.data_mov"(%1) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %19 = "neura.phi"(%17, %18) {mapping_locs = [{id = 11 : i32, resource = "tile", time_step = 1 : i32, x = 3 : i32, y = 2 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %20 = "neura.data_mov"(%16) {mapping_locs = [{id = 25 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %21 = "neura.data_mov"(%13) {mapping_locs = [{id = 13 : i32, resource = "link", time_step = 3 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %22 = "neura.fadd"(%20, %21) {mapping_locs = [{id = 4 : i32, resource = "tile", time_step = 4 : i32, x = 0 : i32, y = 1 : i32}]} : (!neura.data, !neura.data) -> !neura.data -// MAPPING-NEXT: %23 = "neura.data_mov"(%19) {mapping_locs = [{id = 35 : i32, resource = "link", time_step = 1 : i32}, {id = 40 : i32, resource = "register", time_step = 2 : i32}]} : (!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: %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: %26 = "neura.data_mov"(%25) {mapping_locs = []} : (!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: %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: %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 = 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 = [{id = 32 : i32, resource = "link", time_step = 5 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %32 = "neura.data_mov"(%22) {mapping_locs = [{id = 12 : i32, resource = "link", time_step = 4 : i32}, {id = 26 : i32, resource = "link", time_step = 5 : i32}, {id = 48 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %33 = "neura.data_mov"(%28) {mapping_locs = [{id = 34 : i32, resource = "link", time_step = 4 : i32}, {id = 43 : i32, resource = "link", time_step = 5 : i32}, {id = 40 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %34 = neura.grant_predicate %32, %33 {mapping_locs = [{id = 12 : i32, resource = "tile", time_step = 7 : i32, x = 0 : i32, y = 3 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %34 -> %14 {mapping_locs = [{id = 39 : i32, resource = "link", time_step = 7 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %35 = "neura.data_mov"(%3) {mapping_locs = [{id = 11 : i32, resource = "link", time_step = 2 : i32}, {id = 0 : i32, resource = "link", time_step = 3 : i32}, {id = 3 : i32, resource = "link", time_step = 4 : i32}, {id = 7 : i32, resource = "link", time_step = 5 : i32}, {id = 24 : i32, resource = "register", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %36 = "neura.data_mov"(%28) {mapping_locs = [{id = 32 : i32, resource = "link", time_step = 4 : i32}, {id = 36 : i32, resource = "link", time_step = 5 : i32}, {id = 21 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %37 = neura.grant_predicate %35, %36 {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 7 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %37 -> %11 {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 7 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %38 = "neura.data_mov"(%2) {mapping_locs = [{id = 28 : i32, resource = "link", time_step = 0 : i32}, {id = 41 : i32, resource = "register", time_step = 1 : i32}, {id = 41 : i32, resource = "register", time_step = 2 : i32}, {id = 41 : i32, resource = "register", time_step = 3 : i32}, {id = 41 : i32, resource = "register", time_step = 4 : i32}, {id = 41 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %39 = "neura.data_mov"(%28) {mapping_locs = []} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %40 = neura.grant_predicate %38, %39 {mapping_locs = [{id = 10 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 2 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: neura.ctrl_mov %40 -> %8 {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 6 : i32}]} : !neura.data !neura.data -// MAPPING-NEXT: %41 = "neura.data_mov"(%0) {mapping_locs = [{id = 26 : i32, resource = "link", time_step = 1 : i32}, {id = 38 : i32, resource = "link", time_step = 2 : i32}, {id = 42 : i32, resource = "link", time_step = 3 : i32}, {id = 36 : i32, resource = "register", time_step = 4 : i32}, {id = 36 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %42 = "neura.data_mov"(%28) {mapping_locs = [{id = 31 : i32, resource = "link", time_step = 4 : i32}, {id = 37 : i32, resource = "register", time_step = 5 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %43 = neura.grant_predicate %41, %42 {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: neura.ctrl_mov %43 -> %5 {mapping_locs = []} : !neura.data !neura.data -// MAPPING-NEXT: %44 = "neura.data_mov"(%28) {mapping_locs = [{id = 33 : i32, resource = "link", time_step = 4 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %45 = "neura.not"(%44) {mapping_locs = [{id = 6 : i32, resource = "tile", time_step = 5 : i32, x = 2 : i32, y = 1 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: %46 = "neura.data_mov"(%22) {mapping_locs = [{id = 10 : i32, resource = "link", time_step = 4 : i32}, {id = 14 : 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 = 6 : i32, resource = "tile", time_step = 6 : i32, x = 2 : i32, y = 1 : i32}]} : !neura.data, !neura.data -> !neura.data -// MAPPING-NEXT: %49 = "neura.data_mov"(%48) {mapping_locs = [{id = 17 : i32, resource = "link", time_step = 6 : i32}]} : (!neura.data) -> !neura.data -// MAPPING-NEXT: "neura.return"(%49) {mapping_locs = [{id = 5 : i32, resource = "tile", time_step = 7 : i32, x = 1 : i32, y = 1 : i32}]} : (!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: %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: } // INST: "name": "neura.fadd",