Skip to content

Commit 6562464

Browse files
committed
[VM] memory Manager moved up to runtime
Now graph runtime also uses the same memory manager This acommodates a common memory manager with pooled and naive support. As a follow up we can move the WorkspacePool to use this common memory manager.
1 parent d5fab9e commit 6562464

File tree

7 files changed

+55
-54
lines changed

7 files changed

+55
-54
lines changed

include/tvm/runtime/vm/memory_manager.h renamed to include/tvm/runtime/memory_manager.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
*/
1919

2020
/*!
21-
* \file tvm/runtime/vm/memory_manager.h
21+
* \file tvm/runtime/memory_manager.h
2222
* \brief Abstract device memory management API
2323
*/
24-
#ifndef TVM_RUNTIME_VM_MEMORY_MANAGER_H_
25-
#define TVM_RUNTIME_VM_MEMORY_MANAGER_H_
24+
#ifndef TVM_RUNTIME_MEMORY_MANAGER_H_
25+
#define TVM_RUNTIME_MEMORY_MANAGER_H_
2626

2727
#include <tvm/runtime/c_runtime_api.h>
2828
#include <tvm/runtime/ndarray.h>
@@ -37,9 +37,8 @@
3737

3838
namespace tvm {
3939
namespace runtime {
40-
namespace vm {
4140

42-
struct Buffer {
41+
struct MBuffer {
4342
/*! \brief The pointer to the allocated block of memory. */
4443
void* data{nullptr};
4544
/*! \brief The size of the block. */
@@ -63,9 +62,11 @@ class Allocator {
6362
* \param shape The shape of the NDArray.
6463
* \param dtype The datatype of the NDArray.
6564
* \param dev The device where the array is allocated.
65+
* \param mem_scope is the device memory scope hint.
6666
* \return The empty NDArray.
6767
*/
68-
NDArray Empty(std::vector<int64_t> shape, DLDataType dtype, Device dev);
68+
NDArray Empty(std::vector<int64_t> shape, DLDataType dtype, Device dev,
69+
Optional<String> mem_scope);
6970
/*! \brief Return the allocator type. */
7071
inline AllocatorType type() const { return type_; }
7172
/*! \brief Allocate a buffer given a size, alignment and type.
@@ -74,28 +75,28 @@ class Allocator {
7475
* \param type_hint A type hint to the allocator.
7576
* \return A sized allocation in the form of a buffer.
7677
*/
77-
virtual Buffer Alloc(size_t nbytes, size_t alignment, DLDataType type_hint) = 0;
78+
virtual MBuffer Alloc(size_t nbytes, size_t alignment, DLDataType type_hint) = 0;
7879
/*! \brief Allocate a buffer given a shape and type.
7980
* \param ndims The rank of the tensor.
8081
* \param shape The shape of the tensor.
8182
* \param type_hint A type hint to the allocator.
8283
* \param mem_scope A memory scope of the buffer.
8384
* \return A sized allocation in the form of a buffer.
8485
*/
85-
virtual Buffer Alloc(int ndims, int64_t* shape, DLDataType type_hint,
86-
const std::string& mem_scope = "") = 0;
86+
virtual MBuffer Alloc(int ndims, int64_t* shape, DLDataType type_hint,
87+
const std::string& mem_scope = "") = 0;
8788
/*! \brief Free a buffer allocated by the allocator.
8889
* \param buffer The buffer to free.
8990
*/
90-
virtual void Free(const Buffer& buffer) = 0;
91+
virtual void Free(const MBuffer& buffer) = 0;
9192
/*! \brief The amount of memory currently allocated.
9293
* \return The amount of memory currently allocated.
9394
*/
9495
virtual size_t UsedMemory() const = 0;
9596

9697
protected:
97-
virtual Buffer Alloc(Device dev, int ndims, int64_t* shape, DLDataType type_hint,
98-
const std::string& mem_scope);
98+
virtual MBuffer Alloc(Device dev, int ndims, int64_t* shape, DLDataType type_hint,
99+
const std::string& mem_scope);
99100

100101
private:
101102
AllocatorType type_;
@@ -130,7 +131,7 @@ class MemoryManager {
130131
class StorageObj : public Object {
131132
public:
132133
/*! \brief The index into the VM function table. */
133-
Buffer buffer;
134+
MBuffer buffer;
134135

135136
/*! \brief Allocate an NDArray from a given piece of storage. */
136137
NDArray AllocNDArray(size_t offset, std::vector<int64_t> shape, DLDataType dtype);
@@ -151,13 +152,12 @@ class StorageObj : public Object {
151152
/*! \brief reference to storage. */
152153
class Storage : public ObjectRef {
153154
public:
154-
explicit Storage(Buffer buffer);
155+
explicit Storage(MBuffer buffer);
155156

156157
TVM_DEFINE_MUTABLE_OBJECT_REF_METHODS(Storage, ObjectRef, StorageObj);
157158
};
158159

159-
} // namespace vm
160160
} // namespace runtime
161161
} // namespace tvm
162162

163-
#endif // TVM_RUNTIME_VM_MEMORY_MANAGER_H_
163+
#endif // TVM_RUNTIME_MEMORY_MANAGER_H_

include/tvm/runtime/vm/vm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@
2525
#define TVM_RUNTIME_VM_VM_H_
2626

2727
#include <tvm/runtime/container/closure.h>
28+
#include <tvm/runtime/memory_manager.h>
2829
#include <tvm/runtime/module.h>
2930
#include <tvm/runtime/object.h>
3031
#include <tvm/runtime/packed_func.h>
3132
#include <tvm/runtime/registry.h>
3233
#include <tvm/runtime/vm/bytecode.h>
3334
#include <tvm/runtime/vm/executable.h>
34-
#include <tvm/runtime/vm/memory_manager.h>
3535

3636
#include <memory>
3737
#include <string>

src/relay/backend/vm/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
#include <utility>
4242
#include <vector>
4343

44-
#include "../../../runtime/vm/naive_allocator.h"
44+
#include "../../../runtime/naive_allocator.h"
4545
#include "../../../runtime/vm/profiler/vm.h"
4646
#include "../../transforms/pass_utils.h"
4747
#include "../te_compiler.h"

src/runtime/graph_executor/graph_executor.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <tvm/runtime/container/string.h>
2727
#include <tvm/runtime/data_type.h>
2828
#include <tvm/runtime/device_api.h>
29+
#include <tvm/runtime/memory_manager.h>
2930
#include <tvm/runtime/ndarray.h>
3031
#include <tvm/runtime/packed_func.h>
3132
#include <tvm/runtime/profiling.h>
@@ -466,7 +467,8 @@ void GraphExecutor::SetupStorage() {
466467
if (!pit.scope.empty()) {
467468
mem_scope = String(pit.scope);
468469
}
469-
storage_pool_.push_back(NDArray::Empty(shape, pit.dtype, dev, mem_scope));
470+
storage_pool_.push_back(MemoryManager::GetOrCreateAllocator(dev, AllocatorType::kNaive)
471+
->Empty(shape, pit.dtype, dev, mem_scope));
470472
}
471473
}
472474

src/runtime/vm/memory_manager.cc renamed to src/runtime/memory_manager.cc

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
*/
1919

2020
/*!
21-
* \file tvm/runtime/vm/memory_manager.cc
21+
* \file tvm/runtime/memory_manager.cc
2222
* \brief Allocate and manage memory for the runtime.
2323
*/
24-
#include <tvm/runtime/vm/memory_manager.h>
24+
#include <tvm/runtime/memory_manager.h>
2525

2626
#include <memory>
2727
#include <utility>
@@ -31,12 +31,11 @@
3131

3232
namespace tvm {
3333
namespace runtime {
34-
namespace vm {
3534

3635
static void BufferDeleter(Object* obj) {
3736
auto* ptr = static_cast<NDArray::Container*>(obj);
3837
ICHECK(ptr->manager_ctx != nullptr);
39-
Buffer* buffer = reinterpret_cast<Buffer*>(ptr->manager_ctx);
38+
MBuffer* buffer = reinterpret_cast<MBuffer*>(ptr->manager_ctx);
4039
MemoryManager::GetAllocator(buffer->device)->Free(*(buffer));
4140
delete buffer;
4241
delete ptr;
@@ -154,21 +153,26 @@ Allocator* MemoryManager::GetAllocator(Device dev) {
154153
return it->second.get();
155154
}
156155

157-
NDArray Allocator::Empty(std::vector<int64_t> shape, DLDataType dtype, DLDevice dev) {
156+
NDArray Allocator::Empty(std::vector<int64_t> shape, DLDataType dtype, DLDevice dev,
157+
Optional<String> mem_scope) {
158158
VerifyDataType(dtype);
159159
NDArray::Container* container = new NDArray::Container(nullptr, shape, dtype, dev);
160160
container->SetDeleter(BufferDeleter);
161161
size_t size = GetDataSize(container->dl_tensor);
162162
size_t alignment = GetDataAlignment(container->dl_tensor);
163-
Buffer* buffer = new Buffer;
164-
*buffer = this->Alloc(size, alignment, dtype);
163+
MBuffer* buffer = new MBuffer;
164+
if (!mem_scope.defined() || mem_scope == "global") {
165+
*buffer = this->Alloc(size, alignment, dtype);
166+
} else {
167+
*buffer = this->Alloc(shape.size(), shape.data(), dtype, mem_scope.value());
168+
}
165169
container->manager_ctx = reinterpret_cast<void*>(buffer);
166170
container->dl_tensor.data = buffer->data;
167171
return NDArray(GetObjectPtr<Object>(container));
168172
}
169173

170-
Buffer Allocator::Alloc(Device dev, int ndims, int64_t* shape, DLDataType type_hint,
171-
const std::string& mem_scope) {
174+
MBuffer Allocator::Alloc(Device dev, int ndims, int64_t* shape, DLDataType type_hint,
175+
const std::string& mem_scope) {
172176
if (mem_scope.empty() || mem_scope == "global") {
173177
// by default, we can always redirect to the flat memory allocations
174178
std::vector<int64_t> s;
@@ -185,6 +189,5 @@ Buffer Allocator::Alloc(Device dev, int ndims, int64_t* shape, DLDataType type_h
185189
return {};
186190
}
187191

188-
} // namespace vm
189192
} // namespace runtime
190193
} // namespace tvm

src/runtime/vm/naive_allocator.h renamed to src/runtime/naive_allocator.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,24 @@
2020
/*!
2121
* \file src/runtime/naive_allocator.h
2222
*/
23-
#ifndef TVM_RUNTIME_VM_NAIVE_ALLOCATOR_H_
24-
#define TVM_RUNTIME_VM_NAIVE_ALLOCATOR_H_
23+
#ifndef TVM_RUNTIME_NAIVE_ALLOCATOR_H_
24+
#define TVM_RUNTIME_NAIVE_ALLOCATOR_H_
2525

2626
#include <tvm/runtime/device_api.h>
27-
#include <tvm/runtime/vm/memory_manager.h>
27+
#include <tvm/runtime/memory_manager.h>
2828

2929
#include <atomic>
3030
#include <string>
3131

3232
namespace tvm {
3333
namespace runtime {
34-
namespace vm {
3534

3635
class NaiveAllocator final : public Allocator {
3736
public:
3837
explicit NaiveAllocator(Device dev) : Allocator(kNaive), used_memory_(0), device_(dev) {}
3938

40-
Buffer Alloc(size_t nbytes, size_t alignment, DLDataType type_hint) override {
41-
Buffer buf;
39+
MBuffer Alloc(size_t nbytes, size_t alignment, DLDataType type_hint) override {
40+
MBuffer buf;
4241
buf.device = device_;
4342
buf.size = nbytes;
4443
buf.data = DeviceAPI::Get(device_)->AllocDataSpace(device_, nbytes, alignment, type_hint);
@@ -47,9 +46,9 @@ class NaiveAllocator final : public Allocator {
4746
return buf;
4847
}
4948

50-
Buffer Alloc(int ndims, int64_t* shape, DLDataType type_hint,
51-
const std::string& mem_scope) override {
52-
Buffer buf;
49+
MBuffer Alloc(int ndims, int64_t* shape, DLDataType type_hint,
50+
const std::string& mem_scope) override {
51+
MBuffer buf;
5352
size_t nbytes = 1;
5453
for (int i = 0; i < ndims; ++i) {
5554
buf.shape.push_back(shape[i]);
@@ -72,7 +71,7 @@ class NaiveAllocator final : public Allocator {
7271
return buf;
7372
}
7473

75-
void Free(const Buffer& buffer) override {
74+
void Free(const MBuffer& buffer) override {
7675
DeviceAPI::Get(device_)->FreeDataSpace(buffer.device, buffer.data);
7776
used_memory_.fetch_sub(buffer.size, std::memory_order_relaxed);
7877
DLOG(INFO) << "free " << buffer.size << " B, used memory " << used_memory_ << " B";
@@ -85,8 +84,7 @@ class NaiveAllocator final : public Allocator {
8584
Device device_;
8685
};
8786

88-
} // namespace vm
8987
} // namespace runtime
9088
} // namespace tvm
9189

92-
#endif // TVM_RUNTIME_VM_NAIVE_ALLOCATOR_H_
90+
#endif // TVM_RUNTIME_NAIVE_ALLOCATOR_H_

src/runtime/vm/pooled_allocator.h renamed to src/runtime/pooled_allocator.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
/*!
2121
* \file runtime/pooled_allocator.h
2222
*/
23-
#ifndef TVM_RUNTIME_VM_POOLED_ALLOCATOR_H_
24-
#define TVM_RUNTIME_VM_POOLED_ALLOCATOR_H_
23+
#ifndef TVM_RUNTIME_POOLED_ALLOCATOR_H_
24+
#define TVM_RUNTIME_POOLED_ALLOCATOR_H_
2525

2626
#include <tvm/runtime/device_api.h>
27-
#include <tvm/runtime/vm/memory_manager.h>
27+
#include <tvm/runtime/memory_manager.h>
2828

2929
#include <atomic>
3030
#include <mutex>
@@ -34,7 +34,6 @@
3434

3535
namespace tvm {
3636
namespace runtime {
37-
namespace vm {
3837

3938
class PooledAllocator final : public Allocator {
4039
public:
@@ -45,7 +44,7 @@ class PooledAllocator final : public Allocator {
4544

4645
~PooledAllocator() { ReleaseAll(); }
4746

48-
Buffer Alloc(size_t nbytes, size_t alignment, DLDataType type_hint) override {
47+
MBuffer Alloc(size_t nbytes, size_t alignment, DLDataType type_hint) override {
4948
std::lock_guard<std::recursive_mutex> lock(mu_);
5049
size_t size = ((nbytes + page_size_ - 1) / page_size_) * page_size_;
5150
auto&& it = memory_pool_.find(size);
@@ -55,7 +54,7 @@ class PooledAllocator final : public Allocator {
5554
pool.pop_back();
5655
return ret;
5756
}
58-
Buffer buf;
57+
MBuffer buf;
5958
buf.device = device_;
6059
buf.size = size;
6160
try {
@@ -72,19 +71,19 @@ class PooledAllocator final : public Allocator {
7271
return buf;
7372
}
7473

75-
Buffer Alloc(int ndims, int64_t* shape, DLDataType type_hint,
76-
const std::string& mem_scope) override {
74+
MBuffer Alloc(int ndims, int64_t* shape, DLDataType type_hint,
75+
const std::string& mem_scope) override {
7776
if (mem_scope.empty() || mem_scope == "global") {
7877
return Allocator::Alloc(device_, ndims, shape, type_hint, mem_scope);
7978
}
8079
LOG(FATAL) << "This alloc should be implemented";
8180
return {};
8281
}
8382

84-
void Free(const Buffer& buffer) override {
83+
void Free(const MBuffer& buffer) override {
8584
std::lock_guard<std::recursive_mutex> lock(mu_);
8685
if (memory_pool_.find(buffer.size) == memory_pool_.end()) {
87-
memory_pool_.emplace(buffer.size, std::vector<Buffer>{});
86+
memory_pool_.emplace(buffer.size, std::vector<MBuffer>{});
8887
}
8988
memory_pool_.at(buffer.size).push_back(buffer);
9089
VLOG(1) << "reclaim buffer " << buffer.size;
@@ -109,13 +108,12 @@ class PooledAllocator final : public Allocator {
109108
private:
110109
size_t page_size_;
111110
std::atomic<size_t> used_memory_;
112-
std::unordered_map<size_t, std::vector<Buffer>> memory_pool_;
111+
std::unordered_map<size_t, std::vector<MBuffer>> memory_pool_;
113112
std::recursive_mutex mu_;
114113
Device device_;
115114
};
116115

117-
} // namespace vm
118116
} // namespace runtime
119117
} // namespace tvm
120118

121-
#endif // TVM_RUNTIME_VM_POOLED_ALLOCATOR_H_
119+
#endif // TVM_RUNTIME_POOLED_ALLOCATOR_H_

0 commit comments

Comments
 (0)