Unverified Commit fdaa21ee authored by Paul Fultz II's avatar Paul Fultz II Committed by GitHub
Browse files

Improve check_context to handle submodules better (#927)



Improve check_context to handle submodules better
Co-authored-by: default avatarShucai Xiao <shucai@gmail.com>
parent ac0f79aa
...@@ -184,12 +184,13 @@ std::vector<argument> generic_eval(const module* mod, ...@@ -184,12 +184,13 @@ std::vector<argument> generic_eval(const module* mod,
context& ctx, context& ctx,
std::unordered_map<std::string, argument> params, std::unordered_map<std::string, argument> params,
std::unordered_map<instruction_ref, argument> results, std::unordered_map<instruction_ref, argument> results,
F trace) F make_trace)
{ {
assert(mod->validate() == mod->end()); assert(mod->validate() == mod->end());
results.reserve(mod->size() * 2); results.reserve(mod->size() * 2);
std::vector<argument> values; std::vector<argument> values;
values.reserve(16); values.reserve(16);
auto trace = make_trace(mod);
for(auto ins : iterator_for(*mod)) for(auto ins : iterator_for(*mod))
{ {
const auto& name = ins->name(); const auto& name = ins->name();
...@@ -240,7 +241,7 @@ std::vector<argument> generic_eval(const module* mod, ...@@ -240,7 +241,7 @@ std::vector<argument> generic_eval(const module* mod,
const auto& mod_args = ins->module_inputs(); const auto& mod_args = ins->module_inputs();
auto module_eval = [&](module_ref smod, auto module_eval = [&](module_ref smod,
const std::unordered_map<std::string, argument>& inputs) { const std::unordered_map<std::string, argument>& inputs) {
return generic_eval(smod, ctx, inputs, results, trace); return generic_eval(smod, ctx, inputs, results, make_trace);
}; };
results.emplace(ins, trace(ins, [&] { results.emplace(ins, trace(ins, [&] {
...@@ -257,32 +258,44 @@ template <class F> ...@@ -257,32 +258,44 @@ template <class F>
std::vector<argument> generic_eval(const program& p, std::vector<argument> generic_eval(const program& p,
context& ctx, context& ctx,
std::unordered_map<std::string, argument> params, std::unordered_map<std::string, argument> params,
F trace) F make_trace)
{ {
const module* mm = p.get_main_module(); const module* mm = p.get_main_module();
return generic_eval(mm, ctx, params, {}, trace); return generic_eval(mm, ctx, params, {}, make_trace);
} }
std::vector<argument> program::eval(parameter_map params) const std::vector<argument> program::eval(parameter_map params) const
{ {
auto& ctx = this->impl->ctx; auto& ctx = this->impl->ctx;
#ifndef NDEBUG #ifndef NDEBUG
auto sctx = ctx; auto with_check_context = [&](auto f) {
auto check_context = [&](auto f) { return [=, &ctx](auto&&) {
assert(is_shared(ctx, sctx)); auto sctx = std::make_shared<context>(ctx);
auto x = f(); auto check_context = [=, &ctx](auto g) {
sctx = ctx; assert(is_shared(ctx, *sctx));
auto x = g();
*sctx = ctx;
return x; return x;
}; };
return [=](auto&&... xs) { return f(xs..., check_context); };
};
};
#else #else
auto check_context = [](auto f) { return f(); }; auto with_check_context = [](auto f) {
return [=](auto&&) {
return [=](auto&&... xs) { return f(xs..., [](auto g) { return g(); }); };
};
};
#endif #endif
auto trace_level = value_of(MIGRAPHX_TRACE_EVAL{}); auto trace_level = value_of(MIGRAPHX_TRACE_EVAL{});
if(trace_level > 0) if(trace_level > 0)
{ {
return generic_eval(*this, ctx, std::move(params), [&](auto& ins, auto f) { return generic_eval(*this,
ctx,
std::move(params),
with_check_context([&](auto& ins, auto f, auto&& check_context) {
ctx.finish(); ctx.finish();
std::cout << "Run instruction: "; std::cout << "Run instruction: ";
this->debug_print(ins); this->debug_print(ins);
...@@ -292,15 +305,20 @@ std::vector<argument> program::eval(parameter_map params) const ...@@ -292,15 +305,20 @@ std::vector<argument> program::eval(parameter_map params) const
ctx.finish(); ctx.finish();
double t2 = t.record<milliseconds>(); double t2 = t.record<milliseconds>();
std::cout << "Time: " << t1 << "ms, " << t2 << "ms" << std::endl; std::cout << "Time: " << t1 << "ms, " << t2 << "ms" << std::endl;
if(trace_level > 1 and ins->name().front() != '@' and ins->name() != "load") if(trace_level > 1 and ins->name().front() != '@' and
ins->name() != "load")
std::cout << "Output: " << result << std::endl; std::cout << "Output: " << result << std::endl;
return result; return result;
}); }));
} }
else else
{ {
return generic_eval( return generic_eval(*this,
*this, ctx, std::move(params), [&](auto&, auto f) { return check_context(f); }); ctx,
std::move(params),
with_check_context([&](auto&, auto f, auto&& check_context) {
return check_context(f);
}));
} }
} }
...@@ -502,21 +520,21 @@ void program::perf_report(std::ostream& os, std::size_t n, parameter_map params) ...@@ -502,21 +520,21 @@ void program::perf_report(std::ostream& os, std::size_t n, parameter_map params)
std::sort(total_vec.begin(), total_vec.end()); std::sort(total_vec.begin(), total_vec.end());
std::unordered_map<instruction_ref, std::vector<double>> ins_vec; std::unordered_map<instruction_ref, std::vector<double>> ins_vec;
// Fill the map // Fill the map
generic_eval(*this, ctx, params, [&](auto ins, auto) { generic_eval(*this, ctx, params, always([&](auto ins, auto) {
ins_vec[ins].reserve(n); ins_vec[ins].reserve(n);
return argument{}; return argument{};
}); }));
// Run and time each instruction // Run and time each instruction
for(std::size_t i = 0; i < n; i++) for(std::size_t i = 0; i < n; i++)
{ {
generic_eval(*this, ctx, params, [&](auto ins, auto f) { generic_eval(*this, ctx, params, always([&](auto ins, auto f) {
argument result; argument result;
ins_vec[ins].push_back(time<milliseconds>([&] { ins_vec[ins].push_back(time<milliseconds>([&] {
result = f(); result = f();
ctx.finish(); ctx.finish();
})); }));
return result; return result;
}); }));
} }
for(auto&& p : ins_vec) for(auto&& p : ins_vec)
std::sort(p.second.begin(), p.second.end()); std::sort(p.second.begin(), p.second.end());
...@@ -645,7 +663,7 @@ void program::print_cpp(std::ostream& os) const ...@@ -645,7 +663,7 @@ void program::print_cpp(std::ostream& os) const
void program::dry_run(std::unordered_map<std::string, argument> params) const void program::dry_run(std::unordered_map<std::string, argument> params) const
{ {
auto& ctx = this->impl->ctx; auto& ctx = this->impl->ctx;
generic_eval(*this, ctx, std::move(params), [](auto&&...) { return argument{}; }); generic_eval(*this, ctx, std::move(params), always([](auto&&...) { return argument{}; }));
} }
void program::annotate(std::ostream& os, const std::function<void(instruction_ref)>& a) const void program::annotate(std::ostream& os, const std::function<void(instruction_ref)>& a) const
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment