diff --git a/CMakeLists.txt b/CMakeLists.txt index 472b02b0..71deba9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,8 +136,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) set(DLIO_PROFILER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/brahma/posix.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/brahma/stdio.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/dlio_profiler.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/dlio_profiler/dlio_profiler.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/dlio_profiler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/writer/chrome_writer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/utils/posix_internal.cpp) set(DLIO_PROFILER_PUBLIC_INCLUDE @@ -147,6 +146,7 @@ set(DLIO_PROFILER_PUBLIC_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/include/dlio_profiler/dlio_profiler.h) set(DLIO_PROFILER_PRIVATE_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/dlio_logger.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/core/dlio_profiler_main.h ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/core/constants.h ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/utils/posix_internal.h ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/utils/utils.h) diff --git a/include/dlio_profiler/dlio_profiler.h b/include/dlio_profiler/dlio_profiler.h index 098251c8..d8029e62 100644 --- a/include/dlio_profiler/dlio_profiler.h +++ b/include/dlio_profiler/dlio_profiler.h @@ -3,7 +3,7 @@ // #ifndef DLIO_PROFILER_DLIO_PROFILER_H -#define DLIO_PROFILER_DLIO_PROFILER_H +#define DLIO_PROFILER_DLIO_PROFILER_LIB_H #include #include #include diff --git a/src/dlio_profiler/core/constants.h b/src/dlio_profiler/core/constants.h new file mode 100644 index 00000000..e67c5a14 --- /dev/null +++ b/src/dlio_profiler/core/constants.h @@ -0,0 +1,13 @@ +// +// Created by haridev on 10/5/23. +// + +#ifndef DLIO_PROFILER_CONSTANTS_H +#define DLIO_PROFILER_CONSTANTS_H +#define DLIO_PROFILER_ENABLE "DLIO_PROFILER_ENABLE" +#define DLIO_PROFILER_GOTCHA_PRIORITY "DLIO_PROFILER_GOTCHA_PRIORITY" +#define DLIO_PROFILER_LOG_LEVEL "DLIO_PROFILER_LOG_LEVEL" +#define DLIO_PROFILER_LOG_FILE "DLIO_PROFILER_LOG_FILE" +#define DLIO_PROFILER_INIT "DLIO_PROFILER_INIT" +#define DLIO_PROFILER_DATA_DIR "DLIO_PROFILER_DATA_DIR" +#endif //DLIO_PROFILER_CONSTANTS_H diff --git a/src/dlio_profiler/core/dlio_profiler_main.h b/src/dlio_profiler/core/dlio_profiler_main.h new file mode 100644 index 00000000..46cc6d16 --- /dev/null +++ b/src/dlio_profiler/core/dlio_profiler_main.h @@ -0,0 +1,132 @@ +// +// Created by haridev on 10/5/23. +// + +#ifndef DLIO_PROFILER_DLIO_PROFILER_MAIN_H +#define DLIO_PROFILER_DLIO_PROFILER_MAIN_H +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "singleton.h" + +static void handler(int sig) { + void *array[10]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, 10); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, STDERR_FILENO); + exit(1); +} + +namespace dlio_profiler { + class DLIOProfiler { + private: + bool is_enabled; + int gotcha_priority; + cpplogger::LoggerType logger_level; + char* log_file; + char* data_dirs; + int process_id; + bool is_init; + public: + DLIOProfiler(bool is_init, const char *log_file = nullptr, const char *data_dirs = nullptr, const int *process_id = nullptr) : is_enabled( + false), gotcha_priority(1), logger_level(cpplogger::LoggerType::LOG_ERROR), log_file(nullptr), data_dirs( + nullptr), is_init(is_init) { + signal(SIGSEGV, handler); + if (this->is_init) { + char *dlio_profiler_enable = getenv(DLIO_PROFILER_ENABLE); + if (dlio_profiler_enable != nullptr && strcmp(dlio_profiler_enable, "1") == 0) { + is_enabled = true; + } + if (is_enabled) { + char *dlio_profiler_priority_str = getenv(DLIO_PROFILER_GOTCHA_PRIORITY); + if (dlio_profiler_priority_str != nullptr) { + gotcha_priority = atoi(dlio_profiler_priority_str); + } + char *dlio_profiler_log_level = getenv(DLIO_PROFILER_LOG_LEVEL); + if (dlio_profiler_log_level == nullptr) { + logger_level = cpplogger::LoggerType::LOG_ERROR; + } else { + if (strcmp(dlio_profiler_log_level, "ERROR") == 0) { + logger_level = cpplogger::LoggerType::LOG_ERROR; + } else if (strcmp(dlio_profiler_log_level, "INFO") == 0) { + logger_level = cpplogger::LoggerType::LOG_INFO; + } else if (strcmp(dlio_profiler_log_level, "DEBUG") == 0) { + logger_level = cpplogger::LoggerType::LOG_WARN; + } + } + DLIO_PROFILER_LOGGER->level = logger_level; + DLIO_PROFILER_LOGINFO("Enabling logging level %d", logger_level); + + if (log_file == nullptr) { + char *dlio_profiler_log = getenv(DLIO_PROFILER_LOG_FILE); + if (dlio_profiler_log != nullptr) { + this->log_file = dlio_profiler_log; + } else { + const char *message = "log_file not defined. Please define env variable DLIO_PROFILER_LOG_FILE"; + DLIO_PROFILER_LOGERROR(message, ""); + throw std::runtime_error(message); + } + } + + if (data_dirs == nullptr) { + char *dlio_profiler_data_dirs = getenv(DLIO_PROFILER_DATA_DIR); + if (dlio_profiler_data_dirs != nullptr) { + this->data_dirs = dlio_profiler_data_dirs; + } else { + const char *message = "data_dirs not defined. Please define env variable DLIO_PROFILER_DATA_DIR"; + DLIO_PROFILER_LOGERROR(message, ""); + throw std::runtime_error(message); + } + } + + if (process_id == nullptr) { + this->process_id = getpid(); + } else { + this->process_id = *process_id; + } + + dlio_profiler::Singleton::get_instance()->update_log_file(this->log_file, this->process_id); + brahma_gotcha_wrap("dlio_profiler", this->gotcha_priority); + auto posix_instance = brahma::POSIXDLIOProfiler::get_instance(); + auto stdio_instance = brahma::STDIODLIOProfiler::get_instance(); + auto paths = split(this->data_dirs, ':'); + posix_instance->untrace(this->log_file); + stdio_instance->untrace(this->log_file); + for (const auto &path:paths) { + DLIO_PROFILER_LOGINFO("Profiler will trace %s\n", path.c_str()); + posix_instance->trace(path.c_str()); + stdio_instance->trace(path.c_str()); + } + size_t thread_hash = std::hash{}(std::this_thread::get_id()); + DLIO_PROFILER_LOGINFO("Running DLIO Profiler on thread %ld and pid %ld", thread_hash, this->process_id); + } + } + } + bool finalize() { + if (is_init && is_enabled) { + DLIO_PROFILER_LOGINFO("Calling finalize", ""); + dlio_profiler::Singleton::get_instance(false)->finalize(); + free_bindings(); + return true; + } + return false; + } + }; +} // namespace dlio_profiler + + +#endif //DLIO_PROFILER_DLIO_PROFILER_MAIN_H diff --git a/src/dlio_profiler/core/error.h b/src/dlio_profiler/core/error.h new file mode 100644 index 00000000..dfd5372a --- /dev/null +++ b/src/dlio_profiler/core/error.h @@ -0,0 +1,8 @@ +// +// Created by haridev on 10/5/23. +// + +#ifndef DLIO_PROFILER_ERROR_H +#define DLIO_PROFILER_ERROR_H + +#endif //DLIO_PROFILER_ERROR_H diff --git a/src/dlio_profiler/dlio_profiler.cpp b/src/dlio_profiler/dlio_profiler.cpp index cfcb5c35..46e287a5 100644 --- a/src/dlio_profiler/dlio_profiler.cpp +++ b/src/dlio_profiler/dlio_profiler.cpp @@ -9,6 +9,9 @@ #include #include #include +#include +#include + namespace dlio_profiler { bool init = false; } @@ -16,75 +19,18 @@ namespace dlio_profiler { bool is_init() {return dlio_profiler::init;} void set_init(bool _init) { dlio_profiler::init = _init;} void dlio_profiler_init(void) { - bool init_log = false; - char *ld_preload = getenv("LD_PRELOAD"); - if (ld_preload != nullptr && std::string(ld_preload).find("libdlio_profiler.so") != std::string::npos) { - init_log = true; - } - if (!is_init()) { - char *dlio_profiler_enable = getenv("DLIO_PROFILER_ENABLE"); - if (dlio_profiler_enable == nullptr || strcmp(dlio_profiler_enable, "1") == 0) { - char *dlio_profiler_debug = getenv("DLIO_PROFILER_DEBUG"); - if (dlio_profiler_debug != nullptr) { - if (strcmp(dlio_profiler_debug, "1") == 0) { - std::string sp; - std::ifstream("/proc/self/cmdline") >> sp; - std::replace(sp.begin(), sp.end() - 1, '\000', ' '); - fprintf(stderr, "Connect to pid %d %s\n", getpid(), sp.c_str()); - fflush(stderr); - getchar(); - } - } - DLIO_PROFILER_LOGINFO("constructor", ""); - char *dlio_profiler_log_level = getenv("DLIO_PROFILER_LOG_LEVEL"); - if (dlio_profiler_log_level == nullptr) { - DLIO_PROFILER_LOGGER->level = cpplogger::LoggerType::LOG_ERROR; - DLIO_PROFILER_LOGINFO("Enabling ERROR loggin", ""); - } else { - if (strcmp(dlio_profiler_log_level, "ERROR") == 0) { - DLIO_PROFILER_LOGGER->level = cpplogger::LoggerType::LOG_ERROR; - DLIO_PROFILER_LOGINFO("Enabling ERROR loggin", ""); - } else if (strcmp(dlio_profiler_log_level, "INFO") == 0) { - DLIO_PROFILER_LOGGER->level = cpplogger::LoggerType::LOG_INFO; - DLIO_PROFILER_LOGINFO("Enabling INFO loggin", ""); - } else if (strcmp(dlio_profiler_log_level, "DEBUG") == 0) { - DLIO_PROFILER_LOGINFO("Enabling DEBUG loggin", ""); - DLIO_PROFILER_LOGGER->level = cpplogger::LoggerType::LOG_WARN; - } - } - char *dlio_profiler_priority_str = getenv("DLIO_PROFILER_GOTCHA_PRIORITY"); - int dlio_profiler_priority = 1; - if (dlio_profiler_priority_str != nullptr) { - dlio_profiler_priority = atoi(dlio_profiler_priority_str); - } - /* - dlio_profiler::Singleton::get_instance(init_log); - brahma_gotcha_wrap("dlio_profiler", dlio_profiler_priority); - auto posix_instance = brahma::POSIXDLIOProfiler::get_instance(); - auto stdio_instance = brahma::STDIODLIOProfiler::get_instance(); - char *dlio_profiler_dir = getenv("DLIO_PROFILER_DIR"); - if (dlio_profiler_dir != nullptr) { - auto paths = split(dlio_profiler_dir, ':'); - for (const auto &path:paths) { - DLIO_PROFILER_LOGINFO("Profiler will trace %s\n", path.c_str()); - posix_instance->trace(path); - stdio_instance->trace(path); - } - } - */ - } + char *init_type = getenv(DLIO_PROFILER_INIT); + if (!is_init() && init_type != nullptr && strcmp(init_type, "PRELOAD") == 0) { + dlio_profiler::Singleton::get_instance(true); + DLIO_PROFILER_LOGINFO("Running initialize within constructor", ""); set_init(true); } - size_t thread_hash = std::hash{}(std::this_thread::get_id()); - DLIO_PROFILER_LOGINFO("Running DLIO Profiler on thread %ld and pid %ld", thread_hash, getpid()); } void dlio_profiler_fini(void) { - if (is_init()) { - char *dlio_profiler_init = getenv("DLIO_PROFILER_INIT"); - if (dlio_profiler_init == nullptr || strcmp(dlio_profiler_init, "1") == 0) { - free_bindings(); - } + char *init_type = getenv(DLIO_PROFILER_INIT); + if (is_init() && init_type != nullptr && strcmp(init_type, "PRELOAD")) { + dlio_profiler::Singleton::get_instance(false)->finalize(); set_init(false); } } \ No newline at end of file diff --git a/src/dlio_profiler/dlio_profiler_py.cpp b/src/dlio_profiler/dlio_profiler_py.cpp index c26434ce..70e0263d 100644 --- a/src/dlio_profiler/dlio_profiler_py.cpp +++ b/src/dlio_profiler/dlio_profiler_py.cpp @@ -1,8 +1,6 @@ #include #include -#include -#include #include #include #include @@ -14,42 +12,18 @@ #include #include #include +#include +#include namespace py = pybind11; namespace dlio_profiler { - void handler(int sig) { - void *array[10]; - size_t size; - // get void*'s for all entries on the stack - size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, STDERR_FILENO); - exit(1); - } void initialize(std::string &log_file, std::string &data_dirs, int process_id) { - signal(SIGSEGV, handler); - if (process_id <= 0) DLIO_PROFILER_LOGPRINT("log_file %s data_dirs %s and process %d\n", log_file.c_str(), data_dirs.c_str(), process_id); - dlio_profiler::Singleton::get_instance()->update_log_file(log_file, process_id); - char *dlio_profiler_priority_str = getenv("DLIO_PROFILER_GOTCHA_PRIORITY"); - int dlio_profiler_priority = 1; - if (dlio_profiler_priority_str != nullptr) { - dlio_profiler_priority = atoi(dlio_profiler_priority_str); - } - brahma_gotcha_wrap("dlio_profiler", dlio_profiler_priority); - auto posix_instance = brahma::POSIXDLIOProfiler::get_instance(); - auto stdio_instance = brahma::STDIODLIOProfiler::get_instance(); - auto paths = split(data_dirs, ':'); - posix_instance->untrace(log_file.c_str()); - stdio_instance->untrace(log_file.c_str()); - for (const auto &path:paths) { - DLIO_PROFILER_LOGINFO("Profiler will trace %s\n", path.c_str()); - posix_instance->trace(path.c_str()); - stdio_instance->trace(path.c_str()); + char *init_type = getenv(DLIO_PROFILER_INIT); + if (init_type == nullptr || strcmp(init_type, "FUNCTION") == 0) { + dlio_profiler::Singleton::get_instance(true, log_file.c_str(), data_dirs.c_str(), &process_id); } } TimeResolution get_time() { @@ -66,8 +40,10 @@ namespace dlio_profiler { dlio_profiler::Singleton::get_instance(false)->log(name, cat, start_time, duration, args); } void finalize() { - DLIO_PROFILER_LOGINFO("Calling finalize", ""); - dlio_profiler::Singleton::get_instance(false)->finalize(); + char *init_type = getenv(DLIO_PROFILER_INIT); + if (init_type == nullptr || strcmp(init_type, "FUNCTION") == 0) { + dlio_profiler::Singleton::get_instance(false)->finalize(); + } } } // dlio_profiler PYBIND11_MODULE(dlio_profiler_py, m) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fad09792..6829d32c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,20 +1,19 @@ - -set(TEST_BASIC_SRC test.cpp) -add_executable(test_basic ${TEST_BASIC_SRC}) +add_executable(test_basic test.cpp) add_dependencies(test_basic ${PROJECT_NAME}) -file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/data) -file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/log) -add_test(test ${CMAKE_BINARY_DIR}/bin/test_basic ${CMAKE_BINARY_DIR}/data/file.dat) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data) +add_test(test ${CMAKE_BINARY_DIR}/bin/test_basic) set_property(TEST test APPEND PROPERTY ENVIRONMENT LD_PRELOAD=${CMAKE_BINARY_DIR}/lib/libdlio_profiler.so) set_property(TEST test APPEND PROPERTY ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib) -set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_DIR=${CMAKE_BINARY_DIR}/data) -set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_LOG_DIR=${CMAKE_SOURCE_DIR}/log) +set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_ENABLE=1) +set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_INIT=PRELOAD) +set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_DATA_DIR=${CMAKE_CURRENT_BINARY_DIR}/data) +set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_LOG_FILE=${CMAKE_BINARY_DIR}/log_cpp.pwf) set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_LOG_LEVEL=INFO) find_program(PYTHON_EXE python) message("-- Found python at location " ${PYTHON_EXE}) add_test(test_py ${PYTHON_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py) -file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/test/data) set_property(TEST test_py APPEND PROPERTY ENVIRONMENT PYTHONPATH=$ENV{PYTHONPATH}:${CMAKE_SOURCE_DIR}/venv/lib) set_property(TEST test_py APPEND PROPERTY ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib:${CMAKE_SOURCE_DIR}/dependency/.spack-env/view/lib64) +set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_ENABLE=1) set_property(TEST test_py APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_LOG_LEVEL=INFO) diff --git a/test/test.cpp b/test/test.cpp index 01a4d618..fc83ce6f 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -5,5 +5,8 @@ #include int main(int argc, char* argv[]) { + FILE* fh = fopen("./data/demofile.txt", "w+"); + fwrite("hello", sizeof("hello"), 1, fh); + fclose(fh); return 0; } \ No newline at end of file