Skip to content

Commit 69cb979

Browse files
authored
Merge pull request #16506 from sneaxiy/revert-16424-fix_allocator_bug
Revert "Fix allocator bug"
2 parents ed61d67 + 5656fa9 commit 69cb979

31 files changed

+225
-338
lines changed

paddle/fluid/framework/operator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,9 @@ class ExecutionContext {
365365
auto shared_allocation = std::shared_ptr<memory::allocation::Allocation>(
366366
allocation_ptr, deleter);
367367

368+
PADDLE_ENFORCE(
369+
dynamic_cast<platform::TemporaryAllocation*>(allocation_ptr) != nullptr,
370+
"The AllocationPtr must be TemporaryAllocation.");
368371
PADDLE_ENFORCE_GE(allocation_ptr->size(),
369372
framework::product(dim) * sizeof(T));
370373

paddle/fluid/memory/allocation/CMakeLists.txt

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ cc_library(best_fit_allocator SRCS best_fit_allocator.cc DEPS allocator)
44
cc_library(locked_allocator SRCS locked_allocator.cc DEPS allocator)
55
cc_library(buffered_allocator SRCS buffered_allocator.cc DEPS allocator)
66
cc_library(legacy_allocator SRCS legacy_allocator.cc DEPS allocator buddy_allocator profiler)
7-
cc_library(zero_size_allocator SRCS zero_size_allocator.cc DEPS allocator)
87
cc_test(buffered_allocator_test SRCS buffered_allocator_test.cc DEPS best_fit_allocator locked_allocator buffered_allocator cpu_allocator)
98

109
if (WITH_GPU)
@@ -38,20 +37,30 @@ else ()
3837
set(AllocatorFacadeDeps)
3938
endif()
4039

41-
list(APPEND AllocatorFacadeDeps cpu_allocator locked_allocator best_fit_allocator aligned_allocator auto_increment_allocator conditional_allocator retry_allocator buffered_allocator legacy_allocator zero_size_allocator)
42-
4340
cc_library(aligned_allocator SRCS aligned_allocator.cc DEPS allocator)
4441
cc_library(auto_increment_allocator SRCS auto_increment_allocator.cc DEPS allocator)
42+
cc_library(zero_size_allocator SRCS zero_size_allocator.cc DEPS allocator)
4543
cc_library(conditional_allocator SRCS conditional_allocator.cc DEPS allocator)
46-
cc_library(allocator_strategy SRCS allocator_strategy.cc DEPS gflags ${AllocatorFacadeDeps})
47-
cc_library(allocator_facade SRCS allocator_facade.cc DEPS allocator_strategy)
44+
cc_library(allocator_strategy SRCS allocator_strategy.cc DEPS gflags)
45+
cc_library(allocator_facade SRCS allocator_facade.cc DEPS
46+
${AllocatorFacadeDeps}
47+
cpu_allocator
48+
locked_allocator
49+
best_fit_allocator
50+
aligned_allocator
51+
auto_increment_allocator
52+
zero_size_allocator
53+
conditional_allocator
54+
retry_allocator
55+
buffered_allocator
56+
allocator_strategy
57+
legacy_allocator
58+
)
4859

4960
nv_test(allocation_and_eigen_test SRCS allocation_and_eigen_test.cu DEPS allocator_facade)
5061

5162
cc_test(retry_allocator_test SRCS retry_allocator_test.cc DEPS retry_allocator best_fit_allocator locked_allocator cpu_allocator)
5263

53-
cc_test(naive_best_fit_allocator_facade_test SRCS naive_best_fit_allocator_facade_test.cc DEPS allocator_facade)
54-
5564
cc_test(allocator_facade_abs_flags_test SRCS allocator_facade_abs_flags_test.cc DEPS allocator_facade)
5665

5766
cc_test(allocator_facade_frac_flags_test SRCS allocator_facade_frac_flags_test.cc DEPS allocator_facade)

paddle/fluid/memory/allocation/aligned_allocator.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ class AlignedAllocator : public ThinAlignedAllocator {
9494
underlying_allocator_->Allocate(size + kAlignment, attr);
9595
return new AlignedAllocation<kAlignment>(std::move(raw_allocation), size);
9696
}
97-
98-
void FreeImpl(Allocation* allocation) override { delete allocation; }
9997
};
10098

10199
} // namespace allocation

paddle/fluid/memory/allocation/allocator.cc

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,16 @@ bool Allocator::IsAllocThreadSafe() const { return false; }
2727

