Skip to content

Commit

Permalink
Show mlir program when tracing benchmarking (#2741)
Browse files Browse the repository at this point in the history
  • Loading branch information
pfultz2 authored Jun 18, 2024
1 parent 2c4dd4a commit 5a0cf97
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 28 deletions.
1 change: 1 addition & 0 deletions docs/dev/env_vars.rst
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ Defaults to 1.

Set to "1" to print benchmarking trace.
Set to "2" to print detailed benchmarking trace.
Set to "3" to print compiled traces.

MLIR vars
-------------
Expand Down
33 changes: 26 additions & 7 deletions src/targets/gpu/compile_ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ struct compiled_result
{
compiler_replace replace;
instruction_ref ins;

friend std::ostream& operator<<(std::ostream& os, const compiled_result& cr)
{
cr.replace.trace(os, cr.ins);
return os;
}
};

struct compile_plan
Expand Down Expand Up @@ -153,22 +159,33 @@ struct compile_plan
insert_compiles(compiles, value{}, 0);
}
}
std::string problem_string() const
{
if(config)
return to_string(config->problem);
return "<no problem key>";
}

const compiled_result& benchmark() const
{
const auto trace_level = value_of(MIGRAPHX_TRACE_BENCHMARKING{});
if(trace_level > 0 and not results.empty())
{
std::cout << "Benchmarking " << preop.name() << ": " << results.size() << " configs"
<< std::endl;
}
if(results.empty())
MIGRAPHX_THROW("No configs to tune");
MIGRAPHX_THROW("No valid tuned compilation for " + preop.name() + " with " +
problem_string());
if(results.size() == 1)
{
if(not results.front().has_value())
MIGRAPHX_THROW("No configs to tune");
MIGRAPHX_THROW("No valid tuned compilation for " + preop.name() + " with " +
problem_string());
return *results.front();
}
if(not config)
MIGRAPHX_THROW("Multiple kernels without config");
if(trace_level > 0)
std::cout << "Benchmarking " << preop.name() << ": " << results.size() << " configs"
<< std::endl;
MIGRAPHX_THROW("Multiple kernels without config for " + preop.name());
if(trace_level > 1)
std::cout << "Problem: " << config->problem << std::endl;
std::vector<double> times;
Expand All @@ -186,6 +203,8 @@ struct compile_plan
std::cout << "No binary" << std::endl;
return std::numeric_limits<double>::max();
}
if(trace_level > 2)
std::cout << *cr << std::endl;
/*
create a small program with insturction being compiled and call "replace"
on that which would insert all the compiled code objects, prefills etc.
Expand Down Expand Up @@ -220,7 +239,7 @@ struct compile_plan
ctx->get_problem_cache().insert(preop.name(), config->problem, config->solutions.at(i));
if(not results[i].has_value())
MIGRAPHX_THROW("No valid tuned compilation for " + preop.name() + " with " +
to_string(config->problem));
problem_string());
auto skipped = std::count_if(
results.begin(), results.end(), [](const auto& cr) { return not cr.has_value(); });
if(skipped > 0)
Expand Down
46 changes: 37 additions & 9 deletions src/targets/gpu/include/migraphx/gpu/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,48 @@ struct compiler_replace
compiler_replace(const operation& op) : code_objects{{op}} {}

template <class F>
compiler_replace(const operation& op, F f)
: code_objects{{op}},
replace_fn([=](const compiler_replace& cr, module& m, instruction_ref ins) {
f(m, ins, cr.code_objects.front());
})
compiler_replace(const operation& op, F f) : code_objects{{op}}, replace_fn(make_replace(f))
{
}

template <class F, class Trace>
compiler_replace(const operation& op, F f, Trace t)
: code_objects{{op}}, replace_fn(make_replace(f)), trace_fn(t)
{
}

template <class F>
compiler_replace(const std::vector<operation>& op, F f)
: code_objects{op},
replace_fn([=](const compiler_replace& cr, module& m, instruction_ref ins) {
f(m, ins, cr.code_objects);
})
: code_objects{op}, replace_fn(make_replace_all(f))
{
}

template <class F, class Trace>
compiler_replace(const std::vector<operation>& op, F f, Trace t)
: code_objects{op}, replace_fn(make_replace_all(f)), trace_fn(t)
{
}

std::vector<operation> code_objects = {};
std::function<void(const compiler_replace& cr, module& m, instruction_ref ins)> replace_fn =
nullptr;
std::function<void(std::ostream& os, instruction_ref ins)> trace_fn = nullptr;

template <class F>
static auto make_replace(F f)
{
return [=](const compiler_replace& cr, module& m, instruction_ref ins) {
f(m, ins, cr.code_objects.front());
};
}

template <class F>
static auto make_replace_all(F f)
{
return [=](const compiler_replace& cr, module& m, instruction_ref ins) {
f(m, ins, cr.code_objects);
};
}

void replace(module& m, instruction_ref ins) const
{
Expand All @@ -82,6 +104,12 @@ struct compiler_replace
m.replace_instruction(ins, code_objects.front(), ins->inputs());
}
}

void trace(std::ostream& os, instruction_ref ins) const
{
if(trace_fn)
trace_fn(os, ins);
}
};

using compiler_compile =
Expand Down
1 change: 1 addition & 0 deletions src/targets/gpu/include/migraphx/gpu/mlir.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct module;
namespace gpu {

MIGRAPHX_GPU_EXPORT std::string dump_mlir(const module& m);
MIGRAPHX_GPU_EXPORT std::string dump_mlir(const module& m, const std::vector<shape>& inputs);

MIGRAPHX_GPU_EXPORT bool
is_module_fusible(const module& m, const context& migraphx_ctx, const value& solution);
Expand Down
10 changes: 9 additions & 1 deletion src/targets/gpu/jit/mlir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ struct mlir_compiler : compiler<mlir_compiler>
}
auto mlir = insert_mlir(m, ins, any_cast<code_object_op>(ops.front()), inputs);
return m.replace_instruction(ins, mlir);
}};
},
&trace};
}

compiler_replace insert(const std::vector<mlir_code_object>& mcos,
Expand Down Expand Up @@ -202,6 +203,13 @@ struct mlir_compiler : compiler<mlir_compiler>
auto* smod = ins->module_inputs().front();
return get_tuning_config_mlir(ctx, *smod, shapes, exhaustive);
}

static void trace(std::ostream& os, instruction_ref ins)
{
auto shapes = to_shapes(ins->inputs());
auto* smod = ins->module_inputs().front();
os << dump_mlir(*smod, shapes);
}
};

} // namespace gpu
Expand Down
41 changes: 30 additions & 11 deletions src/targets/gpu/mlir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,14 +956,6 @@ bool is_module_fusible(const module& m, const context& migraphx_ctx, const value
return mlirIsModuleFusible(mp.mmodule.get(), make_mlir_string_ref(*solution.if_string()));
}

std::string dump_mlir(const module& m)
{
mlir_program mp;
mp.parse(m);
auto mod_op = mlirModuleGetOperation(mp.mmodule.get());
return mlir_print(&mlirOperationPrint, mod_op);
}

void adjust_param_shapes(module& m, const std::vector<shape>& inputs)
{
auto names = m.get_parameter_names();
Expand All @@ -982,6 +974,24 @@ void adjust_param_shapes(module& m, const std::vector<shape>& inputs)
}
}

std::string dump_mlir(const module& m, const std::vector<shape>& inputs)
{
module mm;
const_module_ref mr = &m;
if(not inputs.empty())
{
mm = m;
mr = &mm;
adjust_param_shapes(mm, inputs);
}
mlir_program mp;
mp.parse(*mr);
auto mod_op = mlirModuleGetOperation(mp.mmodule.get());
return mlir_print(&mlirOperationPrint, mod_op);
}

std::string dump_mlir(const module& m) { return dump_mlir(m, {}); }

mlir_code_object compile_mlir(const context& migraphx_ctx,
module m,
const std::vector<shape>& in_shapes,
Expand Down Expand Up @@ -1063,27 +1073,36 @@ tuning_config get_tuning_config_mlir(const context& migraphx_ctx,
mlir_program mp;
mp.set_gpu_properties(migraphx_ctx);
mp.parse(m);
auto tc = mp.get_tuning_config(exhaustive);

const bool trace = enabled(MIGRAPHX_TRACE_MLIR{});
static std::mutex mutex;
if(trace)
{
const std::lock_guard<std::mutex> lock(mutex);
std::cout << "Problem: " << tc.problem << std::endl;
auto mod_op = mlirModuleGetOperation(mp.mmodule.get());
std::cout << mlir_print(&mlirOperationPrint, mod_op) << std::endl;
}
return mp.get_tuning_config(exhaustive);
return tc;
}

#else

std::string dump_mlir(const module&) { return {}; }

template <class T>
void use(T&)
{
}

std::string dump_mlir(const module&) { return {}; }

std::string dump_mlir(const module& m, const std::vector<shape>& inputs)
{
use(m);
use(inputs);
return {};
}

// Disabling clang-tidy warning on non-real useage.
// NOLINTBEGIN(performance-unnecessary-value-param)
mlir_code_object compile_mlir(const context&, module, const std::vector<shape>&, const value&)
Expand Down

0 comments on commit 5a0cf97

Please sign in to comment.