-
Notifications
You must be signed in to change notification settings - Fork 23
/
memorytracking.cpp
90 lines (74 loc) · 2.69 KB
/
memorytracking.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "memorytracking.h"
#include "log.h"
#include<algorithm>
// Platform independent way to get available memory
#if defined( __linux__ ) || defined( __CYGWIN__)
// Unix way
#include <unistd.h>
size_t total_physical_memory()
{
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
}
#endif
#ifdef __APPLE__
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/sysctl.h>
size_t total_physical_memory()
{
int mib [] = { CTL_HW, HW_MEMSIZE };
uint64_t value = 0;
size_t length = sizeof(value);
sysctl(mib, 2, &value, &length, NULL, 0);
// Physical memory is now in value
return (size_t) value;
}
#endif
#ifdef _WIN32
// Windows way
#include <windows.h>
size_t total_physical_memory()
{
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullTotalPhys;
}
#endif
bool memory_usage_comparison(const MemoryUsage &lhs, const MemoryUsage &rhs)
{
return lhs.num_bytes > rhs.num_bytes;
}
void check_memory_usage(vector<MemoryUsage> &usages, scalar limit_gb, integer nPoints, integer nDims, integer MaxPossibleClusters)
{
sort(usages.begin(), usages.end(), memory_usage_comparison);
double total_min = 0.0, total_max = 0.0;
Output("\nExpected memory usage by array (largest first):\n\n");
for (int i = 0; i < usages.size(); i++)
{
MemoryUsage &m = usages[i];
double base_usage = (double)m.num_bytes / (1024.0*1024.0*1024.0);
double min_usage = m.min_multiplier*base_usage;
double max_usage = m.max_multiplier*base_usage;
total_min += min_usage;
total_max += max_usage;
Output("Array %s will use between %.2f and %.2f GB.\n", m.name_of_array, min_usage, max_usage);
Output("- %lld bytes per element (%s), %lld elements when full.\n", m.bytes_per_element, m.name_of_type, m.num_elements);
Output("- Memory usage scales as %s.\n", m.expr);
}
Output("\nNote that nPoints=%d, nDims=%d, MaxPossibleClusters=%d", (int)nPoints, (int)nDims, (int)MaxPossibleClusters);
Output("\nTotal memory usage will be between %.2f and %.2f GB.\n", total_min, total_max);
Output("RAM limit is set at %.2f GB.\n", limit_gb);
if (total_min > limit_gb)
{
Error("The RAM limit does not cover the minimum possible memory usage.\nKlustaKwik definitely cannot run this.\nOptions include: buying more RAM; reducing the key parameters above.\n");
exit(EXIT_FAILURE);
} else if(total_max > limit_gb)
{
Error("The RAM limit covers the minimum but not maximum possible memory usage, so it\ncannot be guaranteed not to crash. Call KlustaKwik with -RamLimitGB -1 to\nforce it to run.\n");
exit(EXIT_FAILURE);
}
}