-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathaligned-mem-pool.cc
More file actions
83 lines (73 loc) · 2.49 KB
/
aligned-mem-pool.cc
File metadata and controls
83 lines (73 loc) · 2.49 KB
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
#include "aligned-mem-pool.h"
#include <sstream>
using namespace dynet;
void* InternalMemoryPool::allocate(size_t n) {
auto rounded_n = a->round_up_align(n);
if (rounded_n + used > capacity) {
return 0;
}
void* res = static_cast<char*>(mem) + used;
used += rounded_n;
return res;
}
void InternalMemoryPool::sys_alloc(size_t cap) {
capacity = a->round_up_align(cap);
mem = a->malloc(capacity);
if (mem == NULL)
DYNET_RUNTIME_ERR(name << " failed to allocate " << capacity);
used = 0;
}
AlignedMemoryPool::AlignedMemoryPool(const std::string &name, size_t cap, MemAllocator *a) : name(name), current(0), cap(cap), a(a) {
DYNET_ASSERT(cap > 0, "Attempt to allocate memory of size 0 in AlignedMemoryPool");
pools.push_back(new InternalMemoryPool(name, cap, a));
}
AlignedMemoryPool::~AlignedMemoryPool() {
for ( auto p : pools) { delete p; }
}
void* AlignedMemoryPool::allocate(size_t n) {
void *res = pools[current]->allocate(n);
if (res == 0) {
// round up to the nearest multiple of cap
pools.push_back(new InternalMemoryPool(name, ((n+cap-1)/cap)*cap, a));
current++;
res = pools[current]->allocate(n);
}
return res;
}
void AlignedMemoryPool::free() {
if (current > 0) {
for (auto p : pools) { delete p; }
pools.clear();
pools.push_back(new InternalMemoryPool(name, cap * (current+1), a));
cap = cap * (current + 1);
current = 0;
}
pools[0]->free();
}
void AlignedMemoryPool::zero_allocated_memory() {
for (auto p : pools) { p->zero_allocated_memory(); }
}
size_t AlignedMemoryPool::used() {
if (current == 0) {
return pools[0]->used;
}
size_t res = 0;
for (auto p : pools) { res += p->used; }
return res;
}
void AlignedMemoryPool::set_used(size_t s) {
if(s != pools.back()->used) {
DYNET_ARG_CHECK(pools.size() == 1, "Dynet does not support both dynamic increasing of memory pool size, and automatic batching or memory checkpointing. If you want to use automatic batching or checkpointing, please pre-allocate enough memory using the --dynet-mem command line option (details http://dynet.readthedocs.io/en/latest/commandline.html).");
pools[0]->used = s;
}
// TODO: This is disabled for now, because it would require freeing all the memory pools to do properly
// int c = 0;
// while (s > pools[c]->used) {
// s -= pools[c]->used;
// c++;
// DYNET_ASSERT(c <= current, "attempt to set_used to a larger value than used().");
// }
// // s <= pools[c]->used
// pools[c]->used = s;
// current = c;
}