diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bdc267e42ea931bffc45f509eaa964ad592d4680..7297b4d5273a81dedb14b5cd81124dff85a2b78f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(backends) -target_sources(nesmik PRIVATE delegator.cpp nesmik.cpp parallelism_helper.cpp) +add_subdirectory(utils) +target_sources(nesmik PRIVATE delegator.cpp nesmik.cpp) if(BUILD_C_FORTRAN) add_subdirectory(bindings) diff --git a/src/backends/detection/detection.cpp b/src/backends/detection/detection.cpp index 4217fbca8b418839a313195ef7f999fac8edb9bb..627ed18bc44d0207cf0b417eac2772b454abcb82 100644 --- a/src/backends/detection/detection.cpp +++ b/src/backends/detection/detection.cpp @@ -106,13 +106,18 @@ void DetectionStrategy::RegionStopLast( // two error checks are following if(region.stack_.empty()){ - std::cout << "neSmiK WARNING: The stack is already empty, so no more regions to close, but it tried to close " << region.name << std::endl; + if(verbose_mode_.getValue().value_or(false)) + { + std::cout << "neSmiK WARNING: The stack is already empty, so no more regions to close, but it tried to close " << region.name << std::endl; + } has_errors_ = true; return; } // now check if we actually pop the right name if(region.name.compare(region.stack_.top())!= 0){ + if(verbose_mode_.getValue().value_or(false)){ std::cout << "neSmiK WARNING: The stack says the next region to close is " << region.stack_.top() << " but tried closing " << region.name<< std::endl; + } has_errors_ = true; return; } diff --git a/src/backends/detection/detection.hpp b/src/backends/detection/detection.hpp index 1660b3860d410bad264f371cfa842c936108244a..1b9ca7da9aee0ace87a473bd4081d5e6ba2a5718 100644 --- a/src/backends/detection/detection.hpp +++ b/src/backends/detection/detection.hpp @@ -2,7 +2,8 @@ #define NESMIK_DETECTION_H #include -#include +#include +#include #include #include @@ -45,6 +46,8 @@ private: std::mutex starts_mutex_; std::mutex ends_mutex_; + EnvironmentVariable verbose_mode_ = + EnvironmentVariable("DETECTION_VERBOSE", "Enables the verbose mode in the detection backend",true); bool has_errors_ = false; diff --git a/src/backends/dlb/dlb_talp_tree/dlb_talp_tree.cpp b/src/backends/dlb/dlb_talp_tree/dlb_talp_tree.cpp index 4a39a40a42281348e33bab9512390e81281a1b94..62c3e2d973ee5b781beb6aacfddce60454b54fc5 100644 --- a/src/backends/dlb/dlb_talp_tree/dlb_talp_tree.cpp +++ b/src/backends/dlb/dlb_talp_tree/dlb_talp_tree.cpp @@ -13,7 +13,7 @@ #endif -#include +#include DLBTalpTreeStrategy::DLBTalpTreeStrategy():mpi_helper_{}{ parallelism_descriptor_={ diff --git a/src/backends/dlb/dlb_talp_tree/dlb_talp_tree.hpp b/src/backends/dlb/dlb_talp_tree/dlb_talp_tree.hpp index 9e62b3d02ed706b98d87652325e01924a7a725f3..83e51f7ea8ee262b09bf0002347b7011d262543a 100644 --- a/src/backends/dlb/dlb_talp_tree/dlb_talp_tree.hpp +++ b/src/backends/dlb/dlb_talp_tree/dlb_talp_tree.hpp @@ -8,7 +8,7 @@ #include #include -#include +#include struct TalpRegionNode { std::string name; diff --git a/src/parallelism_helper.cpp b/src/parallelism_helper.cpp deleted file mode 100644 index 52f43786908fe0ef9e447c29bb76e3bfc099cbaf..0000000000000000000000000000000000000000 --- a/src/parallelism_helper.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include - -#ifdef WITH_MPI - - -bool MPIHelper::IsUsingMPI()const -{ - return is_using_mpi_; - -} - -bool MPIHelper::CompiledWithMPI() const { - return true; -} - -bool MPIHelper::IsRankNumber(int asked_rank) const { - return asked_rank== mpi_comm_rank; -} - -int MPIHelper::getRankNumber() const{ - return mpi_comm_rank; -} - -MPIHelper::MPIHelper(){ - // First check if MPI is initialized - int is_initialized; - MPI_Initialized(&is_initialized); - mpi_is_initialized_ = static_cast(is_initialized); - - if(mpi_is_initialized_){ - MPI_Comm_size(MPI_COMM_WORLD,&mpi_comm_size); - MPI_Comm_rank(MPI_COMM_WORLD,&mpi_comm_rank); - - is_using_mpi_ = mpi_comm_size > 1; - } -} - -#else - - -bool MPIHelper::IsUsingMPI() const -{ - return false; -} - -bool MPIHelper::CompiledWithMPI() const { - return false; -} - -bool MPIHelper::IsRankNumber(int asked_rank) const { - return asked_rank==0; -} - - -int MPIHelper::getRankNumber() const{ - return mpi_comm_rank; -} - -MPIHelper::MPIHelper(){} - - -#endif \ No newline at end of file diff --git a/src/parallelism_helper.hpp b/src/parallelism_helper.hpp deleted file mode 100644 index 5aebb05a0ab2df42e68a52bb96d053e41aba2a85..0000000000000000000000000000000000000000 --- a/src/parallelism_helper.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef NESMIK_PARALLELISM_HELPER_HPP -#define NESMIK_PARALLELISM_HELPER_HPP -/* - Small helper class that can be used by Backends to Check MPI status in the application beeing run. -*/ -class MPIHelper{ - private: - - // Default values for non-MPI execution - bool is_using_mpi_ = false; - bool mpi_is_initialized_ = false; - int mpi_comm_size = 0; - int mpi_comm_rank = 0; - - public: - - MPIHelper(); - // returns if the library is compiled with MPI support - bool CompiledWithMPI() const ; - // Check is the application is actually using MPI with more than one process - bool IsUsingMPI() const; - // Checks if rank is a certain one, and 0 if MPI is not active - bool IsRankNumber(int asked_rank) const; - - int getRankNumber() const; - -}; - -#endif // NESMIK_PARALLELISM_HELPER_HPP \ No newline at end of file diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..369cedfeed5a75d18805932e80298436db34b79b --- /dev/null +++ b/src/utils/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(nesmik PRIVATE environment_variable.cpp parallelism_helper.cpp) \ No newline at end of file diff --git a/src/utils/environment_variable.cpp b/src/utils/environment_variable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5472e51d85841aad4b4a3cb05b20e2c7e38996b4 --- /dev/null +++ b/src/utils/environment_variable.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include + +#include "environment_variable.hpp" + +// some helper function to compare case insenstive strings +bool charToLowerEquals(char a, char b) { + return std::tolower(static_cast(a)) == + std::tolower(static_cast(b)); +} + +bool compareCaseInsenstive(const std::string &a, const std::string &b) { + return std::equal(a.begin(), a.end(), b.begin(), b.end(), charToLowerEquals); +} + +template <> std::optional fromEnvString(const std::string &env_string) { + if (compareCaseInsenstive(env_string, "0") || + compareCaseInsenstive(env_string, "false") || + compareCaseInsenstive(env_string, "off")) { + return std::optional{false}; + } else if (compareCaseInsenstive(env_string, "1") || + compareCaseInsenstive(env_string, "true") || + compareCaseInsenstive(env_string, "on")) { + return std::optional{true}; + } else { + return std::nullopt; + } +} \ No newline at end of file diff --git a/src/utils/environment_variable.hpp b/src/utils/environment_variable.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2e87a7476887d921e7637d7e0e1ec326f3bfd027 --- /dev/null +++ b/src/utils/environment_variable.hpp @@ -0,0 +1,55 @@ +#ifndef NESMIK_ENVIROMENT_VARIABLE_HPP +#define NESMIK_ENVIROMENT_VARIABLE_HPP +#include +#include +#include +#include +#include +#include + +// some helper function to compare case insenstive strings +bool charToLowerEquals(char a, char b); + +bool compareCaseInsenstive(const std::string &a, const std::string &b); + +// dont allow the compiler to guess, but force user to implement conversion +template +std::optional fromEnvString(const std::string &env_string) = delete; + +template <> std::optional fromEnvString(const std::string &env_string); + +template class EnvironmentVariable { + inline static std::string PREFIX = "NESMIK_"; +public: + /* + Upon construction it will do the getenv + */ + EnvironmentVariable(const std::string &variable_name, + const std::string &description, bool required = false) + : variable_name_(variable_name), description_(description) { + const std::string variable_to_query = + EnvironmentVariable::PREFIX + variable_name_; + + const char *env_string = std::getenv(variable_to_query.c_str()); + + if (env_string != nullptr) { + value_ = fromEnvString(std::string(env_string)); + } + if(required && !value_.has_value()){ + std::cout << "neSmiK Error: " << variable_to_query << " not set, restart application and set it" << std::endl; + exit(1); + } + } + EnvironmentVariable() = delete; + +private: + std::string variable_name_; + std::string description_; + std::optional value_; + +public: + std::optional getValue() const { return value_; } + bool isSet() const { return value_.has_value(); } +}; + +#endif // NESMIK_ENVIROMENT_VARIABLE_HPP \ No newline at end of file diff --git a/src/utils/parallelism_helper.cpp b/src/utils/parallelism_helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20c20147a09628510aef7239cdd6be7ecb71be09 --- /dev/null +++ b/src/utils/parallelism_helper.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#ifdef WITH_MPI + +bool MPIHelper::IsUsingMPI() const { return is_using_mpi_; } + +bool MPIHelper::CompiledWithMPI() const { return true; } + +bool MPIHelper::IsRankNumber(int asked_rank) const { + return asked_rank == mpi_comm_rank; +} + +int MPIHelper::getRankNumber() const { return mpi_comm_rank; } + +MPIHelper::MPIHelper() { + // First check if MPI is initialized + int is_initialized; + MPI_Initialized(&is_initialized); + mpi_is_initialized_ = static_cast(is_initialized); + + if (mpi_is_initialized_) { + MPI_Comm_size(MPI_COMM_WORLD, &mpi_comm_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_comm_rank); + + is_using_mpi_ = mpi_comm_size > 1; + } +} + +#else + +bool MPIHelper::IsUsingMPI() const { return false; } + +bool MPIHelper::CompiledWithMPI() const { return false; } + +bool MPIHelper::IsRankNumber(int asked_rank) const { return asked_rank == 0; } + +int MPIHelper::getRankNumber() const { return mpi_comm_rank; } + +MPIHelper::MPIHelper() {} + +#endif \ No newline at end of file diff --git a/src/utils/parallelism_helper.hpp b/src/utils/parallelism_helper.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e873bb3030028c5c86b2a02fd58702fb0efb3ca9 --- /dev/null +++ b/src/utils/parallelism_helper.hpp @@ -0,0 +1,27 @@ +#ifndef NESMIK_PARALLELISM_HELPER_HPP +#define NESMIK_PARALLELISM_HELPER_HPP +/* + Small helper class that can be used by Backends to Check MPI status in the + application beeing run. +*/ +class MPIHelper { +private: + // Default values for non-MPI execution + bool is_using_mpi_ = false; + bool mpi_is_initialized_ = false; + int mpi_comm_size = 0; + int mpi_comm_rank = 0; + +public: + MPIHelper(); + // returns if the library is compiled with MPI support + bool CompiledWithMPI() const; + // Check is the application is actually using MPI with more than one process + bool IsUsingMPI() const; + // Checks if rank is a certain one, and 0 if MPI is not active + bool IsRankNumber(int asked_rank) const; + + int getRankNumber() const; +}; + +#endif // NESMIK_PARALLELISM_HELPER_HPP \ No newline at end of file