| 226 | bool program::is_compiled() const { return not this->impl->contexts.empty(); } |
| 227 | |
| 228 | void program::compile(const std::vector<target>& targets, std::vector<compile_options> compile_opts) |
| 229 | { |
| 230 | // Gather all the target roots |
| 231 | std::unordered_multimap<std::size_t, module_ref> roots; |
| 232 | auto mods = this->get_modules(); |
| 233 | for(const auto* mod : mods) |
| 234 | { |
| 235 | for(const auto& ins : *mod) |
| 236 | { |
| 237 | if(ins.name() != "run_on_target") |
| 238 | continue; |
| 239 | auto v = ins.get_operator().to_value(); |
| 240 | module_ref root = ins.module_inputs().front(); |
| 241 | std::size_t root_target_id = v.at("target_id").to<std::size_t>(); |
| 242 | assert(root_target_id < targets.size()); |
| 243 | roots.insert({root_target_id, root}); |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | auto trace = tracer{}; |
| 248 | // TODO: Add tracer based on compile options |
| 249 | if(enabled(MIGRAPHX_TRACE_COMPILE{})) |
| 250 | trace = tracer{std::cout}; |
| 251 | |
| 252 | trace(*this); |
| 253 | trace(); |
| 254 | // It is assumed that all instructions outside of any root module would run on "ref" target |
| 255 | // Ref target may or may not be passed as one of the target for the "compile()". |
| 256 | // If it is not passed, Create one and add context of it into the map. |
| 257 | auto target_idx = [&](const std::string& t_name) { |
| 258 | return static_cast<std::size_t>( |
| 259 | std::find_if( |
| 260 | targets.begin(), targets.end(), [&](const auto& t) { return t.name() == t_name; }) - |
| 261 | targets.begin()); |
| 262 | }; |
| 263 | |
| 264 | std::size_t ref_target_id = target_idx("ref"); |
| 265 | if(ref_target_id == targets.size()) |
| 266 | { |
| 267 | this->impl->contexts.resize(targets.size() + 1); |
| 268 | this->impl->contexts[ref_target_id] = migraphx::make_target("ref").get_context(); |
| 269 | // users could pass lessers compile_ops than targets, in that case use default compile_opts |
| 270 | compile_opts.resize(targets.size() + 1, migraphx::compile_options{}); |
| 271 | } |
| 272 | else |
| 273 | { |
| 274 | this->impl->contexts.resize(targets.size()); |
| 275 | compile_opts.resize(targets.size(), migraphx::compile_options{}); |
| 276 | } |
| 277 | // mark all the instruction as ref target first, later change target_id based on root-target |
| 278 | run_passes(*this, {mark_instruction_target{ref_target_id}}); |
| 279 | |
| 280 | // Run passes on each root target |
| 281 | for(const auto i : range(targets.size())) |
| 282 | { |
| 283 | const auto& root_target = targets.at(i); |
| 284 | auto root_target_id = i; |
| 285 | auto root_modules_range = roots.equal_range(root_target_id); |
no test coverage detected