Merge pull request #16295 from zhhsplendid/zhenghuihuang-dev-2
Add support for init_memory and re-allocate_memorymove-code
commit
c64d959343
@ -0,0 +1,100 @@
|
||||
// Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed 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.
|
||||
|
||||
#include "paddle/fluid/memory/allocation/allocator_facade.h"
|
||||
#include <gflags/gflags.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#ifdef PADDLE_WITH_CUDA
|
||||
DECLARE_double(fraction_of_gpu_memory_to_use);
|
||||
DECLARE_double(fraction_of_cuda_pinned_memory_to_use);
|
||||
DECLARE_uint64(initial_gpu_memory_in_mb);
|
||||
DECLARE_uint64(reallocate_gpu_memory_in_mb);
|
||||
DECLARE_int64(gpu_allocator_retry_time);
|
||||
#endif
|
||||
|
||||
namespace paddle {
|
||||
namespace memory {
|
||||
namespace allocation {
|
||||
|
||||
//! Run allocate test cases for different places
|
||||
void AllocateTestCases() {
|
||||
auto &instance = AllocatorFacade::Instance();
|
||||
platform::Place place;
|
||||
size_t size = 1024;
|
||||
|
||||
{
|
||||
place = platform::CPUPlace();
|
||||
size = 1024;
|
||||
auto cpu_allocation = instance.Alloc(place, size);
|
||||
ASSERT_NE(cpu_allocation, nullptr);
|
||||
ASSERT_NE(cpu_allocation->ptr(), nullptr);
|
||||
ASSERT_EQ(cpu_allocation->place(), place);
|
||||
ASSERT_EQ(cpu_allocation->size(), size);
|
||||
}
|
||||
|
||||
#ifdef PADDLE_WITH_CUDA
|
||||
{
|
||||
place = platform::CUDAPlace(0);
|
||||
size = 1024;
|
||||
auto gpu_allocation = instance.Alloc(place, size);
|
||||
ASSERT_NE(gpu_allocation, nullptr);
|
||||
ASSERT_NE(gpu_allocation->ptr(), nullptr);
|
||||
ASSERT_EQ(gpu_allocation->place(), place);
|
||||
ASSERT_GE(gpu_allocation->size(), size);
|
||||
}
|
||||
|
||||
{
|
||||
// Allocate 2GB gpu memory
|
||||
place = platform::CUDAPlace(0);
|
||||
size = 2 * static_cast<size_t>(1 << 30);
|
||||
auto gpu_allocation = instance.Alloc(place, size);
|
||||
ASSERT_NE(gpu_allocation, nullptr);
|
||||
ASSERT_NE(gpu_allocation->ptr(), nullptr);
|
||||
ASSERT_EQ(gpu_allocation->place(), place);
|
||||
ASSERT_GE(gpu_allocation->size(), size);
|
||||
}
|
||||
|
||||
{
|
||||
place = platform::CUDAPinnedPlace();
|
||||
size = (1 << 20);
|
||||
auto cuda_pinned_allocation =
|
||||
instance.Alloc(platform::CUDAPinnedPlace(), 1 << 20);
|
||||
ASSERT_NE(cuda_pinned_allocation, nullptr);
|
||||
ASSERT_NE(cuda_pinned_allocation->ptr(), nullptr);
|
||||
ASSERT_EQ(cuda_pinned_allocation->place(), place);
|
||||
ASSERT_GE(cuda_pinned_allocation->size(), size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Allocator, SpecifyGpuMemory) {
|
||||
#ifdef PADDLE_WITH_CUDA
|
||||
// Set to 0.0 to test FLAGS_initial_gpu_memory_in_mb and
|
||||
// FLAGS_reallocate_gpu_memory_in_mb
|
||||
FLAGS_fraction_of_gpu_memory_to_use = 0.0;
|
||||
// 512 MB
|
||||
FLAGS_initial_gpu_memory_in_mb = 512;
|
||||
// 4 MB
|
||||
FLAGS_reallocate_gpu_memory_in_mb = 4;
|
||||
FLAGS_gpu_allocator_retry_time = 500;
|
||||
FLAGS_fraction_of_cuda_pinned_memory_to_use = 0.5;
|
||||
#endif
|
||||
|
||||
AllocateTestCases();
|
||||
}
|
||||
|
||||
} // namespace allocation
|
||||
} // namespace memory
|
||||
} // namespace paddle
|
@ -0,0 +1,133 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
|
||||
|
||||
Licensed 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. */
|
||||
|
||||
#include "paddle/fluid/memory/detail/buddy_allocator.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "gflags/gflags.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/fluid/memory/detail/system_allocator.h"
|
||||
#include "paddle/fluid/platform/gpu_info.h"
|
||||
|
||||
#ifdef PADDLE_WITH_CUDA
|
||||
DECLARE_double(fraction_of_gpu_memory_to_use);
|
||||
DECLARE_uint64(initial_gpu_memory_in_mb);
|
||||
DECLARE_uint64(reallocate_gpu_memory_in_mb);
|
||||
#endif
|
||||
|
||||
namespace paddle {
|
||||
namespace memory {
|
||||
namespace detail {
|
||||
|
||||
constexpr static int test_gpu_id = 0;
|
||||
|
||||
void TestBuddyAllocator(BuddyAllocator* allocator, size_t size_bytes) {
|
||||
bool freed = false;
|
||||
size_t used_bytes = allocator->Used();
|
||||
|
||||
if (size_bytes > 0) {
|
||||
void* p = allocator->Alloc(size_bytes);
|
||||
|
||||
EXPECT_NE(p, nullptr);
|
||||
#ifdef PADDLE_WITH_CUDA
|
||||
if (size_bytes < platform::GpuMaxChunkSize()) {
|
||||
#else
|
||||
if (size_bytes < platform::CpuMaxChunkSize()) {
|
||||
#endif
|
||||
// Not allocate from SystemAllocator
|
||||
EXPECT_GE(allocator->Used(), used_bytes + size_bytes);
|
||||
} else {
|
||||
// Allocate from SystemAllocator doesn't count in Used()
|
||||
EXPECT_EQ(allocator->Used(), used_bytes);
|
||||
}
|
||||
|
||||
int* intp = static_cast<int*>(p);
|
||||
std::shared_ptr<int> ptr(intp, [&](void* p) {
|
||||
allocator->Free(intp);
|
||||
freed = true;
|
||||
});
|
||||
} else {
|
||||
freed = true;
|
||||
}
|
||||
|
||||
EXPECT_EQ(used_bytes, allocator->Used());
|
||||
EXPECT_TRUE(freed);
|
||||
}
|
||||
|
||||
#ifdef PADDLE_WITH_CUDA
|
||||
TEST(BuddyAllocator, GpuFraction) {
|
||||
FLAGS_fraction_of_gpu_memory_to_use = 0.01;
|
||||
|
||||
BuddyAllocator buddy_allocator(
|
||||
std::unique_ptr<SystemAllocator>(new GPUAllocator(test_gpu_id)),
|
||||
platform::GpuMinChunkSize(), platform::GpuMaxChunkSize());
|
||||
|
||||
TestBuddyAllocator(&buddy_allocator, 10);
|
||||
TestBuddyAllocator(&buddy_allocator, 10 << 10);
|
||||
TestBuddyAllocator(&buddy_allocator, 10 << 20);
|
||||
TestBuddyAllocator(&buddy_allocator, 2 * static_cast<size_t>(1 << 30));
|
||||
}
|
||||
|
||||
TEST(BuddyAllocator, InitRealloc) {
|
||||
FLAGS_initial_gpu_memory_in_mb = 100;
|
||||
FLAGS_reallocate_gpu_memory_in_mb = 50;
|
||||
|
||||
EXPECT_EQ(platform::GpuMaxChunkSize(), static_cast<size_t>(100 << 20));
|
||||
|
||||
BuddyAllocator buddy_allocator(
|
||||
std::unique_ptr<SystemAllocator>(new GPUAllocator(test_gpu_id)),
|
||||
platform::GpuMinChunkSize(), platform::GpuMaxChunkSize());
|
||||
|
||||
// Less then initial size and reallocate size
|
||||
TestBuddyAllocator(&buddy_allocator, 10 << 20);
|
||||
// Between initial size and reallocate size and not exceed pool
|
||||
TestBuddyAllocator(&buddy_allocator, 80 << 20);
|
||||
// Less then reallocate size and exceed pool
|
||||
TestBuddyAllocator(&buddy_allocator, 40 << 20);
|
||||
// Greater then reallocate size and exceed pool
|
||||
TestBuddyAllocator(&buddy_allocator, 80 << 20);
|
||||
// Greater then initial size and reallocate size
|
||||
TestBuddyAllocator(&buddy_allocator, 2 * static_cast<size_t>(1 << 30));
|
||||
}
|
||||
|
||||
TEST(BuddyAllocator, ReallocSizeGreaterThanInit) {
|
||||
FLAGS_initial_gpu_memory_in_mb = 5;
|
||||
FLAGS_reallocate_gpu_memory_in_mb = 10;
|
||||
|
||||
EXPECT_EQ(platform::GpuMaxChunkSize(), static_cast<size_t>(10 << 20));
|
||||
|
||||
BuddyAllocator buddy_allocator(
|
||||
std::unique_ptr<SystemAllocator>(new GPUAllocator(test_gpu_id)),
|
||||
platform::GpuMinChunkSize(), platform::GpuMaxChunkSize());
|
||||
|
||||
// Less then initial size and reallocate size
|
||||
TestBuddyAllocator(&buddy_allocator, 1 << 20);
|
||||
// Between initial size and reallocate size and not exceed pool
|
||||
TestBuddyAllocator(&buddy_allocator, 3 << 20);
|
||||
// Less then initial size and exceed pool
|
||||
TestBuddyAllocator(&buddy_allocator, 3 << 20);
|
||||
// Less then reallocate size and not exceed pool (now pool is 15 MB, used 7
|
||||
// MB)
|
||||
TestBuddyAllocator(&buddy_allocator, 7 << 20);
|
||||
// Less then reallocate size and exceed pool
|
||||
TestBuddyAllocator(&buddy_allocator, 8 << 20);
|
||||
// Greater then initial size and reallocate size
|
||||
TestBuddyAllocator(&buddy_allocator, 2 * static_cast<size_t>(1 << 30));
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace memory
|
||||
} // namespace paddle
|
Loading…
Reference in new issue