Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/gridedit 589 query sys mem bench #196

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a444767
refinement in spherical coordinates (GRIDEDIT-556 | #170)
lucacarniato Jun 13, 2023
6ebc7ec
Added missing ZLIB_ROOT option to CMake config of NetCDF (#171)
ahmad-el-sayed Jun 14, 2023
fffad73
Include wix installer files in repository (#172 | GRIDEDIT-546)
ahmad-el-sayed Jun 19, 2023
8d64a8e
Added workflow for building on macOS (#174 | GRIDEDIT-558, GRIDEDIT-558)
ahmad-el-sayed Jun 19, 2023
0839366
Reduced NetCDF cache size in macOS build (#175 | GRIDEDIT-566)
ahmad-el-sayed Jun 20, 2023
867d952
Make uniform grid on a desired extension (#177 | GRIDEDIT-570)
lucacarniato Jun 23, 2023
658ebad
Add more exceptions (#178 | GRIDEDIT-583)
lucacarniato Jun 27, 2023
a52cb47
Improve refinement based on gridded samples ( #179 | GRIDEDIT-584 )
lucacarniato Jun 28, 2023
4fcf65f
Fix a bug in computing an uniform mesh in spherical coordinate ( #181…
lucacarniato Jun 28, 2023
8b058e0
Added static lib for memory query
ahmad-el-sayed Jun 29, 2023
592087b
Change default values in MakeGridParameters and SplinesToCurvilinearP…
lucacarniato Jun 29, 2023
f1665fa
Merge remote-tracking branch 'origin/release/v2.0.0' into feature/GRI…
ahmad-el-sayed Jun 29, 2023
c4dc6a6
Vector performance enhancements (#182 | GRIDEDIT-588)
BillSenior Jun 29, 2023
4272640
Added celero unit test
ahmad-el-sayed Jun 29, 2023
0a967f8
Merge remote-tracking branch 'origin/release/v2.0.0' into feature/GRI…
ahmad-el-sayed Jun 29, 2023
b4b5bc2
Modernise
ahmad-el-sayed Jun 30, 2023
19771cc
Merge branch 'master' into feature/GRIDEDIT-589_query_sys_mem_bench
ahmad-el-sayed Jul 7, 2023
380a3cf
Merge remote-tracking branch 'origin/master' into feature/GRIDEDIT-58…
ahmad-el-sayed Jul 7, 2023
ac8ea71
Reworked linux memory monitor
ahmad-el-sayed Jul 10, 2023
085334d
Fixed stats
ahmad-el-sayed Jul 11, 2023
6f6ab52
Refactored, now a factory
ahmad-el-sayed Jul 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion cmake/options.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
include(CMakeDependentOption)

# unit testing option
option(
ENABLE_UNIT_TESTING
Expand All @@ -13,7 +15,6 @@ option(
)

# memory usgae reporting option
include(CMakeDependentOption)
cmake_dependent_option(
ENABLE_BENCHMARKING_MEM_REPORT
"When benchmarking is enabled, enables reporting memory usage statistics."
Expand All @@ -22,6 +23,18 @@ cmake_dependent_option(
OFF
)

if(ENABLE_BENCHMARKING_MEM_REPORT)
set(
MEM_COLLECTION_METHOD ""
CACHE STRING
"When memory reporting is enabled, specifies how memory metrics are collected."
)
if( NOT (MEM_COLLECTION_METHOD STREQUAL "QUERY_SYSTEM" OR MEM_COLLECTION_METHOD STREQUAL "COUNT_BYTES"))
message(WARNING "Option MEM_COLLECTION_METHOD not set. QUERY_SYSTEM will be used.")
set(MEM_COLLECTION_METHOD "QUERY_SYSTEM")
endif()
endif()

# code coverage option
if(LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
option(
Expand Down
32 changes: 26 additions & 6 deletions libs/MeshKernel/benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,38 @@ target_link_libraries(
)

if(ENABLE_BENCHMARKING_MEM_REPORT)
# link memory manager
target_link_libraries(
${TARGET_NAME}
PRIVATE
MeshKernelBenchmarkMemoryManager
)
# add compiler definition for reporting the memory statistics in src
target_compile_definitions(
${TARGET_NAME}
PRIVATE
ENABLE_BENCHMARKING_MEM_REPORT
)

if(MEM_COLLECTION_METHOD STREQUAL "QUERY_SYSTEM")
# link memory manager
target_link_libraries(
${TARGET_NAME}
PRIVATE
MeshKernelBenchmarkMemorySystemQuery
)
target_compile_definitions(
${TARGET_NAME}
PRIVATE
MEM_COLLECTION_METHOD_QUERY_SYSTEM
)
elseif(MEM_COLLECTION_METHOD STREQUAL "COUNT_BYTES")
# link memory manager
target_link_libraries(
${TARGET_NAME}
PRIVATE
MeshKernelBenchmarkMemoryManager
)
target_compile_definitions(
${TARGET_NAME}
PRIVATE
MEM_COLLECTION_METHOD_COUNT_BYTES
)
endif()
endif()

# group the sources
Expand Down
8 changes: 8 additions & 0 deletions libs/MeshKernel/benchmark/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#include <benchmark/benchmark.h>

#ifdef ENABLE_BENCHMARKING_MEM_REPORT
#if defined(MEM_COLLECTION_METHOD_COUNT_BYTES)
#include "custom_memory_manager.hpp"
#elif defined(MEM_COLLECTION_METHOD_QUERY_SYSTEM)
#include "memory_system_query.hpp"
#endif
#endif

int main(int argc, char** argv)
Expand All @@ -16,7 +20,11 @@ int main(int argc, char** argv)
::benchmark::Initialize(&argc, argv);
::benchmark::SetDefaultTimeUnit(::benchmark::kMillisecond);
#ifdef ENABLE_BENCHMARKING_MEM_REPORT
#if defined(MEM_COLLECTION_METHOD_COUNT_BYTES)
::benchmark::RegisterMemoryManager(&CUSTOM_MEMORY_MANAGER);
#elif defined(MEM_COLLECTION_METHOD_QUERY_SYSTEM)
::benchmark::RegisterMemoryManager(&MEMORY_SYSTEM_QUERY);
#endif
#endif
if (::benchmark::ReportUnrecognizedArguments(argc, argv))
{
Expand Down
6 changes: 5 additions & 1 deletion tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ add_subdirectory(Version)
# Add custom_memory_manager
# This target is built only if benchmarking with memory reporting is enabled
if(ENABLE_BENCHMARKING AND ENABLE_BENCHMARKING_MEM_REPORT)
add_subdirectory(custom_memory_manager)
if(MEM_COLLECTION_METHOD STREQUAL "COUNT_BYTES")
add_subdirectory(custom_memory_manager)
elseif(MEM_COLLECTION_METHOD STREQUAL "QUERY_SYSTEM")
add_subdirectory(memory_system_query)
endif()
endif()

# Add test utilities
Expand Down
62 changes: 62 additions & 0 deletions tools/memory_system_query/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# project name
project(
MeshKernelBenchmarkMemorySystemQuery
VERSION ${CMAKE_PROJECT_VERSION}
DESCRIPTION "MeshKernel benchmark memory system query"
LANGUAGES CXX
)

# target name
set(TARGET_NAME ${PROJECT_NAME})

# executable
add_library(${TARGET_NAME} STATIC)

# source directories
set(SRC_DIR ${PROJECT_SOURCE_DIR}/src)

# include directories
set(INC_DIR ${PROJECT_SOURCE_DIR}/include)

# list of target sources
set(
SRC_LIST
${SRC_DIR}/memory_system_query.cpp
)

# list of tagret headers
set(
INC_LIST
${INC_DIR}/memory_system_query.hpp
${INC_DIR}/memory_monitor.hpp
${INC_DIR}/memory_monitor_linux.hpp
${INC_DIR}/memory_monitor_windows.hpp
${INC_DIR}/memory_monitor_factory.hpp
)

# add sources to target
target_sources(
${TARGET_NAME}
PRIVATE
${SRC_LIST}
PUBLIC
FILE_SET HEADERS
BASE_DIRS ${INC_DIR}
FILES ${INC_LIST}
)

# specify libraries to be linked to the executable
target_link_libraries(
${TARGET_NAME}
PRIVATE
benchmark::benchmark
)

# group the sources and headers
source_group("Source Files" FILES ${SRC_LIST})
source_group("Header Files" FILES ${INC_LIST})

# add unit tests subdirectory
if(ENABLE_UNIT_TESTING)
add_subdirectory(tests)
endif()
45 changes: 45 additions & 0 deletions tools/memory_system_query/include/memory_monitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <cstdint>

enum class MemoryType
{
Physical = 0,
PhysicalPeak = 1,
Virtual = 2,
VirtualPeak = 3
};

class MemoryMonitor
{
public:
MemoryMonitor() = default;
virtual ~MemoryMonitor() = default;
// non-copyable
MemoryMonitor(const MemoryMonitor& other) = delete;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might move all deleted constructors and operators to private

MemoryMonitor& operator=(const MemoryMonitor& other) = delete;
MemoryMonitor(MemoryMonitor&& other) = delete;
MemoryMonitor& operator=(MemoryMonitor&& other) = delete;

/// @brief Gets the memory usage my type
/// @param memory_type The type of requested memory usage
/// @return The memory usage
virtual uint64_t Usage(MemoryType memory_type) const = 0;

/// @brief Convenience method that returns the total current physical and virtual usage
/// @return The total current physical and virtual usage
uint64_t CurrentUsage() const
{
return Usage(MemoryType::Physical) + Usage(MemoryType::Virtual);
}

/// @brief Convenience method that returns the total peak physical and virtual usage
/// @return The total peak physical and virtual usage
uint64_t PeakUsage() const
{
return Usage(MemoryType::PhysicalPeak) + Usage(MemoryType::VirtualPeak);
}

private:
inline static uint64_t constexpr kilobyte = 1024;
};
23 changes: 23 additions & 0 deletions tools/memory_system_query/include/memory_monitor_factory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <iostream>
#include <memory>

#if defined(_WIN32)
#include "memory_monitor_windows.hpp"
#elif defined(__linux__)
#include "memory_monitor_linux.hpp"
#else
#error "Unsupported platform"
#endif

inline static std::unique_ptr<MemoryMonitor> CreateMemoryMonitor()
{
#if defined(_WIN32)
return std::make_unique<WindowsMemoryMonitor>();
#elif defined(__linux__)
return std::make_unique<LinuxMemoryMonitor>();
#else
#error "Unsupported platform"
#endif
}
123 changes: 123 additions & 0 deletions tools/memory_system_query/include/memory_monitor_linux.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#ifdef __linux__

#pragma once

#include <filesystem>
#include <fstream>
#include <map>
#include <stdexcept>
#include <string>

#include <cmath>
#include <cstdint>

#include <unistd.h>

#include "memory_monitor.hpp"

class LinuxMemoryMonitor final : public MemoryMonitor
{
public:
LinuxMemoryMonitor()
{
std::filesystem::path path("/proc");
path /= std::to_string(getpid());
path /= "status";
m_path_str = path.string();
std::cout << m_path_str << std::endl;
}

~LinuxMemoryMonitor() = default;

// non-copyable
LinuxMemoryMonitor(const LinuxMemoryMonitor&) = delete;
LinuxMemoryMonitor& operator=(const LinuxMemoryMonitor&) = delete;
LinuxMemoryMonitor(LinuxMemoryMonitor&&) = delete;
LinuxMemoryMonitor& operator=(LinuxMemoryMonitor&&) = delete;

uint64_t Usage(MemoryType memory_type) const override
{
uint64_t usage = 0;
std::ifstream file(m_path_str);
std::string line;

std::string const memory_type_str = memory_type_map.at(memory_type);
while (std::getline(file, line))
{
if (line.find(memory_type_str) != std::string::npos)
{
usage = Bytes(line);
/*if (memory_type == MemoryType::Physical)
{
usage *= page_size;
}*/
break;
}
}
return usage;
}

private:
std::string m_path_str;

inline static std::map<MemoryType, std::string> const memory_type_map = {
{MemoryType::Physical, "VmRSS"},
{MemoryType::PhysicalPeak, "VmHWM"},
{MemoryType::Virtual, "VmSize"},
{MemoryType::VirtualPeak, "VmPeak"} //
};

inline static std::map<char, uint64_t> unit_prefix_map = {
{'k', 1}, // kilo
{'K', 1}, // Kilo
{'m', 2}, // mega
{'M', 2}, // Mega
{'g', 3}, // giga
{'G', 3} // Giga
};

inline static uint64_t constexpr kilobyte = 1024;

inline static uint64_t const page_size = sysconf(_SC_PAGE_SIZE); // in bytes

static uint64_t ConversionFactor(std::string const& unit)
{
uint64_t conversion_factor = 1;
char const byte = unit[1];
if (byte == 'b' || byte == 'B')
{
char const unit_prefix = unit[0];
conversion_factor = std::pow(kilobyte, unit_prefix_map.at(unit_prefix));
}
else
{
throw std::runtime_error("Memory is not measured bytes");
}
return conversion_factor;
}

// ex: VmPeak: 4296 kB
// KEY: VALUE UNIT
// > < key
// > < colon
// > < tab
// > < spaces
// > < value
// > < space
// > < unit (2 chars)
// position of colon separating the key from the value

static uint64_t Bytes(std::string& line)
{
size_t const key_end_pos = line.find(':');
size_t const value_start_pos = line.find_first_not_of('\t', key_end_pos + 1);
size_t const value_end_pos = line.size() - 2;
std::string const value(line.begin() + value_start_pos, line.begin() + value_end_pos);
uint64_t const usage = std::stoull(value.c_str());
std::string const unit(line.begin() + value_end_pos, line.end());
uint64_t const conversion_factor = ConversionFactor(unit);
return usage * conversion_factor;
}
};

#endif
Loading