Change-Id: I2ba07a213acc7db403b804d8136edce28df9dd14


[ROCm/rocprofiler commit: 6ee20035dd]
Этот коммит содержится в:
gobhardw
2023-08-17 21:27:00 +05:30
коммит произвёл Gopesh Bhardwaj
родитель be079032bb
Коммит 51a6df35d1
3 изменённых файлов: 506 добавлений и 179 удалений
+18 -7
Просмотреть файл
@@ -1,5 +1,13 @@
# Setting Default Binary output directory
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
# fmt library for formatting
include(FetchContent)
fetchcontent_declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG master)
fetchcontent_makeavailable(fmt)
# Getting HSA Include Directory
get_property(
@@ -18,17 +26,20 @@ endif()
file(GLOB ROCPROFV2_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
add_executable(rocprofv2 ${ROCPROFV2_SRC_FILES})
add_executable(rocprofv2_bin ${ROCPROFV2_SRC_FILES})
target_compile_definitions(
rocprofv2
rocprofv2_bin
PUBLIC AMD_INTERNAL_BUILD
PRIVATE PROF_API_IMPL)
target_include_directories(
rocprofv2
rocprofv2_bin
PUBLIC ${HSA_RUNTIME_INCLUDE_DIRECTORIES}
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/inc>
PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/inc)
target_link_libraries(rocprofv2 PRIVATE ${AQLPROFILE_LIB} hsa-runtime64::hsa-runtime64
stdc++fs Threads::Threads atomic -ldl)
# install(TARGETS rocprofv2 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime)
target_link_libraries(
rocprofv2_bin PRIVATE ${AQLPROFILE_LIB} hsa-runtime64::hsa-runtime64 stdc++fs
Threads::Threads atomic -ldl fmt::fmt)
install(TARGETS rocprofv2_bin RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT runtime)
+472 -157
Просмотреть файл
@@ -1,4 +1,5 @@
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
/******************************************************************************
Copyright (c) 2022 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -16,199 +17,505 @@
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. */
THE SOFTWARE.
*******************************************************************************/
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <atomic>
#include <experimental/filesystem>
#include <cstddef>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <algorithm>
#include <unordered_set>
#include <fmt/core.h>
#include <fmt/color.h>
namespace fs = std::experimental::filesystem;
// filesystem for path resolutions
namespace fs = std::filesystem;
// Usage message
void printUsage() {
std::cout << "ROCProfiler Run Binary Usage:" << std::endl;
std::cout << "\nTo run ./run.sh PARAMs, PARAMs can be the following:" << std::endl;
std::cout << "-h | --help For showing this message" << std::endl;
std::cout << "-t | --test For Running the tests" << std::endl;
std::cout << "-mt | --mem-test For Running the Memory Leak tests" << std::endl;
std::cout << "\nTo run ./run.sh PARAMs APP_EXEC, PARAMs can be the following:" << std::endl;
std::cout << "-i | --input For adding counters file path "
"(every line in the text file represents a counter)"
<< std::endl;
std::cout << "-d | --output-directory For adding output path where the "
"output files will be saved"
<< std::endl;
std::cout << "-fi | --flush-interval For adding a flush interval in "
"milliseconds, every \"flush interval\" the buffers will be flushed"
<< std::endl;
std::cout << "-a | --asan For adding libasan.so.6 for memory leak "
"check run requires building using -act | --asan-clean-build option"
<< std::endl;
namespace rocprofiler {
namespace src {
namespace tools {
// supported plugin list
std::vector<std::string> plugins{"ctf", "perfetto", "file", "att"};
// set rocm path and creates sym_link to /opt/rocm if not exists already
fs::path set_rocm_path() {
// check symlink
std::vector<std::string> rocm_paths;
fs::path opt_path = "/opt";
fs::path rocm_path = "/opt/rocm";
// iterate and save all dirs under /opt that matches rocm
for (const auto& entry : fs::directory_iterator(opt_path)) {
if (entry.is_directory()) {
std::string dirName = entry.path().filename().string();
if (dirName.compare(0, 4, "rocm") == 0) {
rocm_paths.push_back(entry.path());
}
}
}
// check if symlink already exists
bool is_sym_link = false;
for (const auto& rocm_dir : rocm_paths) {
fs::path dir_path = opt_path / rocm_dir;
if (fs::is_symlink(dir_path)) {
is_sym_link = true;
}
}
// create a symlink if not already exists
if (!is_sym_link) {
try {
fs::create_symlink(rocm_paths[rocm_paths.size() - 1], "/opt/rocm");
std::cout << "symbolic link created successfully." << std::endl;
} catch (const fs::filesystem_error& e) {
std::cerr << "error creating symbolic link: " << e.what() << std::endl;
}
}
return rocm_path;
}
void runMemCheck(fs::path bin_path) {
fs::path counter_path = bin_path;
// usage message
void print_usage(fs::path current_path) {
fmt::print("Usage: rocprofv2 [options] [target]\n");
fmt::print("Options:\n");
// help message
fmt::print(fg(fmt::color::cyan), " -h | --help\t\t");
fmt::print("For showing this message\n");
// list counters
fmt::print(fg(fmt::color::cyan), " --list-counters\t");
fmt::print("For showing all available counters for the current GPUs\n");
// only show tests when running from build
if (current_path.string().find("build") != std::string::npos) {
fmt::print(fg(fmt::color::cyan), " -t | --test\t\t");
fmt::print("For Running the tests\n");
fmt::print(fg(fmt::color::cyan), " -mt | --mem-test \t");
fmt::print("For Running the Memory Leak tests\n");
}
// HIP API traces
fmt::print(fg(fmt::color::cyan), " --hip-api\t\t");
fmt::print("For Collecting HIP API Traces\n");
// HIP API and Activity traces
fmt::print(fg(fmt::color::cyan), " --hip-activity | --hip-trace\n\t\t\t");
fmt::print("For Collecting HIP API Activities Traces\n");
// HSA API traces
fmt::print(fg(fmt::color::cyan), " --hsa-api\t\t");
fmt::print("For Collecting HSA API Traces\n");
// HSA API and Activity traces
fmt::print(fg(fmt::color::cyan), " --hsa-activity | --hsa-trace\n\t\t\t");
fmt::print("For Collecting HSA API Activities Traces\n");
// ROCtx traces
fmt::print(fg(fmt::color::cyan), " --roctx-trace\t\t");
fmt::print("For Collecting ROCTx Traces\n");
// HSA API traces
fmt::print(fg(fmt::color::cyan), " --kernel-trace\t\t");
fmt::print("For Collecting Kernel dispatch Traces\n");
// HSA API traces
fmt::print(fg(fmt::color::cyan), " --sys-trace\t\t");
fmt::print(
"For Collecting HIP and HSA APIs and their Activities Traces along with ROCTX and Kernel "
"Dispatch traces\n\t\t\t");
fmt::print(fg(fmt::color::gray),
"usage e.g: rocprofv2 --[hip-trace|hsa-trace|roctx-trace|kernel-trace|sys-trace] "
"[target]\n");
// plugins
fmt::print(fg(fmt::color::cyan), " --plugin [PLUGIN_NAME]\n\t\t\t");
fmt::print("For enabling a plugin (file/perfetto/att/ctf)\n\t\t\t");
fmt::print(fg(fmt::color::gray),
"usage(file/perfetto/ctf) e.g: rocprofv2 -i pmc.txt --plugin [file/perfetto/ctf] -d "
"out-dir [target]\n\t\t\t");
fmt::print(fg(fmt::color::gray),
"usage(att): rocprofv2 [rocprofv2_params] --plugin att [ISA_file] [att_parameters] "
"[target]\n\t\t\t");
fmt::print(fg(fmt::color::gray),
"use rocprofv2 --plugin att --help for ATT-specific parameters help\n");
// input file
fmt::print(fg(fmt::color::cyan), " -i | --input\t\t");
fmt::print(
"For adding counters file path (every line in the text file represents a counter)\n\t\t\t");
fmt::print(fg(fmt::color::gray), "usage: rocprofv2 -i pmc.txt -d [target]\n");
// output file
fmt::print(fg(fmt::color::cyan), " -o | --output-file\t\t");
fmt::print("For the output file name\n\t\t\t");
fmt::print(fg(fmt::color::gray),
"usage e.g:(with current dir): rocprofv2 --hip-trace -o <file_name> [target]\n\t\t\t");
fmt::print(
fg(fmt::color::gray),
"usage e.g:(with custom dir): rocprofv2 --hip-trace -d <out_dir> -o <file_name> [target]\n");
// output directory
fmt::print(fg(fmt::color::cyan), " -d | --output-directory\n\t\t\t");
fmt::print("For adding output path where the output files will be saved\n\t\t\t");
fmt::print(fg(fmt::color::gray),
"usage e.g:(with custom dir): rocprofv2 --hip-trace -d <out_dir> [target]\n");
// flush interval
fmt::print(fg(fmt::color::cyan), " -fi | --flush-interval\n\t\t\t");
fmt::print(
"For adding a flush interval in milliseconds, every flush interval the buffers will be "
"flushed\n\t\t\t");
fmt::print(fg(fmt::color::gray), "usage e.g : rocprofv2 --hip-trace - fi 1000 [target]\n");
// trace period
fmt::print(fg(fmt::color::cyan), " -tp | --trace-period\n\t\t\t");
fmt::print(
"For specifing a trace period in milliseconds with -tp "
"<DELAY>:<ACTIVE_TIME>:<LOOP_RESET_TIME>\n\t\t\t");
fmt::print(fg(fmt::color::gray),
"usage e.g: rocprofv2 --hip-trace -tp 1000:2000:4000 [target]\n");
}
// runs memory check on hip_vectoradd
void run_mem_check(fs::path bin_path) {
fs::path app_path = bin_path;
fs::path log_path = bin_path;
fs::path suppr_path = bin_path;
fs::path pyscript_path = bin_path;
fs::path asan_script_path = bin_path;
std::string pathenv = bin_path.replace_filename("librocprofiler_tool.so");
pyscript_path = pyscript_path.replace_filename("tests/memorytests/test_mem.py");
counter_path = counter_path.replace_filename("tests/memorytests/input.txt");
suppr_path = suppr_path.replace_filename("tests/memorytests/suppr.txt");
app_path = app_path.replace_filename(
"tests/featuretests/profiler/gtests/apps/"
"hip_vectoradd");
log_path = log_path.replace_filename("memleaks.log");
std::cout << "Running Memory Leaks Check...." << std::endl;
std::string run_command = "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6:" + pathenv +
" ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=suppressions=" + suppr_path.string() +
" COUNTERS_PATH=" + counter_path.string() + " " + app_path.string() +
" > /tmp/rocprofv2-temp 2> " + log_path.string();
int status = system(run_command.c_str());
if (status < 0) std::cerr << "Invalid Command!" << std::endl;
asan_script_path =
asan_script_path.string() + std::string("/tests-v2/memorytests/run_asan_tests.sh");
app_path = app_path.string() + std::string("/tests-v2/featuretests/profiler/apps/hip_vectoradd");
log_path = log_path.string() + std::string("memleaks.log");
std::cout << "Log with all detected leaks is available at " << log_path.string() << std::endl;
std::string python_command = "python3 " + pyscript_path.string() + " " + log_path.string();
status = system(python_command.c_str());
if (status < 0) std::cerr << "Invalid Command!" << std::endl;
}
// Passes Counter
static std::atomic<uint32_t> pass_num{1};
// Getting the number of passes needed using the counters file path
uint32_t getNumberOfPasses(std::string counter_path) {
// TODO(aelwazir): Adding a way to get the number of passes;
return 1;
}
// Function to run the app for the amount of passes needed
void runApp(const char* app_path, char* const envp[], char* const args[],
uint32_t number_of_passes = 1) {
while (pass_num.load(std::memory_order_relaxed) <= number_of_passes) {
// Forking to keep the original
int status = 0;
if (fork() > 0) {
status = execve(app_path, args, envp);
std::cout << "Error: can't launch(" << app_path << "):" << std::endl;
perror("errno");
exit(EXIT_FAILURE);
}
if (status == 0)
std::cout << "Pass(" << pass_num.fetch_add(1, std::memory_order_release)
<< ") of the application: " << fs::path(app_path).filename()
<< " is executed successfully!" << std::endl;
int status = system((asan_script_path.string() + " " + app_path.string()).c_str());
if (status < 0) {
std::cerr << "Invalid Command!" << std::endl;
}
}
uint32_t number_of_passes = 1;
// passes counter
static std::atomic<uint32_t> pass_num{1};
// function to run the app for the amount of passes needed
void run_application(const char* app_path, char* const envp[], char* const args[]) {
std::vector<char*> envp_vector;
std::vector<char*> counter_passes;
// each line of counter input file needs a single pass
for(int i = 0; envp[i] != nullptr; ++i)
{
std::string envpString = envp[i];
if(envpString.find("ROCPROFILER_COUNTERS") != std::string::npos)
{
counter_passes.push_back(const_cast<char*>(envp[i]));
}
else
{
envp_vector.push_back(const_cast<char*>(envp[i]));
}
}
// no counter collection. hence need only 1 pass
if(counter_passes.empty())
{
envp_vector[envp_vector.size()] = nullptr;
int status = 0;
if(fork() > 0)
{
status = execve(app_path, args, envp_vector.data());
std::cout << "error: can't launch(" << app_path << "):" << std::endl;
perror("errno");
exit(EXIT_FAILURE);
}
envp_vector.pop_back();
if(status == 0)
std::cout << "pass(" << pass_num.fetch_add(1, std::memory_order_release)
<< ") of the application: " << fs::path(app_path).filename()
<< " is executed successfully!" << std::endl;
}
// counter collection. might need multipass, depends on input file pmc lines
else
{
for(const auto& pass : counter_passes)
{
int status = 0;
envp_vector.push_back(pass);
envp_vector[envp_vector.size()] = nullptr;
if(fork() > 0)
{
status = execve(app_path, args, envp_vector.data());
std::cout << "error: can't launch(" << app_path << "):" << std::endl;
perror("errno");
exit(EXIT_FAILURE);
}
envp_vector.pop_back();
if(status == 0)
std::cout << "pass(" << pass_num.fetch_add(1, std::memory_order_release)
<< ") of the application: " << fs::path(app_path).filename()
<< " is executed successfully!" << std::endl;
}
}
envp_vector.clear();
}
} // namespace tools
} // namespace src
} // namespace rocprofiler
// creating a shorter alias
namespace rocprofv2 = rocprofiler::src::tools;
int main(int argc, char** argv) {
// Getting Current Path
// environment variables vector
std::vector<std::string> pathenv;
// reading arguments: one env var for the whole options!!
int app_argc_start = 0;
char* app_path = nullptr;
// att params
std::string att_argv;
std::string att_pthon3_arg;
fs::path att_py_path;
std::string att_input_path;
// getting current path
char current_path[FILENAME_MAX];
if (!getcwd(current_path, sizeof(current_path))) {
throw errno;
}
current_path[sizeof(current_path) - 1] = '\0';
// Getting the rocprofv2 binary path to locate rocprofiler library path
fs::path bin_path;
if (Dl_info dl_info; dladdr((void*)runApp, &dl_info) != 0) {
bin_path = fs::path(dl_info.dli_fname);
// set rocm path (/opt/rocm)
fs::path rocm_path = rocprofv2::set_rocm_path();
// to show usage when no arguments are given
if (argc <= 1) {
rocprofv2::print_usage(current_path);
return (EXIT_SUCCESS);
}
// Environment cariables vector
std::vector<std::string> pathenv;
// providing LD_PRELOAD of rocprofiler library to run_application function
std::string tool_lib_path = rocm_path.string() + "/lib/rocprofiler/librocprofiler_tool.so";
std::string current_ld_preload;
if (getenv("LD_PRELOAD")) current_ld_preload = getenv("LD_PRELOAD");
if (!current_ld_preload.empty())
tool_lib_path = "LD_PRELOAD=" + current_ld_preload + ":" + tool_lib_path;
else
tool_lib_path = "LD_PRELOAD=" + current_ld_preload + tool_lib_path;
pathenv.emplace_back(tool_lib_path);
// Reading Arguments
// One ENV Var for the whole options!!
int app_argc_start = 0;
char* app_path = nullptr;
// iterate through all options
for (int i = 1; i < argc; i++) {
// Help Message
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-h") == 0) {
printUsage();
return 1;
// Normal ROCProfiler Tests
} else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--test") == 0) {
fs::path test_path = bin_path;
test_path = test_path.replace_filename("run_tests.sh");
// help message
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
rocprofv2::print_usage(current_path);
return (EXIT_SUCCESS);
}
// list counters
if (strcmp(argv[i], "--list-counters") == 0) {
fs::path ctrl_path = rocm_path.string() + "/libexec/rocprofiler/ctrl";
std::string iterate_counters = tool_lib_path + " " + ctrl_path.string();
int status = system(iterate_counters.c_str());
if (status < 0) {
std::cerr << "Invalid Command!" << std::endl;
return (EXIT_FAILURE);
}
return (EXIT_SUCCESS);
}
// rocprofiler tests
else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--test") == 0) {
fs::path test_path = current_path + std::string("/run_tests.sh");
int status = system(test_path.string().c_str());
if (status < 0) std::cerr << "Invalid Command!" << std::endl;
return 1;
// Memory Check Test
} else if (strcmp(argv[i], "-mt") == 0 || strcmp(argv[i], "--mem-test") == 0) {
runMemCheck(bin_path);
return 1;
// Counters File
} else if (strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--input") == 0) {
if (status < 0) {
std::cerr << "Invalid Command!" << std::endl;
return (EXIT_FAILURE);
}
return (EXIT_SUCCESS);
}
// memory check tests
else if (strcmp(argv[i], "-mt") == 0 || strcmp(argv[i], "--mem-test") == 0) {
rocprofv2::run_mem_check(current_path);
return (EXIT_SUCCESS);
}
// counters file
else if (strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--input") == 0) {
i++;
if (argv[i]) {
std::string counters_path = std::string(current_path) + "/" + argv[2];
std::cout << "Reading counters from: " << counters_path << std::endl;
number_of_passes = getNumberOfPasses(counters_path);
std::string counters_path;
if (!fs::path(argv[i]).is_absolute()) {
counters_path = std::string(current_path) + "/" + argv[i];
} else {
counters_path = argv[i];
}
std::cout << "reading counters from: " << counters_path << std::endl;
pathenv.emplace_back("COUNTERS_PATH=" + counters_path);
// setting att input path for later
att_input_path = counters_path;
std::ifstream inputfile(counters_path);
std::string pmc_line;
while (std::getline(inputfile, pmc_line)) {
// std::cout << "ROCPROFILER_COUNTERS=" + pmc_line << std::endl;
pathenv.emplace_back("ROCPROFILER_COUNTERS=" + pmc_line);
}
// close the file.
inputfile.close();
} else {
std::cerr << "Error: Missing Counters File path!" << std::endl;
printUsage();
rocprofv2::print_usage(current_path);
exit(EXIT_FAILURE);
}
// Output Directory
} // HIP API trace
else if (strcmp(argv[i], "--hip-api") == 0) {
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_HIP_API_TRACE=1");
}
// HIP trace
} else if (strcmp(argv[i], "--hip-trace") == 0 || strcmp(argv[i], "--hip-activity") == 0) {
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_HIP_API_TRACE=1");
pathenv.emplace_back("ROCPROFILER_HIP_ACTIVITY_TRACE=1");
}
// HSA API trace
} else if (strcmp(argv[i], "--hsa-api") == 0) {
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_HSA_API_TRACE=1");
}
// HSA trace
} else if (strcmp(argv[i], "--hsa-trace") == 0 || strcmp(argv[i], "--hsa-activity") == 0) {
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_HSA_API_TRACE=1");
pathenv.emplace_back("ROCPROFILER_HSA_ACTIVITY_TRACE=1");
}
// ROCTx trace
} else if (strcmp(argv[i], "--roctx-trace") == 0) {
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_ROCTX_TRACE=1");
}
// kernel trace
} else if (strcmp(argv[i], "--kernel-trace") == 0) {
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_KERNEL_TRACE=1");
}
// sys trace
} else if (strcmp(argv[i], "--sys-trace") == 0) {
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_HIP_API_TRACE=1");
pathenv.emplace_back("ROCPROFILER_HIP_ACTIVITY_TRACE=1");
pathenv.emplace_back("ROCPROFILER_HSA_API_TRACE=1");
pathenv.emplace_back("ROCPROFILER_HSA_ACTIVITY_TRACE=1");
pathenv.emplace_back("ROCPROFILER_ROCTX_TRACE=1");
pathenv.emplace_back("ROCPROFILER_KERNEL_TRACE=1");
}
// plugins
} else if (strcmp(argv[i], "--plugin") == 0) {
i++;
auto it =
std::find(rocprofv2::plugins.begin(), rocprofv2::plugins.end(), std::string(argv[i]));
if (it == rocprofv2::plugins.end()) {
rocprofv2::print_usage(current_path);
exit(EXIT_FAILURE);
}
pathenv.emplace_back("ROCPROFILER_PLUGIN_LIB=lib" + std::string(argv[i]) + "_plugin.so");
if (std::string(argv[i]) == "att") {
att_py_path = rocm_path.string() + std::string("/libexec/rocprofiler/att/att.py");
pathenv.emplace_back("ROCPROFV2_ATT_LIB_PATH=" + rocm_path.string() +
"/lib/hsa-amd-aqlprofile/librocprofv2_att.so");
i++;
att_argv = argv[3];
att_pthon3_arg = "python3";
i++;
att_argv = "";
for (int i = 4; i < argc; i++) {
if (std::string(argv[i]) == "--trace-file") {
att_argv = att_argv + " " + argv[i] + " " + argv[i + 1];
i = i + 1;
} else if (std::string(argv[i]) == "--mpi") {
att_pthon3_arg = "mpirun -np " + std::string(argv[i]) + " python3";
i = i + 1;
} else if (std::string(argv[i]) == "--mode" || std::string(argv[i]) == "--ports" ||
std::string(argv[i]) == "--genasm" || std::string(argv[i]) == "--att_kernel" ||
std::string(argv[i]) == "--depth") {
att_argv = att_argv + " " + argv[i] + " " + argv[i + 1] + " " + argv[i - 1];
i = i + 1;
} else {
continue;
}
} // for loop
}
// output directory
} else if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--output-directory") == 0) {
i++;
if (argv[i]) {
std::string output_path = std::string(current_path) + "/" + argv[2];
fs::create_directory(output_path);
std::cout << "Output directory path: " << output_path << std::endl;
pathenv.emplace_back("OUTPUT_PATH=" + output_path);
pathenv.emplace_back("OUTPUT_PATH_INTERNAL=" + std::string(argv[i]));
pathenv.emplace_back("OUTPUT_PATH=" + std::string(argv[i]));
} else {
std::cerr << "Error: Missing output directory path!" << std::endl;
printUsage();
rocprofv2::print_usage(current_path);
exit(EXIT_FAILURE);
}
// ASAN run
} else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--asan") == 0) {
std::string current_ld_preload{getenv("LD_PRELOAD")};
std::string ld_preload = "/usr/lib/x86_64-linux-gnu/libasan.so.6";
if (!current_ld_preload.empty()) ld_preload = current_ld_preload + ":" + ld_preload;
std::cout << ld_preload << std::endl;
pathenv.emplace_back("LD_PRELOAD=" + ld_preload);
pathenv.emplace_back("ASAN_OPTIONS=detect_leaks=1");
fs::path suppr_path = bin_path;
std::string suppr =
"suppressions=" + suppr_path.replace_filename("tests/memorytests/suppr.txt").string();
std::cout << suppr << std::endl;
pathenv.emplace_back("LSAN_OPTIONS=" + suppr);
// Flush Interval
} // output file name
else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output-file-name") == 0) {
i++;
if (argv[i]) {
pathenv.emplace_back("OUT_FILE_NAME=" + std::string(argv[i]));
} else {
std::cerr << "Error: Missing output file name!" << std::endl;
rocprofv2::print_usage(current_path);
exit(EXIT_FAILURE);
}
// flush interval
} else if (strcmp(argv[i], "-fi") == 0 || strcmp(argv[i], "--flush-interval") == 0) {
i++;
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_FLUSH_INTERVAL=" + std::string(argv[i]));
} else {
std::cerr << "Error: Missing flush interval value!" << std::endl;
printUsage();
rocprofv2::print_usage(current_path);
exit(EXIT_FAILURE);
}
// Wrong argument given
// trace period
} else if (strcmp(argv[i], "-tp") == 0 || strcmp(argv[i], "--trace-period") == 0) {
i++;
if (argv[i]) {
pathenv.emplace_back("ROCPROFILER_TRACE_PERIOD=" + std::string(argv[i]));
} else {
std::cerr << "Error: Missing trace period value!" << std::endl;
rocprofv2::print_usage(current_path);
exit(EXIT_FAILURE);
}
// wrong argument given
} else if (argv[i][0] == '-') {
std::cerr << "Wrong option (" << argv[i] << "), Please use the following options:\n"
<< std::endl;
printUsage();
rocprofv2::print_usage(current_path);
exit(EXIT_FAILURE);
// Taking up the Application path with its arguments
// taking up the Application path with its arguments
} else {
app_path = argv[i];
app_argc_start = i;
@@ -216,7 +523,7 @@ int main(int argc, char** argv) {
}
}
// Getting Original Application Arguments
// getting original application arguments
char* app_args[argc - app_argc_start + 1];
int j = 0;
for (int i = app_argc_start; i < argc; i++) {
@@ -225,32 +532,40 @@ int main(int argc, char** argv) {
}
app_args[j] = NULL;
// Providing LD_PRELOAD of ROCProfiler Library to runApp function
std::string pathenv_str = "LD_PRELOAD=librocprofiler_tool.so";
std::string current_ld_preload;
if (getenv("LD_PRELOAD")) current_ld_preload = getenv("LD_PRELOAD");
if (strstr(bin_path.c_str(), "build") != nullptr)
pathenv_str = bin_path.replace_filename("librocprofiler_tool.so");
else
pathenv_str = bin_path.remove_filename().replace_filename("lib/librocprofiler_tool.so");
if (!current_ld_preload.empty())
pathenv_str = "LD_PRELOAD=" + current_ld_preload + ":" + pathenv_str;
else
pathenv_str = "LD_PRELOAD=" + current_ld_preload + pathenv_str;
pathenv.emplace_back(pathenv_str);
// Providing all Environment variables needed by the arguments
// providing all environment variables needed by the arguments
char* envp_run[pathenv.size() + 1];
for (uint32_t i = 0; i < pathenv.size(); i++)
envp_run[i] = const_cast<char*>(pathenv.at(i).c_str());
envp_run[pathenv.size()] = NULL;
// Getting Application Executable path to be provided to runApp function
// getting application executable path to be provided to run_application function
std::string app_path_str;
if (app_path) app_path_str = std::string(current_path) + "/" + std::string(app_path);
if (!fs::path(app_path).is_absolute()) {
app_path_str = std::string(current_path) + "/" + std::string(app_path);
} else {
app_path_str = app_path;
}
// providing metrics path
std::string metrics_path_str =
rocm_path.string() + "/libexec/rocprofiler/counters/derived_counters.xml";
pathenv.emplace_back("ROCPROFILER_METRICS_PATH=" + metrics_path_str);
// ATT: check if the att required environment variables are set.
if (!att_py_path.empty()) {
if (!att_argv.empty()) {
std::string command = att_pthon3_arg + " " + att_py_path.string() + " " + att_argv;
setenv("COUNTERS_PATH", att_input_path.c_str(), 1);
int status = system(command.c_str());
if (status < 0) {
std::cerr << "Invalid Command!" << std::endl;
return (EXIT_FAILURE);
}
}
}
// calling run_application function to execute the application with environment variables and
// original arguments
rocprofv2::run_application(app_path_str.c_str(), envp_run, app_args);
// Calling runApp function to execute the application with Environment
// variables and original arguments
runApp(app_path_str.c_str(), envp_run, app_args, number_of_passes);
return 1;
}
}
+16 -15
Просмотреть файл
@@ -309,11 +309,10 @@ att_parsed_input_t GetATTParams() {
// Default values used for token generation.
std::unordered_map<std::string, uint32_t> default_params = {
{"SE_MASK", 0x111111}, // One every 4 SEs, by default
{"SIMD_SELECT", 0x3}, // 0x3 works for both gfx9 and Navi
{"BUFFER_SIZE", 0x40000000}, // 2^30 == 1GB
{"ISA_CAPTURE_MODE", static_cast<uint32_t>(ROCPROFILER_CAPTURE_SYMBOLS_ONLY)}
};
{"SE_MASK", 0x111111}, // One every 4 SEs, by default
{"SIMD_SELECT", 0x3}, // 0x3 works for both gfx9 and Navi
{"BUFFER_SIZE", 0x40000000}, // 2^30 == 1GB
{"ISA_CAPTURE_MODE", static_cast<uint32_t>(ROCPROFILER_CAPTURE_SYMBOLS_ONLY)}};
std::ifstream trace_file(path);
if (!trace_file.is_open()) {
@@ -338,14 +337,15 @@ att_parsed_input_t GetATTParams() {
if (pos == std::string::npos) continue;
param_name = line.substr(0, pos);
for (auto& c : param_name) c = (char)toupper(c); // So we don't have to worry about lowercase inputs
line = line.substr(pos+1);
for (auto& c : param_name)
c = (char)toupper(c); // So we don't have to worry about lowercase inputs
line = line.substr(pos + 1);
}
if (param_name.find("ATT") != std::string::npos &&
param_name.find("TARGET_CU") != std::string::npos) {
started_att_counters = true; // Means we'll do ATT
param_name = "TARGET_CU"; // To cover different variations
started_att_counters = true; // Means we'll do ATT
param_name = "TARGET_CU"; // To cover different variations
}
if (!started_att_counters) continue;
@@ -364,7 +364,7 @@ att_parsed_input_t GetATTParams() {
int rank = (comma < line.size() - 1) ? stoi(line.substr(comma + 1)) : 0;
if (MPI_RANK < 0 || rank == MPI_RANK) // Only add ID if rank matches the one in input.txt
dispatch_ids.push_back(std::max(id-1,0)); // off by 1 in relation to kernel-trace
dispatch_ids.push_back(std::max(id - 1, 0)); // off by 1 in relation to kernel-trace
continue;
}
// param_value is a number
@@ -439,7 +439,7 @@ void finish() {
static bool env_var_search(std::string& s) {
std::smatch m;
std::regex e ("(.*)\\%\\q\\{([^}]+)\\}(.*)");
std::regex e("(.*)\\%\\q\\{([^}]+)\\}(.*)");
std::regex_match(s, m, e);
if (m.size() != 4) return false;
@@ -447,7 +447,7 @@ static bool env_var_search(std::string& s) {
while (m.size() == 4) {
const char* envvar = getenv(m[2].str().c_str());
if (!envvar) envvar = "";
s = m[1].str()+envvar+m[3].str();
s = m[1].str() + envvar + m[3].str();
std::regex_match(s, m, e);
};
@@ -482,12 +482,13 @@ void plugins_load(void* userdata) {
if (out_path.size()) {
try {
std::experimental::filesystem::create_directories(out_path);
} catch (...) {}
} catch (...) {
}
out_path = out_path + '/';
}
if (out_path.size() && getenv("ROCPROFILER_COUNTERS")) {
std::ofstream(out_path+"pmc.txt", std::ios::app)
<< std::string(getenv("ROCPROFILER_COUNTERS")) << '\n';
std::ofstream(out_path + "pmc.txt", std::ios::app)
<< std::string(getenv("ROCPROFILER_COUNTERS")) << '\n';
}
PluginHeaderPacket header{