diff --git a/examples/transpose/transpose.cpp b/examples/transpose/transpose.cpp index 6eb161a93..c19a0fd20 100644 --- a/examples/transpose/transpose.cpp +++ b/examples/transpose/transpose.cpp @@ -31,6 +31,7 @@ THE SOFTWARE. #include #include #include +#include #include #include @@ -106,12 +107,15 @@ run(int rank, int tid, hipStream_t stream, int argc, char** argv) std::cout << "[" << rank << "][" << tid << "] M: " << M << " N: " << N << std::endl; _lk.unlock(); + std::default_random_engine _engine{ std::random_device{}() * (rank + 1) * (tid + 1) }; + std::uniform_int_distribution _dist{ 0, 1000 }; + size_t size = sizeof(int) * M * N; int* inp_matrix = new int[size]; int* out_matrix = new int[size]; for(size_t i = 0; i < M * N; i++) { - inp_matrix[i] = rand() % 1002; + inp_matrix[i] = _dist(_engine); out_matrix[i] = 0; } int* in = nullptr; diff --git a/source/bin/omnitrace/details.cpp b/source/bin/omnitrace/details.cpp index 8fec01651..669203c58 100644 --- a/source/bin/omnitrace/details.cpp +++ b/source/bin/omnitrace/details.cpp @@ -529,11 +529,9 @@ are_file_include_exclude_lists_empty() // the instrumented loop and formats it properly. // function_signature -get_loop_file_line_info(module_t* module, procedure_t* func, flow_graph_t* cfGraph, +get_loop_file_line_info(module_t* module, procedure_t* func, flow_graph_t*, basic_loop_t* loopToInstrument) { - if(!cfGraph || !loopToInstrument || !func) return function_signature{ "", "", "" }; - std::vector basic_blocks{}; loopToInstrument->getLoopBasicBlocksExclusive(basic_blocks); @@ -563,7 +561,7 @@ get_loop_file_line_info(module_t* module, procedure_t* func, flow_graph_t* cfGra memset(fname, '\0', FUNCNAMELEN + 1); memset(mname, '\0', FUNCNAMELEN + 1); - module->getName(mname, FUNCNAMELEN); + module->getFullName(mname, FUNCNAMELEN); func->getName(fname, FUNCNAMELEN); auto* returnType = func->getReturnType(); @@ -641,7 +639,8 @@ get_loop_file_line_info(module_t* module, procedure_t* func, flow_graph_t* cfGra } else { - return function_signature(typeName, fname, filename, _params); + return function_signature(typeName, fname, filename, _params, { 0, 0 }, { 0, 0 }, + true, false, false); } } @@ -661,7 +660,7 @@ get_func_file_line_info(module_t* module, procedure_t* func) memset(fname, '\0', FUNCNAMELEN + 1); memset(mname, '\0', FUNCNAMELEN + 1); - module->getName(mname, FUNCNAMELEN); + module->getFullName(mname, FUNCNAMELEN); func->getName(fname, FUNCNAMELEN); address_t base_addr{}; @@ -727,7 +726,7 @@ get_basic_block_file_line_info(module_t* module, procedure_t* func) memset(fname, '\0', FUNCNAMELEN + 1); memset(mname, '\0', FUNCNAMELEN + 1); - module->getName(mname, FUNCNAMELEN); + module->getFullName(mname, FUNCNAMELEN); func->getName(fname, FUNCNAMELEN); auto* returnType = func->getReturnType(); diff --git a/source/bin/omnitrace/function_signature.cpp b/source/bin/omnitrace/function_signature.cpp index ab43349a5..0d535c33e 100644 --- a/source/bin/omnitrace/function_signature.cpp +++ b/source/bin/omnitrace/function_signature.cpp @@ -67,7 +67,7 @@ function_signature::get(bool _all, bool _save) const if((_all || use_return_info) && !m_return.empty()) ss << m_return << " "; ss << m_name; if(_all || use_args_info) ss << m_params; - if(m_loop && m_info_beg) + if(m_loop) { auto _row_col_str = [](unsigned long _row, unsigned long _col) { std::stringstream _ss{}; @@ -89,8 +89,11 @@ function_signature::get(bool _all, bool _save) const ss << " [" << _rc1 << "]"; else if(!m_info_end && !_rc1.empty()) ss << " [" << _rc1 << "]"; + else if(m_loop_num < std::numeric_limits::max()) + ss << " [loop#" << m_loop_num << "]"; else - errprintf(3, "line info for %s is empty!\n", m_name.c_str()); + errprintf(3, "line info for %s is empty! [{%s}] [{%s}]\n", m_name.c_str(), + _rc1.c_str(), _rc2.c_str()); } if((_all || use_file_info) && m_file.length() > 0) ss << " [" << m_file; if((_all || use_line_info) && m_row.first > 0) ss << ":" << m_row.first; diff --git a/source/bin/omnitrace/function_signature.hpp b/source/bin/omnitrace/function_signature.hpp index cbbe08ca5..e0fe4cd4e 100644 --- a/source/bin/omnitrace/function_signature.hpp +++ b/source/bin/omnitrace/function_signature.hpp @@ -40,6 +40,12 @@ struct function_signature location_t _col = { 0, 0 }, bool _loop = false, bool _info_beg = false, bool _info_end = false); + function_signature& set_loop_number(uint32_t _n) + { + m_loop_num = _n; + return *this; + } + static string_t get(function_signature& sig); string_t get(bool _all = false, bool _save = true) const; string_t get_coverage(bool _is_basic_block) const; @@ -47,6 +53,7 @@ struct function_signature bool m_loop = false; bool m_info_beg = false; bool m_info_end = false; + uint32_t m_loop_num = std::numeric_limits::max(); location_t m_row = { 0, 0 }; location_t m_col = { 0, 0 }; string_t m_return = {}; diff --git a/source/bin/omnitrace/module_function.cpp b/source/bin/omnitrace/module_function.cpp index cd89e30c6..d99914ea9 100644 --- a/source/bin/omnitrace/module_function.cpp +++ b/source/bin/omnitrace/module_function.cpp @@ -24,6 +24,8 @@ #include "fwd.hpp" #include "omnitrace.hpp" +#include + module_function::width_t& module_function::get_width() { @@ -133,7 +135,8 @@ module_function::should_coverage_instrument() const { messages.emplace_back( 2, "Skipping", "function", - TIMEMORY_JOIN("-", "less-than", absolute_min_instructions, "instructions")); + TIMEMORY_JOIN("-", "less-than", absolute_min_instructions, "instructions"), + function_name); return false; } @@ -169,7 +172,8 @@ module_function::should_instrument(bool coverage) const { messages.emplace_back( 2, "Skipping", "function", - TIMEMORY_JOIN("-", "less-than", absolute_min_instructions, "instructions")); + TIMEMORY_JOIN("-", "less-than", absolute_min_instructions, "instructions"), + function_name); return false; } @@ -199,7 +203,7 @@ module_function::is_instrumentable() const { if(!function->isInstrumentable()) { - messages.emplace_back(2, "Skipping", "module", "not-instrumentable"); + messages.emplace_back(2, "Skipping", "module", "not-instrumentable", module_name); return false; } @@ -225,12 +229,14 @@ module_function::is_user_restricted() const { if(check_regex_restrictions(module_name, file_restrict)) { - messages.emplace_back(2, "Forcing", "module", "module-restrict-regex"); + messages.emplace_back(2, "Forcing", "module", "module-restrict-regex", + module_name); return false; } else { - messages.emplace_back(3, "Skipping", "module", "module-restrict-regex"); + messages.emplace_back(3, "Skipping", "module", "module-restrict-regex", + module_name); return true; } } @@ -239,17 +245,20 @@ module_function::is_user_restricted() const { if(check_regex_restrictions(function_name, func_restrict)) { - messages.emplace_back(2, "Forcing", "function", "function-restrict-regex"); + messages.emplace_back(2, "Forcing", "function", "function-restrict-regex", + function_name); return false; } else if(check_regex_restrictions(signature.get(), func_restrict)) { - messages.emplace_back(2, "Forcing", "function", "function-restrict-regex"); + messages.emplace_back(2, "Forcing", "function", "function-restrict-regex", + signature.get()); return false; } else { - messages.emplace_back(3, "Skipping", "function", "function-restrict-regex"); + messages.emplace_back(3, "Skipping", "function", "function-restrict-regex", + function_name); return true; } } @@ -264,7 +273,8 @@ module_function::is_user_included() const { if(check_regex_restrictions(module_name, file_include)) { - messages.emplace_back(2, "Forcing", "module", "module-include-regex"); + messages.emplace_back(2, "Forcing", "module", "module-include-regex", + module_name); return true; } } @@ -273,12 +283,14 @@ module_function::is_user_included() const { if(check_regex_restrictions(function_name, func_include)) { - messages.emplace_back(2, "Forcing", "function", "function-include-regex"); + messages.emplace_back(2, "Forcing", "function", "function-include-regex", + function_name); return true; } else if(check_regex_restrictions(signature.get(), func_include)) { - messages.emplace_back(2, "Forcing", "function", "function-include-regex"); + messages.emplace_back(2, "Forcing", "function", "function-include-regex", + signature.get()); return true; } } @@ -293,7 +305,8 @@ module_function::is_user_excluded() const { if(check_regex_restrictions(module_name, file_exclude)) { - messages.emplace_back(2, "Skipping", "module", "module-exclude-regex"); + messages.emplace_back(2, "Skipping", "module", "module-exclude-regex", + module_name); return true; } } @@ -302,12 +315,14 @@ module_function::is_user_excluded() const { if(check_regex_restrictions(function_name, func_exclude)) { - messages.emplace_back(2, "Skipping", "function", "function-exclude-regex"); + messages.emplace_back(2, "Skipping", "function", "function-exclude-regex", + function_name); return true; } else if(check_regex_restrictions(signature.get(), func_exclude)) { - messages.emplace_back(2, "Skipping", "function", "function-exclude-regex"); + messages.emplace_back(2, "Skipping", "function", "function-exclude-regex", + signature.get()); return true; } } @@ -327,7 +342,7 @@ module_function::is_module_constrained() const { auto regex_opts = std::regex_constants::egrep | std::regex_constants::optimize; auto _report = [&](const string_t& _action, const string_t& _reason, int _lvl) { - messages.emplace_back(_lvl, _action, "module", _reason); + messages.emplace_back(_lvl, _action, "module", _reason, module_name); return true; }; @@ -390,7 +405,7 @@ module_function::is_routine_constrained() const { auto regex_opts = std::regex_constants::egrep | std::regex_constants::optimize; auto _report = [&](const string_t& _action, const string_t& _reason, int _lvl) { - messages.emplace_back(_lvl, _action, "function", _reason); + messages.emplace_back(_lvl, _action, "function", _reason, function_name); return true; }; @@ -462,7 +477,7 @@ module_function::is_overlapping_constrained() const { if(!allow_overlapping && is_overlapping()) { - messages.emplace_back(2, "Skipping", "function", "overlapping"); + messages.emplace_back(2, "Skipping", "function", "overlapping", function_name); return true; } @@ -482,7 +497,8 @@ module_function::is_dynamic_callsite_forced() const { if(instr_dynamic_callsites && contains_dynamic_callsites()) { - messages.emplace_back(2, "Forcing", "function", "dynamic-callsites"); + messages.emplace_back(2, "Forcing", "function", "dynamic-callsites", + function_name); return true; } @@ -496,7 +512,8 @@ module_function::is_address_range_constrained() const if(address_range < min_address_range) { - messages.emplace_back(2, "Skipping", "function", "min-address-range"); + messages.emplace_back(2, "Skipping", "function", "min-address-range", + function_name); return true; } return false; @@ -509,7 +526,8 @@ module_function::is_loop_address_range_constrained() const if(address_range < min_loop_address_range) { - messages.emplace_back(2, "Skipping", "function", "min-address-range-loop"); + messages.emplace_back(2, "Skipping", "function", "min-address-range-loop", + function_name); return true; } @@ -523,7 +541,8 @@ module_function::is_num_instructions_constrained() const if(num_instructions < min_instructions) { - messages.emplace_back(2, "Skipping", "function", "min-instructions"); + messages.emplace_back(2, "Skipping", "function", "min-instructions", + function_name); return true; } @@ -537,7 +556,8 @@ module_function::is_loop_num_instructions_constrained() const if(num_instructions < min_loop_instructions) { - messages.emplace_back(2, "Skipping", "function", "min-instructions-loop"); + messages.emplace_back(2, "Skipping", "function", "min-instructions-loop", + function_name); return true; } @@ -554,7 +574,8 @@ module_function::can_instrument_entry() const if(_num_points == 0) { - messages.emplace_back(3, "Skipping", "function", "no-instrumentable-entry-point"); + messages.emplace_back(3, "Skipping", "function", "no-instrumentable-entry-point", + function_name); return false; } @@ -571,7 +592,8 @@ module_function::can_instrument_exit() const if(_num_points == 0) { - messages.emplace_back(3, "Skipping", "function", "no-instrumentable-exit-point"); + messages.emplace_back(3, "Skipping", "function", "no-instrumentable-exit-point", + function_name); return false; } @@ -591,7 +613,7 @@ module_function::is_entry_trap_constrained() const if(!instr_traps && (_num_points - _num_traps) == 0) { messages.emplace_back(3, "Skipping", "function", - "entry-point-trap-instrumentation"); + "entry-point-trap-instrumentation", function_name); return true; } @@ -611,7 +633,7 @@ module_function::is_exit_trap_constrained() const if((_num_points - _num_traps) == 0) { messages.emplace_back(3, "Skipping", "function", - "exit-point-trap-instrumentation"); + "exit-point-trap-instrumentation", function_name); return true; } @@ -633,54 +655,62 @@ module_function::operator()(address_space_t* _addr_space, procedure_t* _entr_tra if(insert_instr(_addr_space, function, _entr, BPatch_entry) && insert_instr(_addr_space, function, _exit, BPatch_exit)) { - messages.emplace_back(1, "Instrumenting", "function", "no-constraint"); + messages.emplace_back(1, "Instrumenting", "function", "no-constraint", + function_name); ++_count.first; } - for(auto* itr : loop_blocks) + for(size_t i = 0; i < loop_blocks.size(); ++i) { if(!loop_level_instr) continue; - auto _is_constrained = [this](bool _v, const std::string& _label) { - if(!_v) + auto* itr = loop_blocks.at(i); + auto _is_constrained = [this](bool _v, const std::string& _label, + const std::string& _name) { + if(_v) { - messages.emplace_back(3, "Skipping", "function", _label); + messages.emplace_back(3, "Skipping", "function-loop", _label, _name); return true; } return false; }; + auto lname = + get_loop_file_line_info(module, function, flow_graph, itr).set_loop_number(i); + auto _lname = lname.get(); + size_t _points = 0; size_t _ntraps = 0; std::tie(_points, _ntraps) = query_instr(function, BPatch_entry, flow_graph, itr); - if(_is_constrained(_points == 0, "no-instrumentable-loop-entry-point")) continue; - if(_is_constrained(!instr_traps && (_points - _ntraps) == 0, - "loop-entry-point-trap-instrumentation")) + if(_is_constrained(_points == 0, "no-instrumentable-loop-entry-point", _lname)) + continue; + if(_is_constrained(!instr_loop_traps && _points == _ntraps, + "loop-entry-point-trap-instrumentation", _lname)) continue; std::tie(_points, _ntraps) = query_instr(function, BPatch_exit, flow_graph, itr); - if(_is_constrained(_points == 0, "no-instrumentable-loop-exit-point")) continue; - if(_is_constrained(!instr_traps && (_points - _ntraps) == 0, - "loop-exit-point-trap-instrumentation")) + if(_is_constrained(_points == 0, "no-instrumentable-loop-exit-point", _lname)) + continue; + if(_is_constrained(!instr_loop_traps && _points == _ntraps, + "loop-exit-point-trap-instrumentation", _lname)) continue; - - auto lname = get_loop_file_line_info(module, function, flow_graph, itr); - auto _lname = lname.get(); - - messages.emplace_back(1, "Loop Instrumenting", "function", "no-constraint"); - ++_count.second; auto _ltrace_entr = omnitrace_call_expr(_lname.c_str()); auto _ltrace_exit = omnitrace_call_expr(_lname.c_str()); auto _lentr = _ltrace_entr.get(_entr_trace); auto _lexit = _ltrace_exit.get(_exit_trace); - insert_instr(_addr_space, function, _lentr, BPatch_entry, flow_graph, itr, - instr_loop_traps); - insert_instr(_addr_space, function, _lexit, BPatch_exit, flow_graph, itr, - instr_loop_traps); + if(insert_instr(_addr_space, function, _lentr, BPatch_entry, flow_graph, itr, + instr_loop_traps) && + insert_instr(_addr_space, function, _lexit, BPatch_exit, flow_graph, itr, + instr_loop_traps)) + { + messages.emplace_back(1, "Loop Instrumenting", "function", "no-constraint", + _lname); + ++_count.second; + } } return _count; @@ -702,7 +732,8 @@ module_function::register_source(address_space_t* _addr_space, procedure_t* _ent if(insert_instr(_addr_space, _entr_points, _entr, BPatch_entry)) { - messages.emplace_back(1, "Code Coverage", "function", "no-constraint"); + messages.emplace_back(1, "Code Coverage", "function", "no-constraint", + _name); } break; } @@ -721,7 +752,7 @@ module_function::register_source(address_space_t* _addr_space, procedure_t* _ent if(insert_instr(_addr_space, _entr_points, _entr, BPatch_entry)) { messages.emplace_back(1, "Code Coverage", "basic_block", - "no-constraint"); + "no-constraint", _name); } } break; @@ -745,7 +776,8 @@ module_function::register_coverage(address_space_t* _addr_space, if(insert_instr(_addr_space, function, _entr, BPatch_entry)) { - messages.emplace_back(1, "Code Coverage", "function", "no-constraint"); + messages.emplace_back(1, "Code Coverage", "function", "no-constraint", + signature.get_coverage(false)); ++_count.first; } break; @@ -764,7 +796,7 @@ module_function::register_coverage(address_space_t* _addr_space, { ++_count.second; messages.emplace_back(1, "Code Coverage", "basic_block", - "no-constraint"); + "no-constraint", _signature.get_coverage(true)); } } break; diff --git a/source/bin/omnitrace/module_function.hpp b/source/bin/omnitrace/module_function.hpp index 3b0712155..b15ec8072 100644 --- a/source/bin/omnitrace/module_function.hpp +++ b/source/bin/omnitrace/module_function.hpp @@ -98,7 +98,7 @@ struct module_function basic_loop_vec_t loop_blocks = {}; std::vector> instructions = {}; - using str_msg_t = std::tuple; + using str_msg_t = std::tuple; using str_msg_vec_t = std::vector; mutable str_msg_vec_t messages = {}; @@ -183,6 +183,8 @@ module_function::serialize(ArchiveT& ar, const unsigned) if constexpr(tim::concepts::is_output_archive::value) { + ar(cereal::make_nvp("num_basic_blocks", basic_blocks.size()), + cereal::make_nvp("num_outer_loops", loop_blocks.size())); ar.setNextName("heuristics"); ar.startNode(); ar(cereal::make_nvp("should_instrument", should_instrument()), @@ -202,10 +204,12 @@ module_function::serialize(ArchiveT& ar, const unsigned) cereal::make_nvp("is_dynamic_callsite_forced", is_dynamic_callsite_forced()), cereal::make_nvp("is_address_range_constrained", is_address_range_constrained()), + cereal::make_nvp("is_num_instructions_constrained", + is_num_instructions_constrained()), cereal::make_nvp("is_loop_address_range_constrained", is_loop_address_range_constrained()), - cereal::make_nvp("is_num_instructions_constrained", - is_num_instructions_constrained())); + cereal::make_nvp("is_loop_num_instructions_constrained", + is_loop_num_instructions_constrained())); ar.finishNode(); // instructions can inflate JSON size so only output when verbosity is increased // above default diff --git a/source/bin/omnitrace/omnitrace.cpp b/source/bin/omnitrace/omnitrace.cpp index 40d115ef6..d70dc624f 100644 --- a/source/bin/omnitrace/omnitrace.cpp +++ b/source/bin/omnitrace/omnitrace.cpp @@ -23,6 +23,7 @@ #include "omnitrace.hpp" #include "fwd.hpp" +#include #include #include #include @@ -947,7 +948,7 @@ main(int argc, char** argv) return EXIT_FAILURE; } - verbprintf(0, "instrumentation target: %s\n", mutname.c_str()); + verbprintf(1, "instrumentation target: %s\n", mutname.c_str()); // did we load a library? if not, load the default auto generate_libnames = [](auto& _targ, const auto& _base, @@ -1041,7 +1042,11 @@ main(int argc, char** argv) if(app_modules && !app_modules->empty()) { - modules = *app_modules; + modules.reserve(app_modules->size()); + for(auto* itr : *app_modules) + { + if(!itr->isSystemLib()) modules.emplace_back(itr); + } for(auto* itr : modules) { auto* procedures = itr->getProcedures(); @@ -1065,7 +1070,11 @@ main(int argc, char** argv) if(app_functions && !app_functions->empty()) { - functions = *app_functions; + functions.reserve(app_functions->size()); + for(auto* itr : *app_functions) + { + if(!itr->getModule()->isSystemLib()) functions.emplace_back(itr); + } for(auto* itr : functions) { module_t* mod = itr->getModule(); @@ -1083,7 +1092,7 @@ main(int argc, char** argv) verbprintf(0, "Warning! No functions in application...\n"); } - verbprintf(0, "Module size before loading instrumentation library: %lu\n", + verbprintf(1, "Module size before loading instrumentation library: %lu\n", (long unsigned) modules.size()); if(debug_print || verbose_level > 2) @@ -1153,7 +1162,7 @@ main(int argc, char** argv) { _libname = get_absolute_lib_filepath(_libname); _tried_libs += string_t("|") + _libname; - verbprintf(0, "loading library: '%s'...\n", _libname.c_str()); + verbprintf(1, "loading library: '%s'...\n", _libname.c_str()); result = (addr_space->loadLibrary(_libname.c_str()) != nullptr); verbprintf(2, "loadLibrary(%s) result = %s\n", _libname.c_str(), (result) ? "success" : "failure"); @@ -1646,7 +1655,7 @@ main(int argc, char** argv) //----------------------------------------------------------------------------------// if(app_thread) { - verbprintf(1, "Beginning insertion set...\n"); + verbprintf(2, "Beginning insertion set...\n"); addr_space->beginInsertionSet(); } @@ -1670,7 +1679,7 @@ main(int argc, char** argv) if(instr_mode != "coverage") { std::map> _pass_info{}; - const int _pass_verbose_lvl = 1; + const int _pass_verbose_lvl = 0; for(const auto& itr : instrumented_module_functions) { auto _count = itr(addr_space, entr_trace, exit_trace); @@ -1679,24 +1688,22 @@ main(int argc, char** argv) for(const auto& mitr : itr.messages) _report_info(std::get<0>(mitr), std::get<1>(mitr), std::get<2>(mitr), - std::get<3>(mitr), - std::get<2>(mitr) == "module" ? itr.module_name - : itr.function_name); + std::get<3>(mitr), std::get<4>(mitr)); } // report the trace instrumented functions for(auto& itr : _pass_info) { - auto _valid = (verbose_level > _pass_verbose_lvl || + auto _valid = (verbose_level >= _pass_verbose_lvl || (itr.second.first + itr.second.second) > 0); if(!_valid) continue; - verbprintf(_pass_verbose_lvl, "%4zu instrumented procedures in %s\n", + verbprintf(_pass_verbose_lvl, "%4zu instrumented funcs in %s\n", itr.second.first, itr.first.c_str()); _valid = (loop_level_instr && - (verbose_level > _pass_verbose_lvl || itr.second.second > 0)); + (verbose_level >= _pass_verbose_lvl || itr.second.second > 0)); if(_valid) { - verbprintf(_pass_verbose_lvl, "%4zu instrumented loops in procedure %s\n", + verbprintf(_pass_verbose_lvl, "%4zu instrumented loops in %s\n", itr.second.second, itr.first.c_str()); } } @@ -1715,9 +1722,7 @@ main(int argc, char** argv) for(const auto& mitr : itr.messages) _report_info(std::get<0>(mitr), std::get<1>(mitr), std::get<2>(mitr), - std::get<3>(mitr), - std::get<2>(mitr) == "module" ? itr.module_name - : itr.function_name); + std::get<3>(mitr), std::get<4>(mitr)); } // report the coverage instrumented functions @@ -1751,7 +1756,7 @@ main(int argc, char** argv) if(app_thread) { - verbprintf(1, "Finalizing insertion set...\n"); + verbprintf(2, "Finalizing insertion set...\n"); bool modified = true; bool success = addr_space->finalizeInsertionSet(true, &modified); if(!success) @@ -1939,7 +1944,8 @@ main(int argc, char** argv) if(main_func) { verbprintf(0, "Getting linked libraries for %s...\n", cmdv0.c_str()); - verbprintf(0, "Consider instrumenting the relevant libraries...\n\n"); + verbprintf(0, "Consider instrumenting the relevant libraries...\n"); + verbprintf(0, "\n"); using TIMEMORY_PIPE = tim::popen::TIMEMORY_PIPE; @@ -1953,9 +1959,9 @@ main(int argc, char** argv) if(perr != 0) perror("Error in omnitrace_fork"); for(const auto& itr : linked_libraries) - printf("\t%s\n", itr.c_str()); + verbprintf(0, "\t%s\n", itr.c_str()); - printf("\n"); + verbprintf(0, "\n"); } } else @@ -2080,14 +2086,29 @@ query_instr(procedure_t* funcToInstr, procedure_loc_t traceLoc, flow_graph_t* cf module_t* module = funcToInstr->getModule(); if(!module) return { 0, 0 }; + if(!cfGraph) cfGraph = funcToInstr->getCFG(); + bpvector_t* _points = nullptr; - if(cfGraph && loopToInstrument) + if((cfGraph && loopToInstrument) || + (traceLoc == BPatch_locLoopEntry || traceLoc == BPatch_locLoopExit)) { - if(traceLoc == BPatch_entry) + if(!cfGraph) throw std::runtime_error("No control flow graph"); + if(!loopToInstrument) throw std::runtime_error("No loop to instrument"); + + if(traceLoc == BPatch_entry || traceLoc == BPatch_locLoopEntry) + { _points = cfGraph->findLoopInstPoints(BPatch_locLoopEntry, loopToInstrument); - else if(traceLoc == BPatch_exit) + } + else if(traceLoc == BPatch_exit || traceLoc == BPatch_locLoopExit) + { _points = cfGraph->findLoopInstPoints(BPatch_locLoopExit, loopToInstrument); + } + else + { + throw std::runtime_error("unsupported trace location :: " + + std::to_string(traceLoc)); + } } else { @@ -2145,7 +2166,7 @@ get_absolute_exe_filepath(std::string exe_name, const std::string& env_path) if(file_exists(TIMEMORY_JOIN('/', pitr, exe_name))) { exe_name = get_realpath(TIMEMORY_JOIN('/', pitr, exe_name)); - verbprintf(0, "Resolved '%s' to '%s'...\n", _exe_orig.c_str(), + verbprintf(1, "Resolved '%s' to '%s'...\n", _exe_orig.c_str(), exe_name.c_str()); break; } @@ -2181,7 +2202,7 @@ get_absolute_lib_filepath(std::string lib_name, const std::string& env_path) if(file_exists(TIMEMORY_JOIN('/', pitr, lib_name))) { lib_name = get_realpath(TIMEMORY_JOIN('/', pitr, lib_name)); - verbprintf(0, "Resolved '%s' to '%s'...\n", _lib_orig.c_str(), + verbprintf(1, "Resolved '%s' to '%s'...\n", _lib_orig.c_str(), lib_name.c_str()); break; } diff --git a/source/bin/omnitrace/omnitrace.hpp b/source/bin/omnitrace/omnitrace.hpp index b646d714d..87b266eb0 100644 --- a/source/bin/omnitrace/omnitrace.hpp +++ b/source/bin/omnitrace/omnitrace.hpp @@ -331,6 +331,7 @@ insert_instr(address_space_t* mutatee, procedure_t* funcToInstr, Tp traceFunc, bpvector_t* _points = nullptr; auto _trace = traceFunc.get(); + if(!cfGraph) funcToInstr->getCFG(); if(cfGraph && loopToInstrument) { if(traceLoc == BPatch_entry) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 028ec7325..11a6956e5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -406,10 +406,43 @@ omnitrace_add_test( TARGET transpose MPI ${TRANSPOSE_USE_MPI} NUM_PROCS ${NUM_PROCS} - REWRITE_ARGS -e -v 2 --print-instructions - RUNTIME_ARGS -e -v 1 --label file line return args + REWRITE_ARGS -e -v 2 --print-instructions -E uniform_int_distribution + RUNTIME_ARGS + -e + -v + 1 + --label + file + line + return + args + -E + uniform_int_distribution ENVIRONMENT "${_base_environment};OMNITRACE_CRITICAL_TRACE=ON") +omnitrace_add_test( + SKIP_BASELINE SKIP_SAMPLING SKIP_RUNTIME + NAME transpose-loops + TARGET transpose + LABELS "loops" + MPI ${TRANSPOSE_USE_MPI} + NUM_PROCS ${NUM_PROCS} + REWRITE_ARGS + -e + -v + 2 + --label + return + args + -l + -i + 8 + -E + uniform_int_distribution + RUN_ARGS 2 100 50 + ENVIRONMENT "${_base_environment};OMNITRACE_CRITICAL_TRACE=OFF" + REWRITE_FAIL_REGEX "0 instrumented loops in procedure transpose") + omnitrace_add_test( NAME parallel-overhead TARGET parallel-overhead @@ -454,6 +487,7 @@ omnitrace_add_test( omnitrace_add_test( NAME user-api TARGET user-api + LABELS "loops" REWRITE_ARGS -e -v 2 -l --min-instructions=8 -E custom_push_region RUNTIME_ARGS -e @@ -469,7 +503,8 @@ omnitrace_add_test( return args RUN_ARGS 10 ${NUM_THREADS} 1000 - ENVIRONMENT "${_base_environment};OMNITRACE_CRITICAL_TRACE=OFF") + ENVIRONMENT "${_base_environment};OMNITRACE_CRITICAL_TRACE=OFF" + REWRITE_FAIL_REGEX "0 instrumented loops in procedure") omnitrace_add_test( SKIP_RUNTIME @@ -553,7 +588,7 @@ omnitrace_add_test( TARGET lulesh MPI ${LULESH_USE_MPI} NUM_PROCS 8 - LABELS "kokkos" + LABELS "kokkos;loops" REWRITE_ARGS -e -v 2 RUNTIME_ARGS -e @@ -575,7 +610,7 @@ omnitrace_add_test( TARGET lulesh MPI ${LULESH_USE_MPI} NUM_PROCS 8 - LABELS "kokkos" + LABELS "kokkos;loops" REWRITE_ARGS -e -v 2 -l --dynamic-callsites --traps --allow-overlapping RUNTIME_ARGS -e @@ -590,7 +625,8 @@ omnitrace_add_test( peak_rss RUN_ARGS -i 10 -s 20 -p ENVIRONMENT - "${_timemory_environment};OMNITRACE_CRITICAL_TRACE=OFF;OMNITRACE_USE_KOKKOSP=OFF") + "${_timemory_environment};OMNITRACE_CRITICAL_TRACE=OFF;OMNITRACE_USE_KOKKOSP=OFF" + REWRITE_FAIL_REGEX "0 instrumented loops in procedure") omnitrace_add_test( SKIP_SAMPLING @@ -601,7 +637,8 @@ omnitrace_add_test( RUNTIME_ARGS -e -v 1 --label return args REWRITE_TIMEOUT 180 RUNTIME_TIMEOUT 360 - ENVIRONMENT "${_ompt_environment};OMNITRACE_USE_SAMPLING=OFF") + ENVIRONMENT "${_ompt_environment};OMNITRACE_USE_SAMPLING=OFF" + REWRITE_FAIL_REGEX "0 instrumented loops in procedure") omnitrace_add_test( SKIP_RUNTIME @@ -613,7 +650,8 @@ omnitrace_add_test( REWRITE_TIMEOUT 180 RUNTIME_TIMEOUT 360 ENVIRONMENT - "${_ompt_environment};OMNITRACE_USE_SAMPLING=ON;OMNITRACE_SAMPLING_FREQ=100") + "${_ompt_environment};OMNITRACE_USE_SAMPLING=ON;OMNITRACE_SAMPLING_FREQ=100" + REWRITE_FAIL_REGEX "0 instrumented loops in procedure") omnitrace_add_test( SKIP_BASELINE SKIP_SAMPLING