-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
[Relay][Runtime] Add memory manager for NDArray #3121
Changes from 7 commits
5d5ae6d
6decb1d
e4d9e2d
41af59d
d71d875
0591b9a
d00950d
f26cb52
048b003
15763c8
76c201c
52cf9fa
ce21917
d317631
c07f6e6
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 |
---|---|---|
|
@@ -19,7 +19,7 @@ | |
|
||
/*! | ||
* \file tvm/runtime/ndarray.h | ||
* \brief Abstract device memory management API | ||
* \brief A device-independent managed NDArray abstraction. | ||
*/ | ||
#ifndef TVM_RUNTIME_NDARRAY_H_ | ||
#define TVM_RUNTIME_NDARRAY_H_ | ||
|
@@ -32,6 +32,10 @@ | |
|
||
namespace tvm { | ||
namespace runtime { | ||
|
||
class Allocator; | ||
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. remove Allocator(see my other comment about reverse the dependency) allocator depend on ndarry.h |
||
struct Buffer; | ||
jroesch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/*! | ||
* \brief Managed NDArray. | ||
* The array is backed by reference counted blocks. | ||
|
@@ -163,11 +167,13 @@ class NDArray { | |
* \param shape The shape of the new array. | ||
* \param dtype The data type of the new array. | ||
* \param ctx The context of the Array. | ||
* \param allocator The memory allocator. | ||
* \return The created Array | ||
*/ | ||
TVM_DLL static NDArray Empty(std::vector<int64_t> shape, | ||
DLDataType dtype, | ||
DLContext ctx); | ||
DLContext ctx, | ||
Allocator* allocator = nullptr); | ||
/*! | ||
* \brief Create a NDArray backed by a dlpack tensor. | ||
* | ||
|
@@ -248,6 +254,7 @@ class NDArray::Container { | |
* The head ptr of this struct can be viewed as DLTensor*. | ||
*/ | ||
DLTensor dl_tensor; | ||
|
||
/*! | ||
* \brief addtional context, reserved for recycling | ||
* \note We can attach additional content here | ||
|
@@ -281,6 +288,7 @@ class NDArray::Container { | |
int32_t array_type_code_{0}; | ||
/*! \brief The internal reference counter */ | ||
std::atomic<int> ref_counter_{0}; | ||
|
||
/*! | ||
* \brief The shape container, | ||
* can be used used for shape data. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
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. consider moving all the memory manager into src/runtime/vm, because it is used for dynamic memory allocation, and basic version of runtime does not need it |
||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
/*! | ||
* Copyright (c) 2019 by Contributors | ||
* \file tvm/runtime/memory_manager.cc | ||
* \brief Allocate and manage memory for the runtime. | ||
*/ | ||
#include <utility> | ||
#include <memory> | ||
#include "memory_manager.h" | ||
#include "naive_allocator.h" | ||
#include "pooled_allocator.h" | ||
|
||
namespace tvm { | ||
namespace runtime { | ||
|
||
MemoryManager* MemoryManager::Global() { | ||
static MemoryManager memory_manager; | ||
return &memory_manager; | ||
} | ||
|
||
Allocator* MemoryManager::GetAllocator(TVMContext ctx) { | ||
std::lock_guard<std::mutex> lock(mu_); | ||
if (allocators_.find(ctx) == allocators_.end()) { | ||
// LOG(INFO) << "New allocator for " << DeviceName(ctx.device_type) << "(" | ||
// << ctx.device_id << ")"; | ||
std::unique_ptr<Allocator> alloc(new NaiveAllocator(ctx)); | ||
allocators_.emplace(ctx, std::move(alloc)); | ||
} | ||
return allocators_.at(ctx).get(); | ||
} | ||
|
||
} // namespace runtime | ||
} // namespace tvm |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
/*! | ||
* Copyright (c) 2019 by Contributors | ||
* \file src/runtime/memory_manager.h | ||
* \brief Abstract device memory management API | ||
*/ | ||
#ifndef TVM_RUNTIME_MEMORY_MANAGER_H_ | ||
#define TVM_RUNTIME_MEMORY_MANAGER_H_ | ||
|
||
#include <tvm/runtime/c_runtime_api.h> | ||
#include <functional> | ||
#include <memory> | ||
#include <mutex> | ||
#include <unordered_map> | ||
#include <vector> | ||
|
||
namespace std { | ||
template <> | ||
struct hash<TVMContext> { | ||
std::size_t operator()(const TVMContext& ctx) const { | ||
return ((ctx.device_id << 8) | ctx.device_type); | ||
} | ||
}; | ||
|
||
template <> | ||
struct equal_to<TVMContext> { | ||
bool operator()(const TVMContext& lhs, const TVMContext& rhs) const { | ||
return (lhs.device_type == rhs.device_type && lhs.device_id == rhs.device_id); | ||
} | ||
}; | ||
|
||
} // namespace std | ||
|
||
namespace tvm { | ||
namespace runtime { | ||
|
||
struct Buffer { | ||
jroesch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// data pointer | ||
void* data{nullptr}; | ||
// Buffer size in bytes | ||
size_t size{0}; | ||
// TVM Context | ||
TVMContext ctx; | ||
}; | ||
|
||
class Allocator { | ||
public: | ||
explicit Allocator(TVMContext ctx) : ctx_(ctx) {} | ||
jroesch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
virtual Buffer Alloc(size_t nbytes, size_t alignment, TVMType type_hint) = 0; | ||
virtual void Free(const Buffer& buffer) = 0; | ||
virtual size_t UsedMemory() = 0; | ||
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. UsedMemory(Const)? |
||
virtual ~Allocator() = default; | ||
|
||
protected: | ||
TVMContext ctx_; | ||
}; | ||
|
||
class MemoryManager { | ||
public: | ||
static MemoryManager* Global(); | ||
|
||
Allocator* GetAllocator(TVMContext ctx); | ||
|
||
private: | ||
MemoryManager() {} | ||
|
||
private: | ||
std::mutex mu_; | ||
std::unordered_map<TVMContext, std::unique_ptr<Allocator>> allocators_; | ||
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.
|
||
}; | ||
|
||
} // namespace runtime | ||
} // namespace tvm | ||
|
||
#endif // TVM_RUNTIME_MEMORY_MANAGER_H_ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
/*! | ||
* Copyright (c) 2019 by Contributors | ||
* \file src/runtime/naive_allocator.h | ||
*/ | ||
#ifndef TVM_RUNTIME_NAIVE_ALLOCATOR_H_ | ||
#define TVM_RUNTIME_NAIVE_ALLOCATOR_H_ | ||
|
||
#include <tvm/runtime/device_api.h> | ||
#include <atomic> | ||
|
||
#include "memory_manager.h" | ||
|
||
namespace tvm { | ||
namespace runtime { | ||
|
||
class NaiveAllocator final : public Allocator { | ||
public: | ||
explicit NaiveAllocator(TVMContext ctx) : Allocator(ctx), used_memory_(0) {} | ||
|
||
Buffer Alloc(size_t nbytes, size_t alignment, TVMType type_hint) override { | ||
Buffer buf; | ||
buf.ctx = ctx_; | ||
buf.size = nbytes; | ||
buf.data = DeviceAPI::Get(ctx_)->AllocDataSpace(ctx_, nbytes, alignment, type_hint); | ||
used_memory_.fetch_add(nbytes, std::memory_order_relaxed); | ||
DLOG(INFO) << "allocate " << nbytes << " B, used memory " << used_memory_ << " B"; | ||
return buf; | ||
} | ||
|
||
void Free(const Buffer& buffer) override { | ||
DeviceAPI::Get(ctx_)->FreeDataSpace(buffer.ctx, buffer.data); | ||
used_memory_.fetch_sub(buffer.size, std::memory_order_relaxed); | ||
DLOG(INFO) << "free " << buffer.size << " B, used memory " << used_memory_ << " B"; | ||
} | ||
|
||
size_t UsedMemory() override { return used_memory_.load(std::memory_order_relaxed); } | ||
|
||
private: | ||
std::atomic<size_t> used_memory_; | ||
}; | ||
|
||
} // namespace runtime | ||
} // namespace tvm | ||
|
||
#endif // TVM_RUNTIME_NAIVE_ALLOCATOR_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for now, do not include memory_manager.cc, consider add back once we have all the vm changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't link correctly without this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you break the dependency of the NDArrary from memory_manager(move allocator aware alloca to allocator->Empty), you should be able to break the link dp