2828
AllocationPtr Allocator::Allocate(size_t size, Allocator::Attr attr) {
2929
auto ptr = AllocateImpl(size, attr);
30-
ptr->RegisterDecoratedAllocator(this);
30+
ptr->set_allocator(this);
3131
return AllocationPtr(ptr);
3232
}
3333

34-
void Allocator::FreeImpl(Allocation* allocation) {
35-
Allocator* allocator = allocation->TopDecoratedAllocator();
36-
allocator->Free(allocation);
37-
}
38-
39-
void Allocator::Free(Allocation* allocation) {
40-
allocation->PopDecoratedAllocator();
41-
FreeImpl(allocation);
42-
}
34+
void Allocator::Free(Allocation* allocation) { delete allocation; }
4335

4436
const char* BadAlloc::what() const noexcept { return msg_.c_str(); }
4537

4638
void AllocationDeleter::operator()(Allocation* allocation) const {
47-
Allocator* allocator = allocation->TopDecoratedAllocator();
39+
auto* allocator = allocation->allocator();
4840
allocator->Free(allocation);
4941
}
5042

paddle/fluid/memory/allocation/allocator.h

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -46,56 +46,13 @@ class Allocator;
4646
// NOTE: this is the base class of Allocation. Each allocator can use its own
4747
// allocation object.
4848
// NOTE: the `Allocation::ptr()` could be nullptr, if the allocation size is 0
49-
50-
/**
51-
* Allocation is returned by Allocator::Allocate() method.
52-
*
53-
* An allocator may be decorated by another allocator. For example, we can
54-
* decorate
55-
* a RetryAllocator to any allocator to perform allocation retry when first
56-
* allocation request fails.
57-
*
58-
* Explanations of Allocator design is as follows:
59-
*
60-
* Suppose we have an allocator which is decorated by several allocators:
61-
*
62-
* A(1) <- A(2) <- A(3) <- ... <- A(n)
63-
*
64-
* , and the public allocator is A(1).
65-
*
66-
* The allocation process would be:
67-
*
68-
* A(n).Allocate() -> ... -> A(2).Allocate() -> A(1).Allocate()
69-
*
70-
* , and the free process would be:
71-
*
72-
* A(1).Free() -> A(2).Free() -> ... -> A(n).Free()
73-
*
74-
* Therefore, we should record the allocator chain when allocating, so
75-
* that we can free the allocation in the reverse order of allocator chain.
76-
* The field `decorated_allocators_` is used to record this chain.
77-
*
78-
* Another example is that we want to add additional fields in Allocation,
79-
* e.g., something what is done in AlignedAllocator, etc.
80-
* In this case, we should declare a derived class of Allocation, which
81-
* contains an underlying Allocation allocated by the underlying allocator.
82-
* Therefore, `decorated_allocators_` of the new Allocation object would
83-
* be a new chain, differing from the underlying Allocation object.
84-
*/
8549
class Allocation {
8650
public:
8751
Allocation(void* ptr, size_t size, platform::Place place)
88-
: ptr_(ptr), size_(size), place_(place) {
89-
// NOTE(zjl): Since decorated_allocators_ is usually a small vector
90-
// We reserve a small buffer to it to prevent frequent heap allocation
91-
// Not quite sure whether we need something like gtl vector.
92-
decorated_allocators_.reserve(8);
93-
}
52+
: allocator_(nullptr), ptr_(ptr), size_(size), place_(place) {}
9453

9554
Allocation(const Allocation& o) = delete;
9655
Allocation& operator=(const Allocation& o) = delete;
97-
Allocation(Allocation&& o) = delete;
98-
Allocation& operator=(Allocation&& o) = delete;
9956

10057
// Returns the holding pointer.
10158
// NOTE: For performance consideration, it is better not to make this method
@@ -117,31 +74,17 @@ class Allocation {
11774

11875
const platform::Place& place() const { return place_; }
11976

120-
virtual ~Allocation();
121-
122-
private:
123-
const std::vector<Allocator*>& DecoratedAllocators() const {
124-
return decorated_allocators_;
125-
}
126-
127-
inline void RegisterDecoratedAllocator(Allocator* allocator) {
128-
decorated_allocators_.push_back(allocator);
129-
}
77+
Allocator* allocator() { return allocator_; }
13078

131-
inline void PopDecoratedAllocator() { decorated_allocators_.pop_back(); }
79+
void set_allocator(Allocator* allocator) { allocator_ = allocator; }
13280

133-
inline Allocator* TopDecoratedAllocator() {
134-
return decorated_allocators_.back();
135-
}
81+
virtual ~Allocation();
13682

13783
private:
84+
Allocator* allocator_;
13885
void* ptr_;
13986
size_t size_;
14087
platform::Place place_;
141-
std::vector<Allocator*> decorated_allocators_;
142-
143-
friend class Allocator;
144-
friend class AllocationDeleter;
14588
};
14689

14790
using AllocationPtr = std::unique_ptr<Allocation, AllocationDeleter>;
@@ -191,12 +134,9 @@ class Allocator {
191134
// True if the `Allocate` is thread safe.
192135
virtual bool IsAllocThreadSafe() const;
193136

194-
// This function should not be called outside
195-
void Free(Allocation* allocation);
196-
197137
protected:
138+
virtual void Free(Allocation* allocation);
198139
virtual Allocation* AllocateImpl(size_t size, Allocator::Attr attr) = 0;
199-
virtual void FreeImpl(Allocation* allocation);
200140

201141
private:
202142
friend class AllocationDeleter;

paddle/fluid/memory/allocation/allocator_facade.cc

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,6 @@ namespace paddle {
4949
namespace memory {
5050
namespace allocation {
5151

52-
static inline std::shared_ptr<Allocator> WrapRetryAllocator(
53-
std::shared_ptr<Allocator> allocator, int64_t retry_time) {
54-
if (retry_time > 0) {
55-
auto* retry_allocator =
56-
new RetryAllocator(std::move(allocator), retry_time);
57-
allocator.reset(retry_allocator);
58-
}
59-
60-
return allocator;
61-
}
62-
6352
// TODO(yy): Dirty code here. This class should be configurable in runtime.
6453
class CPUManagedAllocator : public Allocator {
6554
public:
@@ -123,10 +112,14 @@ class ChunkedAllocator : public Allocator {
123112
std::shared_ptr<Allocator> CreateAllocatorWithChunk() {
124113
chunks_.emplace_back(raw_allocator_->Allocate(max_chunk_size_));
125114
auto* allocation = chunks_.back().get();
126-
std::shared_ptr<Allocator> allocator(new LockedAllocator(
127-
std::shared_ptr<Allocator>(new BestFitAllocator(allocation))));
115+
std::unique_ptr<Allocator> allocator(new LockedAllocator(
116+
std::unique_ptr<Allocator>(new BestFitAllocator(allocation))));
128117

129-
allocator = WrapRetryAllocator(allocator, retry_time_);
118+
if (retry_time_ > 0) {
119+
auto* retry_allocator =
120+
new RetryAllocator(std::move(allocator), retry_time_);
121+
allocator.reset(retry_allocator);
122+
}
130123

131124
return std::make_shared<AlignedAllocator<64u>>(std::move(allocator));
132125
}
@@ -197,23 +190,13 @@ class AllocatorFacadePrivate {
197190
~AllocatorFacadePrivate() = default;
198191

199192
AllocatorFacadePrivate() {
200-
auto strategy = GetAllocatorStrategy();
201-
switch (strategy) {
202-
case AllocatorStrategy::kLegacy: {
203-
InitLegacyAllocator();
204-
break;
205-
}
206-
case AllocatorStrategy::kNaiveBestFit: {
207-
InitCPUAllocator();
208-
InitCUDAAllocator();
209-
InitCUDAPinnedAllocator();
210-
WrapZeroSizeAllocator();
211-
break;
212-
}
213-
default: {
214-
PADDLE_THROW("Unsupported allocator strategy: %d",
215-
static_cast<int>(strategy));
216-
}
193+
if (GetAllocatorStrategy() == AllocatorStrategy::kLegacy) {
194+
InitLegacyAllocator();
195+
} else {
196+
InitCPUAllocator();
197+
InitCUDAAllocator();
198+
InitCUDAPinnedAllocator();
199+
WrapZeroSizeAllocator();
217200
}
218201
}
219202

@@ -271,7 +254,8 @@ AllocatorFacade& AllocatorFacade::Instance() {
271254

272255
std::shared_ptr<Allocation> AllocatorFacade::AllocShared(
273256
const platform::Place& place, size_t size, Allocator::Attr attr) {
274-
return std::shared_ptr<Allocation>(Alloc(place, size, attr));
257+
return std::shared_ptr<Allocation>(Alloc(place, size, attr).release(),
258+
AllocationDeleter());
275259
}
276260

277261
AllocationPtr AllocatorFacade::Alloc(const platform::Place& place, size_t size,

paddle/fluid/memory/allocation/allocator_strategy.cc

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,16 @@
1919
DEFINE_string(
2020
allocator_strategy, "legacy",
2121
"The allocation strategy. Legacy means the original allocator of Fluid."
22-
"naive_best_fit means the experimental best fit allocator. "
23-
"allocator. Enum in [legacy, naive_best_fit].");
22+
"New means the experimental allocators of Fluid. in [legacy, new]");
2423

2524
namespace paddle {
2625
namespace memory {
2726
namespace allocation {
2827

2928
static AllocatorStrategy GetStrategyFromFlag() {
30-
if (FLAGS_allocator_strategy == "legacy") {
31-
return AllocatorStrategy::kLegacy;
32-
} else if (FLAGS_allocator_strategy == "naive_best_fit") {
33-
return AllocatorStrategy::kNaiveBestFit;
34-
} else {
35-
PADDLE_THROW("Unsupported allocator strategy: %s",
36-
FLAGS_allocator_strategy);
37-
}
29+
return FLAGS_allocator_strategy == "legacy"
30+
? AllocatorStrategy::kLegacy
31+
: AllocatorStrategy::kNaiveBestFit;
3832
}
3933

4034
AllocatorStrategy GetAllocatorStrategy() {

paddle/fluid/memory/allocation/best_fit_allocator.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ size_t BestFitAllocator::NumFreeChunks() const {
109109
}
110110
return num;
111111
}
112-
void BestFitAllocator::FreeImpl(Allocation* allocation) {
112+
void BestFitAllocator::Free(Allocation* allocation) {
113113
auto* bf_allocation = dynamic_cast<BestFitAllocation*>(allocation);
114114
PADDLE_ENFORCE_NOT_NULL(bf_allocation,
115115
"The input allocation is not BestFitAllocation.");

paddle/fluid/memory/allocation/best_fit_allocator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class BestFitAllocator : public Allocator {
119119
void InsertFreeNode(const ListIt& it);
120120

121121
protected:
122-
void FreeImpl(Allocation* allocation) override;
122+
void Free(Allocation* allocation) override;
123123
Allocation* AllocateImpl(size_t size, Allocator::Attr attr) override;
124124

125125
private:

paddle/fluid/memory/allocation/buffered_allocator.cc

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ namespace paddle {
2222
namespace memory {
2323
namespace allocation {
2424

25-
BufferedAllocator::BufferedAllocator(std::shared_ptr<Allocator> allocator)
25+
BufferedAllocator::BufferedAllocator(std::unique_ptr<Allocator> &&allocator)
2626
: underlying_allocator_(std::move(allocator)) {
2727
PADDLE_ENFORCE_NOT_NULL(
2828
underlying_allocator_,
29-
"Underlying allocator of BufferedAllocator must not be null");
29+
"Underlying allocator of BufferedAllocator must be unmanaged");
3030
if (underlying_allocator_->IsAllocThreadSafe()) {
3131
mtx_.reset(new std::mutex());
3232
}
@@ -41,35 +41,37 @@ void BufferedAllocator::FreeCache(size_t size) {
4141
while (!allocations_.empty()) { // free the largest
4242
auto it = --allocations_.end();
4343
cur += it->second->size();
44-
underlying_allocator_->Free(it->second.release());
44+
delete it->second.release();
4545
allocations_.erase(it);
4646
if (cur >= size) return;
4747
}
4848
}
4949

50-
bool BufferedAllocator::IsAllocThreadSafe() const { return mtx_ != nullptr; }
51-
52-
void BufferedAllocator::FreeImpl(Allocation *allocation) {
50+
bool BufferedAllocator::IsAllocThreadSafe() const {
51+
return this->underlying_allocator_->IsAllocThreadSafe();
52+
}
53+
void BufferedAllocator::Free(Allocation *allocation) {
5354
platform::LockGuardPtr<std::mutex> guard(mtx_);
5455
allocations_.emplace(allocation->size(), AllocationPtr(allocation));
5556
}
56-
5757
Allocation *BufferedAllocator::AllocateImpl(size_t size, Allocator::Attr attr) {
5858
{
5959
platform::LockGuardPtr<std::mutex> guard(mtx_);
6060
auto it = allocations_.lower_bound(size);
6161
if (it != allocations_.end() && it->first < size * 2) {
6262
AllocationPtr result(std::move(it->second));
6363
allocations_.erase(it);
64-
return result.release();
64+
return new AllocationWithUnderlying(std::move(result));
6565
}
6666
}
6767

6868
try {
69-
return underlying_allocator_->Allocate(size, attr).release();
69+
return new AllocationWithUnderlying(
70+
underlying_allocator_->Allocate(size, attr));
7071
} catch (BadAlloc &) {
7172
FreeCache(size);
72-
return underlying_allocator_->Allocate(size, attr).release();
73+
return new AllocationWithUnderlying(
74+
underlying_allocator_->Allocate(size, attr));
7375
}
7476
}
7577

0 commit comments

Comments
 (0)