-
Notifications
You must be signed in to change notification settings - Fork 0
Add runtime memory monitoring functions #2
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
31296c8
8fed5f7
6a8577a
443dbcc
5ce64a9
7678738
45f0022
ad51978
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,34 @@ | ||
| #ifndef KOKKOS_MEMINFO_HPP | ||
| #define KOKKOS_MEMINFO_HPP | ||
|
|
||
| #include <cstddef> | ||
| #include <Kokkos_Core.hpp> | ||
| #include <sstream> | ||
| #include <fstream> | ||
|
|
||
| #ifdef _WIN32 | ||
| #include <windows.h> | ||
| #else | ||
| #include <sys/sysinfo.h> | ||
| #endif | ||
|
|
||
| #include <Kokkos_Core.hpp> | ||
|
|
||
| namespace Kokkos { | ||
| namespace Experimental { | ||
|
|
||
| namespace { | ||
| constexpr int OVERCOMMIT_DISABLED = 2; | ||
| constexpr char COMMITTED_AS_KEY[] = "Committed_AS:"; | ||
| constexpr char COMMIT_LIMIT_KEY[] = "CommitLimit:"; | ||
| constexpr char MEMINFO_PATH[] = "/proc/meminfo"; | ||
| constexpr char OVERCOMMIT_PATH[] = "/proc/sys/vm/overcommit_memory"; | ||
| constexpr char MEM_FREE_KEY[] = "MemFree:"; | ||
| constexpr char MEM_TOTAL_KEY[] = "MemTotal:"; | ||
| constexpr char COMMITTED_AS_KEY[] = "Committed_AS:"; | ||
| constexpr char COMMIT_LIMIT_KEY[] = "CommitLimit:"; | ||
| constexpr char MEMINFO_PATH[] = "/proc/meminfo"; | ||
| constexpr char OVERCOMMIT_PATH[] = "/proc/sys/vm/overcommit_memory"; | ||
| } | ||
|
|
||
| // On some systems, overcommit is disabled, and the kernel does not allow | ||
| // memory allocation beyond the commit limit. This means that allocations | ||
| // that touch only a small amount of memory are still counted at their full size. | ||
| // man proc_sys_vm | ||
| bool is_overcommit_limit_set() { | ||
| bool is_overcommit_disabled() { | ||
| std::ifstream overcommit_file(OVERCOMMIT_PATH); | ||
| int overcommit_value = 0; | ||
|
|
||
|
|
@@ -72,17 +76,13 @@ void MemGetInfo<Kokkos::HostSpace>(size_t* free, size_t* total) { | |
| *total = statex.ullTotalPhys; | ||
| } | ||
| #else | ||
| static bool overcommit_limit = is_overcommit_limit_set(); | ||
| if (overcommit_limit) { | ||
| static bool overcommit_disabled = is_overcommit_disabled(); | ||
| if (overcommit_disabled) { | ||
| *total = get_meminfo_value(COMMIT_LIMIT_KEY); | ||
| *free = *total - get_meminfo_value(COMMITTED_AS_KEY); | ||
| return; | ||
| } | ||
| struct sysinfo info; | ||
| if (sysinfo(&info) == 0) { | ||
| *free = info.freeram * info.mem_unit; | ||
| *total = info.totalram * info.mem_unit; | ||
| return; | ||
| } else { | ||
| *total = get_meminfo_value(MEM_TOTAL_KEY); | ||
| *free = get_meminfo_value(MEM_FREE_KEY); | ||
| } | ||
|
||
| #endif | ||
| } | ||
|
|
@@ -127,3 +127,5 @@ void MemGetInfo<Kokkos::SYCLDeviceUSMSpace>(size_t* free, size_t* total) { | |
|
|
||
| } // namespace Experimental | ||
| } // namespace Kokkos | ||
|
|
||
| #endif // KOKKOS_MEMINFO_HPP | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,81 +1,61 @@ | ||
| #include <Kokkos_Core.hpp> | ||
| #include <cexa_MemInfo.hpp> | ||
| #include <gtest/gtest.h> | ||
|
|
||
| #include <cstddef> | ||
AdRi1t marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #include <type_traits> | ||
|
|
||
| #include <Kokkos_Core.hpp> | ||
| #include <gtest/gtest.h> | ||
|
|
||
| template <typename MemorySpace = void> | ||
| template <typename Space = Kokkos::DefaultExecutionSpace> | ||
| void testMemInfo() { | ||
| size_t step1_total = 0ul; | ||
| size_t step2_total = 0ul; | ||
| size_t step2_free = 0ul; | ||
| size_t step1_free = 0ul; | ||
| std::size_t step1_total = 0ul; | ||
| std::size_t step2_total = 0ul; | ||
| std::size_t step1_free = 0ul; | ||
| std::size_t step2_free = 0ul; | ||
|
|
||
| if constexpr (std::is_same<MemorySpace, void>::value) { | ||
| Kokkos::Experimental::MemGetInfo(&step1_free, &step1_total); | ||
| } else { | ||
| Kokkos::Experimental::MemGetInfo<MemorySpace>(&step1_free, &step1_total); | ||
| } | ||
| { | ||
| // Allocate 128 MiB of memory | ||
| Kokkos::View<double**, MemorySpace> data("data test", 128, 1024*1024); | ||
| if constexpr (std::is_same<MemorySpace, void>::value) { | ||
| Kokkos::Experimental::MemGetInfo(&step2_free, &step2_total); | ||
| } else { | ||
| Kokkos::Experimental::MemGetInfo<MemorySpace>(&step2_free, &step2_total); | ||
| } | ||
| } | ||
| Kokkos::Experimental::MemGetInfo<Space>(&step1_free, &step1_total); | ||
| // Allocate 64 MiB of memory | ||
| Kokkos::View<double**, typename Space::memory_space> data("data test", 1024, 8192); | ||
| Kokkos::fence(); | ||
| Kokkos::Experimental::MemGetInfo<Space>(&step2_free, &step2_total); | ||
|
||
| // Same total memory before and after aloccation | ||
| EXPECT_EQ(step1_total, step2_total); | ||
| // Check that free memory is less after allocation | ||
| EXPECT_LT(step2_free, step1_free); | ||
| } | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is repeating logic in the tests. The tests are one of the two types for different execution spaces: Kokkos::initialize(); size_t free = 0; But it is ok if you don't refactor. |
||
| TEST(MemInfo, HostSpace) { | ||
| Kokkos::initialize(); | ||
| testMemInfo<Kokkos::HostSpace>(); | ||
| Kokkos::finalize(); | ||
| } | ||
| TEST(MemInfo, HostSpaceUninitialized) { | ||
| size_t free = 0; | ||
| size_t total = 0; | ||
| Kokkos::Experimental::MemGetInfo<Kokkos::HostSpace>(&free, &total); | ||
| EXPECT_GT(free, 0); | ||
| EXPECT_GT(total, 0); | ||
| } | ||
| #define TEST_SPACE(Space) \ | ||
| TEST(MemInfo, Space) { \ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are calling the function |
||
| testMemInfo<Kokkos::Space>(); \ | ||
| } | ||
|
|
||
| TEST(MemInfo, DefaultSpace) { | ||
| Kokkos::initialize(); | ||
| testMemInfo<>(); | ||
| Kokkos::finalize(); | ||
| } | ||
| TEST(MemInfo, DefaultSpaceUninitialized) { | ||
| size_t free = 0; | ||
| size_t total = 0; | ||
| Kokkos::Experimental::MemGetInfo(&free, &total); | ||
| EXPECT_GT(free, 0); | ||
| EXPECT_GT(total, 0); | ||
| } | ||
|
|
||
| TEST_SPACE(HostSpace) | ||
|
|
||
| #if defined(KOKKOS_ENABLE_CUDA) | ||
| TEST(MemInfo, CudaSpace) { | ||
| Kokkos::initialize(); | ||
| testMemInfo<Kokkos::CudaSpace>(); | ||
| testMemInfo<Kokkos::SharedSpace>(); | ||
| Kokkos::finalize(); | ||
| } | ||
| TEST_SPACE(CudaSpace) | ||
| TEST_SPACE(SharedSpace) | ||
| #endif | ||
|
|
||
| #if defined(KOKKOS_ENABLE_HIP) | ||
| TEST(MemInfo, HIPSpace) { | ||
| Kokkos::initialize(); | ||
| testMemInfo<Kokkos::HIPSpace>(); | ||
| testMemInfo<Kokkos::SharedSpace>(); | ||
| Kokkos::finalize(); | ||
| } | ||
| TEST_SPACE(HIPSpace) | ||
| TEST_SPACE(SharedSpace) | ||
| #endif | ||
|
|
||
| #if defined(KOKKOS_ENABLE_SYCL) | ||
| TEST_SPACE(SYCLDeviceUSMSpace) | ||
| TEST_SPACE(SharedSpace) | ||
| #endif | ||
|
|
||
AdRi1t marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| int main(int argc, char *argv[]) { | ||
| Kokkos::initialize(argc, argv); | ||
| ::testing::InitGoogleTest(&argc, argv); | ||
| int result = RUN_ALL_TESTS(); | ||
| Kokkos::finalize(); | ||
| return result; | ||
science-enthusiast marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| #undef TEST_SPACE | ||
Uh oh!
There was an error while loading. Please reload this page.