CGRA-ME
CompositeMappers.cpp
Go to the documentation of this file.
1 #include <CGRA/Mapper.h>
2 
3 #include <future>
4 
7  static constexpr const char* mapper_name = "BothSmallTimeThenHeurFullTime";
8 
9  ConfigStore untouched_args; //< passed through to the mappers
10  ConfigStore args; //< local use
11 
15  BothSmallTimeThenHeurFullTime(std::shared_ptr<CGRA> cgra, int timelimit, const ConfigStore& args)
17  { }
18 
24  , untouched_args(std::move(untouched_args))
25  , args(std::move(args))
26  { }
27 
28  template<typename T>
29  void printStatus(const T& msg) const {
30  if (args.getInt("verbosity") > 0) {
31  std::cout << mapper_name << "mapper: " << msg << '\n';
32  }
33  }
34 
35  Mapping mapOpGraph(std::shared_ptr<OpGraph> opgraph, int II, const MRRG& mrrg, std::unordered_map<std::string, std::string> fix_port) override {
36  return mapOpGraph_internal(opgraph, II, mrrg, fix_port);
37  }
38 
39  Mapping mapOpGraph_internal(std::shared_ptr<OpGraph> opgraph, int II, const MRRG& mrrg, std::unordered_map<std::string, std::string> fix_port) const {
40  // The idea is to simulate being able to stop one mapper or the other before it takes too long.
41  // Unfortunately, there is currently no support for some sort of stop token, (async or otherwise)
42  // so first run them with a short time limit, then the full one.
43  // TODO: share caches between HeurILP runs
44 
45  struct Times {
46  long heur, ilp;
47  long heur_wait;
48  };
49 
50  double last_solve_time = -1;
51 
52  int ilp_mapper_seed = args.getInt("seed");
53 
54  const auto advance_ilp_mapper_seed = [&] { ilp_mapper_seed += 1; };
55 
56  for (const auto& timeouts : {
57  Times{std::min<long>(args.getInt("initial_timeout"),timelimit), std::min<long>(args.getInt("initial_timeout"),timelimit), args.getInt("initial_heur_wait")},
58  Times{timelimit, std::min<long>(args.getInt("secondary_limit"),timelimit), 0L},
59  }) {
60  const auto ilp_mapper_computed_options = [&] {
61  ConfigStore result;
62  result.setInt("ILPMapper.seed", ilp_mapper_seed);
63  return result;
64  };
65 
66  const auto heur_mapper_computed_options = [&] {
67  ConfigStore result;
68  return result;
69  };
70 
71  printStatus("Staring the ILPMapper");
72  auto ilp_future = std::async(std::launch::async, [&]() {
74  "ILPMapper", cgra, timeouts.ilp, with_set(untouched_args, ilp_mapper_computed_options()));
75  return ilp_mapper->mapOpGraph(opgraph, II, mrrg, fix_port);
76  });
77 
78  if (args.getInt("max_threads") < 2) { ilp_future.wait(); }
79 
80  if (timeouts.heur_wait > 0 && ilp_future.wait_for(std::chrono::seconds(timeouts.heur_wait)) == std::future_status::ready) {
81  printStatus("ILPMapper completed quickly!");
82  auto ilp_mapping = ilp_future.get();
83  switch (analyzeILPMapping(ilp_mapping, mrrg)) {
84  case ILPMapperAnalysisResult::return_mapping: printStatus("Using ILPMapper result"); return ilp_mapping;
85  case ILPMapperAnalysisResult::advance_seed: printStatus("ILPMapper mapping unusable"); advance_ilp_mapper_seed(); break;
86  default: [[fallthrough]];
87  case ILPMapperAnalysisResult::ignore_mapping: printStatus("ILPMapper failed/mapping not used"); break;
88  }
89  }
90 
91  printStatus("Starting the ILPHeuristicMapper");
92  auto heur_future = std::async(std::launch::async, [&]() {
94  "ILPHeuristicMapper", cgra, timeouts.heur - timeouts.heur_wait, with_set(untouched_args, heur_mapper_computed_options()));
95  return heur_mapper->mapOpGraph(opgraph, II, mrrg, fix_port);
96  });
97 
98  auto heur_mapping = heur_future.get();
99  if (heur_mapping.isMapped()) {
100  printStatus("Using successful ILPHeuristicMapper mapping");
101  return heur_mapping;
102  }
103 
104  // possibly examine the ILPMapper result
105  if (ilp_future.valid()) { // only if the future is not consumed
106  auto ilp_mapping = ilp_future.get();
107  switch (analyzeILPMapping(ilp_mapping, mrrg)) {
108  case ILPMapperAnalysisResult::return_mapping: printStatus("Using ILPMapper result"); return ilp_mapping;
109  case ILPMapperAnalysisResult::advance_seed: printStatus("ILPMapper mapping unusable"); advance_ilp_mapper_seed(); break;
110  default: [[fallthrough]];
111  case ILPMapperAnalysisResult::ignore_mapping: printStatus("ILPMapper failed/mapping not used"); break;
112  }
113  }
114 
115  if (not heur_mapping.isTimeout()) {
116  printStatus("Everything returned failure without timing out, giving up");
117  return heur_mapping;
118  }
119 
120  last_solve_time = heur_mapping.solve_time_in_seconds;
121  }
122 
123  printStatus("Schedule ended, returning failure");
124  auto failure_result = Mapping(cgra, II, opgraph);
125  failure_result.solve_time_in_seconds = last_solve_time;
126  return failure_result;
127  }
128 
131  advance_seed,
133  };
134 
135  static ILPMapperAnalysisResult analyzeILPMapping(const Mapping& ilp_mapping, const MRRG& mrrg) {
136  switch (ilp_mapping.getStatus()) {
138  if (mappingIsOK(ilp_mapping, mrrg)) {
140  } else {
141  return ILPMapperAnalysisResult::advance_seed; // try to get lucky
142  }
144  return ILPMapperAnalysisResult::return_mapping; // return failure, must be impossible to map
145  default: [[fallthrough]];
148  }
149  }
150 
154  static bool mappingIsOK(const Mapping& mapping, const MRRG& mrrg) {
155  const auto create_mapping_graph_result = createMappingGraph(mrrg, mapping);
156  const auto final_mapping_graph = removeIsolatedRoutingNodes(create_mapping_graph_result.mg, mrrg, create_mapping_graph_result.toMRRG);
157  const auto latency_check_result = latencyCheck(final_mapping_graph, mrrg, create_mapping_graph_result.toMRRG);
158  return latency_check_result.first;
159  }
160 };
161 
164  [](std::shared_ptr<CGRA> cgra, int timelimit, const ConfigStore& args) {
165  return std::make_unique<BothSmallTimeThenHeurFullTime>(cgra, timelimit, args);
166  },
167  true, // is a composite
168  "In parallel, runs both ILPHeuristicMapper and ILPMapper with a short timeout, "
169  "then ILPHeuristicMapper with the full timeout while running ILPMapper with a capped timeout. "
170  "Any successful & correct mapping is returned",
171  { // required args
172  {"seed", 0, ""},
173  {"verbosity", 0, ""},
174  {"max_threads", 2, ""},
175  {"initial_timeout", 25, "Max time of the first iteration"},
176  {"initial_heur_wait", 10,
177  "The first run of ILPHeuristicMapper will be launched this many seconds after ILPMapper\n"
178  "The point is to try to avoid the cache warm-up if possible, as that takes a while, and isn't included in the timeout."
179  "(cache warm-up can easily take tens of seconds)"
180  },
181  {"secondary_limit", 3*60, "Time limit applied to second run of ILPMapper"},
182  },
183  { // optional arg regexes
184  }
185 );
removeIsolatedRoutingNodes
MappingGraph removeIsolatedRoutingNodes(const MappingGraph &mapping, const MRRG &mrrg, const MappingGraph::ToMRRGVertexMap &toMRRG)
Definition: Mapping.cpp:504
BothSmallTimeThenHeurFullTime::BothSmallTimeThenHeurFullTime
BothSmallTimeThenHeurFullTime(std::shared_ptr< CGRA > cgra, int timelimit, const ConfigStore &args)
Definition: CompositeMappers.cpp:15
MRRG
Definition: MRRG.h:216
BothSmallTimeThenHeurFullTime::args
ConfigStore args
Definition: CompositeMappers.cpp:10
BothSmallTimeThenHeurFullTime::ILPMapperAnalysisResult::ignore_mapping
@ ignore_mapping
ConfigStore::setInt
void setInt(std::string key, long long value)
Definition: ConfigStore.h:129
AutoRegisterMapper
Special helper for registering mappers to the default mapper registry.
Definition: Mapper.h:200
ConfigStore
Definition: ConfigStore.h:76
Mapping::getStatus
MappingStatus getStatus() const
Definition: Mapping.h:39
BothSmallTimeThenHeurFullTime::mapOpGraph_internal
Mapping mapOpGraph_internal(std::shared_ptr< OpGraph > opgraph, int II, const MRRG &mrrg, std::unordered_map< std::string, std::string > fix_port) const
Definition: CompositeMappers.cpp:39
Mapper
Common interface for mappers.
Definition: Mapper.h:28
latencyCheck
std::pair< bool, MappingGraphCycleAssignment > latencyCheck(const MappingGraph &mapping, const MRRG &mrrg, const CreateMappingGraphResult::ToMRRG &toMRRG)
Definition: Mapping.cpp:582
BothSmallTimeThenHeurFullTime::BothSmallTimeThenHeurFullTime
BothSmallTimeThenHeurFullTime(std::shared_ptr< CGRA > cgra, int timelimit, ConfigStore untouched_args, ConfigStore args)
Definition: CompositeMappers.cpp:22
BothSmallTimeThenHeurFullTime
Definition: CompositeMappers.cpp:5
BothSmallTimeThenHeurFullTime::mapper_name
static constexpr const char * mapper_name
Definition: CompositeMappers.cpp:7
Mapping
Definition: Mapping.h:31
BothSmallTimeThenHeurFullTime::ILPMapperAnalysisResult::return_mapping
@ return_mapping
MappingStatus::timeout
@ timeout
BothSmallTimeThenHeurFullTime::untouched_args
ConfigStore untouched_args
Definition: CompositeMappers.cpp:9
MappingStatus::failure
@ failure
BothSmallTimeThenHeurFullTime::printStatus
void printStatus(const T &msg) const
Definition: CompositeMappers.cpp:29
AutoRegisterMapper::getDefaultRegistry
static const MapperRegistry & getDefaultRegistry()
Public read-only access to the mapper registry that this class automatically adds mappers to.
Definition: Mapper.h:214
BothSmallTimeThenHeurFullTime::mapOpGraph
Mapping mapOpGraph(std::shared_ptr< OpGraph > opgraph, int II, const MRRG &mrrg, std::unordered_map< std::string, std::string > fix_port) override
Definition: CompositeMappers.cpp:35
Mapper::cgra
std::shared_ptr< CGRA > cgra
Definition: Mapper.h:45
BothSmallTimeThenHeurFullTime::analyzeILPMapping
static ILPMapperAnalysisResult analyzeILPMapping(const Mapping &ilp_mapping, const MRRG &mrrg)
Definition: CompositeMappers.cpp:135
BothSmallTimeThenHeurFullTime::ILPMapperAnalysisResult
ILPMapperAnalysisResult
Definition: CompositeMappers.cpp:129
with_set
ConfigStore with_set(ConfigStore into, const ConfigStore &from1, const CSes &... froms)
Definition: ConfigStore.h:279
BothSmallTimeThenHeurFullTime::arm
static AutoRegisterMapper arm
Definition: CompositeMappers.cpp:6
MappingStatus::success
@ success
BothSmallTimeThenHeurFullTime::ILPMapperAnalysisResult::advance_seed
@ advance_seed
Mapper.h
createMappingGraph
CreateMappingGraphResult createMappingGraph(const MRRG &mrrg, const Mapping &m)
Definition: Mapping.cpp:468
getEntriesForPrefix
ConfigStore getEntriesForPrefix(const ConfigStore &cs, const std::string &prefix)
Definition: ConfigStore.h:285
MapperRegistry::createMapper
std::unique_ptr< Mapper > createMapper(const std::string &mapper_id, std::shared_ptr< CGRA > cgra, int timelimit, const ConfigStore &args) const
Given a mapper_id, create an instance of that mapper with the given arguments.
Definition: Mapper.cpp:36
BothSmallTimeThenHeurFullTime::mappingIsOK
static bool mappingIsOK(const Mapping &mapping, const MRRG &mrrg)
Checks latency balancing. Only needed for the ILP mapper.
Definition: CompositeMappers.cpp:154
ConfigStore::getInt
long long getInt(const std::string &key) const
Definition: ConfigStore.h:146
Mapper::timelimit
int timelimit
Definition: Mapper.h:46