Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
402a9f1f
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
402a9f1f
编写于
4月 07, 2018
作者:
Y
Yi Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Rewrite the interface of memroy/detail
上级
544254fe
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
180 addition
and
269 deletion
+180
-269
paddle/fluid/memory/CMakeLists.txt
paddle/fluid/memory/CMakeLists.txt
+1
-5
paddle/fluid/memory/detail/CMakeLists.txt
paddle/fluid/memory/detail/CMakeLists.txt
+3
-7
paddle/fluid/memory/detail/buddy_allocator.h
paddle/fluid/memory/detail/buddy_allocator.h
+7
-7
paddle/fluid/memory/detail/memory_block.cc
paddle/fluid/memory/detail/memory_block.cc
+45
-50
paddle/fluid/memory/detail/memory_block.h
paddle/fluid/memory/detail/memory_block.h
+82
-43
paddle/fluid/memory/detail/meta_cache.cc
paddle/fluid/memory/detail/meta_cache.cc
+3
-4
paddle/fluid/memory/detail/meta_cache.h
paddle/fluid/memory/detail/meta_cache.h
+0
-64
paddle/fluid/memory/detail/meta_data.cc
paddle/fluid/memory/detail/meta_data.cc
+15
-11
paddle/fluid/memory/detail/meta_data.h
paddle/fluid/memory/detail/meta_data.h
+0
-54
paddle/fluid/memory/detail/system_allocator.cc
paddle/fluid/memory/detail/system_allocator.cc
+11
-11
paddle/fluid/memory/detail/system_allocator.h
paddle/fluid/memory/detail/system_allocator.h
+4
-4
paddle/fluid/memory/detail/system_allocator_test.cc
paddle/fluid/memory/detail/system_allocator_test.cc
+9
-9
未找到文件。
paddle/fluid/memory/CMakeLists.txt
浏览文件 @
402a9f1f
...
@@ -7,11 +7,7 @@ cc_library(paddle_memory
...
@@ -7,11 +7,7 @@ cc_library(paddle_memory
DEPS
DEPS
memory
memory
memcpy
memcpy
meta_data
buddy_allocator
)
meta_cache
memory_block
buddy_allocator
system_allocator
)
cc_test
(
memory_test SRCS memory_test.cc DEPS place paddle_memory
)
cc_test
(
memory_test SRCS memory_test.cc DEPS place paddle_memory
)
...
...
paddle/fluid/memory/detail/CMakeLists.txt
浏览文件 @
402a9f1f
cc_library
(
memory_block SRCS memory_block.cc meta_data.cc meta_cache.cc
)
if
(
${
WITH_GPU
}
)
if
(
${
WITH_GPU
}
)
nv_library
(
system_allocator SRCS system_allocator.cc DEPS gflags cpu_info gpu_info
)
nv_library
(
system_allocator SRCS system_allocator.cc DEPS gflags cpu_info gpu_info
)
else
(
${
WITH_GPU
}
)
else
(
${
WITH_GPU
}
)
...
@@ -6,10 +8,4 @@ endif(${WITH_GPU})
...
@@ -6,10 +8,4 @@ endif(${WITH_GPU})
cc_test
(
system_allocator_test SRCS system_allocator_test.cc DEPS system_allocator
)
cc_test
(
system_allocator_test SRCS system_allocator_test.cc DEPS system_allocator
)
cc_library
(
meta_data SRCS meta_data.cc
)
cc_library
(
buddy_allocator SRCS buddy_allocator.cc DEPS memory_block system_allocator glog
)
cc_library
(
meta_cache SRCS meta_cache.cc
)
cc_library
(
memory_block SRCS memory_block.cc
)
cc_library
(
buddy_allocator SRCS buddy_allocator.cc DEPS glog
)
paddle/fluid/memory/detail/buddy_allocator.h
浏览文件 @
402a9f1f
...
@@ -14,18 +14,18 @@ limitations under the License. */
...
@@ -14,18 +14,18 @@ limitations under the License. */
#pragma once
#pragma once
#include "paddle/fluid/memory/detail/meta_cache.h"
#include <mutex> // NOLINT
#include "paddle/fluid/memory/detail/meta_data.h"
#include <set>
#include <tuple>
#include <unordered_map>
#include <vector>
#include "paddle/fluid/memory/detail/memory_block.h"
#include "paddle/fluid/memory/detail/system_allocator.h"
#include "paddle/fluid/memory/detail/system_allocator.h"
#include "paddle/fluid/platform/assert.h"
#include "paddle/fluid/platform/assert.h"
#include "paddle/fluid/platform/cpu_info.h"
#include "paddle/fluid/platform/cpu_info.h"
#include "paddle/fluid/platform/gpu_info.h"
#include "paddle/fluid/platform/gpu_info.h"
#include <mutex>
#include <set>
#include <unordered_map>
#include <vector>
namespace
paddle
{
namespace
paddle
{
namespace
memory
{
namespace
memory
{
namespace
detail
{
namespace
detail
{
...
...
paddle/fluid/memory/detail/memory_block.cc
浏览文件 @
402a9f1f
...
@@ -13,17 +13,15 @@ See the License for the specific language governing permissions and
...
@@ -13,17 +13,15 @@ See the License for the specific language governing permissions and
limitations under the License. */
limitations under the License. */
#include "paddle/fluid/memory/detail/memory_block.h"
#include "paddle/fluid/memory/detail/memory_block.h"
#include "paddle/fluid/memory/detail/meta_cache.h"
#include "paddle/fluid/memory/detail/meta_data.h"
#include "paddle/fluid/platform/assert.h"
#include "paddle/fluid/platform/assert.h"
namespace
paddle
{
namespace
paddle
{
namespace
memory
{
namespace
memory
{
namespace
detail
{
namespace
detail
{
void
MemoryBlock
::
init
(
MetadataCache
&
cache
,
Type
t
,
size_t
index
,
size_t
size
,
void
MemoryBlock
::
init
(
MetadataCache
*
cache
,
Type
t
,
size_t
index
,
size_t
size
,
void
*
left_buddy
,
void
*
right_buddy
)
{
void
*
left_buddy
,
void
*
right_buddy
)
{
cache
.
stor
e
(
this
,
Metadata
(
t
,
index
,
size
-
sizeof
(
Metadata
),
size
,
cache
->
sav
e
(
this
,
Metadata
(
t
,
index
,
size
-
sizeof
(
Metadata
),
size
,
static_cast
<
MemoryBlock
*>
(
left_buddy
),
static_cast
<
MemoryBlock
*>
(
left_buddy
),
static_cast
<
MemoryBlock
*>
(
right_buddy
)));
static_cast
<
MemoryBlock
*>
(
right_buddy
)));
}
}
...
@@ -32,115 +30,112 @@ MemoryBlock::Type MemoryBlock::type(MetadataCache& cache) const {
...
@@ -32,115 +30,112 @@ MemoryBlock::Type MemoryBlock::type(MetadataCache& cache) const {
return
cache
.
load
(
this
).
type
;
return
cache
.
load
(
this
).
type
;
}
}
size_t
MemoryBlock
::
size
(
MetadataCache
&
cache
)
const
{
size_t
MemoryBlock
::
size
(
const
MetadataCache
&
cache
)
const
{
return
cache
.
load
(
this
).
size
;
return
cache
.
load
(
this
).
size
;
}
}
size_t
MemoryBlock
::
total_size
(
MetadataCache
&
cache
)
const
{
size_t
MemoryBlock
::
index
(
const
MetadataCache
&
cache
)
const
{
return
cache
.
load
(
this
).
index
;
}
size_t
MemoryBlock
::
total_size
(
const
MetadataCache
&
cache
)
const
{
return
cache
.
load
(
this
).
total_size
;
return
cache
.
load
(
this
).
total_size
;
}
}
MemoryBlock
*
MemoryBlock
::
left_buddy
(
MetadataCache
&
cache
)
const
{
bool
MemoryBlock
::
has_left_buddy
(
const
MetadataCache
&
cache
)
const
{
return
left_buddy
(
cache
)
!=
nullptr
;
}
bool
MemoryBlock
::
has_right_buddy
(
const
MetadataCache
&
cache
)
const
{
return
right_buddy
(
cache
)
!=
nullptr
;
}
MemoryBlock
*
MemoryBlock
::
left_buddy
(
const
MetadataCache
&
cache
)
const
{
return
cache
.
load
(
this
).
left_buddy
;
return
cache
.
load
(
this
).
left_buddy
;
}
}
MemoryBlock
*
MemoryBlock
::
right_buddy
(
MetadataCache
&
cache
)
const
{
MemoryBlock
*
MemoryBlock
::
right_buddy
(
const
MetadataCache
&
cache
)
const
{
return
cache
.
load
(
this
).
right_buddy
;
return
cache
.
load
(
this
).
right_buddy
;
}
}
void
MemoryBlock
::
split
(
MetadataCache
&
cache
,
size_t
size
)
{
void
MemoryBlock
::
split
(
MetadataCache
*
cache
,
size_t
size
)
{
// make sure the split fits
// make sure the split fits
PADDLE_ASSERT
(
total_size
(
cache
)
>=
size
);
PADDLE_ASSERT
(
total_size
(
*
cache
)
>=
size
);
// bail out if there is no room for another partition
// bail out if there is no room for another partition
if
(
total_size
(
cache
)
-
size
<=
sizeof
(
Metadata
))
{
if
(
total_size
(
*
cache
)
-
size
<=
sizeof
(
Metadata
))
{
return
;
return
;
}
}
// find the position of the split
// find the position of the split
void
*
right_partition
=
reinterpret_cast
<
uint8_t
*>
(
this
)
+
size
;
void
*
right_partition
=
reinterpret_cast
<
uint8_t
*>
(
this
)
+
size
;
size_t
remaining_size
=
total_size
(
cache
)
-
size
;
size_t
remaining_size
=
total_size
(
*
cache
)
-
size
;
// Add the new block as a buddy
// Add the new block as a buddy
auto
metadata
=
cache
.
load
(
this
);
auto
metadata
=
cache
->
load
(
this
);
// Write the metadata for the new block
// Write the metadata for the new block
auto
new_block_right_buddy
=
metadata
.
right_buddy
;
auto
new_block_right_buddy
=
metadata
.
right_buddy
;
cache
.
stor
e
(
cache
->
sav
e
(
static_cast
<
MemoryBlock
*>
(
right_partition
),
static_cast
<
MemoryBlock
*>
(
right_partition
),
Metadata
(
FREE_CHUNK
,
index
(
cache
),
remaining_size
-
sizeof
(
Metadata
),
Metadata
(
FREE_CHUNK
,
index
(
*
cache
),
remaining_size
-
sizeof
(
Metadata
),
remaining_size
,
this
,
new_block_right_buddy
));
remaining_size
,
this
,
new_block_right_buddy
));
metadata
.
right_buddy
=
static_cast
<
MemoryBlock
*>
(
right_partition
);
metadata
.
right_buddy
=
static_cast
<
MemoryBlock
*>
(
right_partition
);
metadata
.
size
=
size
-
sizeof
(
Metadata
);
metadata
.
size
=
size
-
sizeof
(
Metadata
);
metadata
.
total_size
=
size
;
metadata
.
total_size
=
size
;
cache
.
stor
e
(
this
,
metadata
);
cache
->
sav
e
(
this
,
metadata
);
// Write metadata for the new block's right buddy
// Write metadata for the new block's right buddy
if
(
new_block_right_buddy
!=
nullptr
)
{
if
(
new_block_right_buddy
!=
nullptr
)
{
auto
buddy_metadata
=
cache
.
load
(
new_block_right_buddy
);
auto
buddy_metadata
=
cache
->
load
(
new_block_right_buddy
);
buddy_metadata
.
left_buddy
=
static_cast
<
MemoryBlock
*>
(
right_partition
);
buddy_metadata
.
left_buddy
=
static_cast
<
MemoryBlock
*>
(
right_partition
);
cache
.
stor
e
(
new_block_right_buddy
,
buddy_metadata
);
cache
->
sav
e
(
new_block_right_buddy
,
buddy_metadata
);
}
}
}
}
void
MemoryBlock
::
merge
(
MetadataCache
&
cache
,
MemoryBlock
*
right_buddy
)
{
void
MemoryBlock
::
merge
(
MetadataCache
*
cache
,
MemoryBlock
*
right_buddy
)
{
// only free blocks can be merged
// only free blocks can be merged
PADDLE_ASSERT
(
type
(
cache
)
==
FREE_CHUNK
);
PADDLE_ASSERT
(
type
(
*
cache
)
==
FREE_CHUNK
);
PADDLE_ASSERT
(
right_buddy
->
type
(
cache
)
==
FREE_CHUNK
);
PADDLE_ASSERT
(
right_buddy
->
type
(
*
cache
)
==
FREE_CHUNK
);
auto
metadata
=
cache
.
load
(
this
);
auto
metadata
=
cache
->
load
(
this
);
// link this->buddy's buddy
// link this->buddy's buddy
metadata
.
right_buddy
=
right_buddy
->
right_buddy
(
cache
);
metadata
.
right_buddy
=
right_buddy
->
right_buddy
(
*
cache
);
// link buddy's buddy -> this
// link buddy's buddy -> this
if
(
metadata
.
right_buddy
!=
nullptr
)
{
if
(
metadata
.
right_buddy
!=
nullptr
)
{
auto
buddy_metadata
=
cache
.
load
(
metadata
.
right_buddy
);
auto
buddy_metadata
=
cache
->
load
(
metadata
.
right_buddy
);
buddy_metadata
.
left_buddy
=
this
;
buddy_metadata
.
left_buddy
=
this
;
cache
.
stor
e
(
metadata
.
right_buddy
,
buddy_metadata
);
cache
->
sav
e
(
metadata
.
right_buddy
,
buddy_metadata
);
}
}
metadata
.
size
+=
right_buddy
->
total_size
(
cache
);
metadata
.
size
+=
right_buddy
->
total_size
(
*
cache
);
metadata
.
total_size
+=
right_buddy
->
total_size
(
cache
);
metadata
.
total_size
+=
right_buddy
->
total_size
(
*
cache
);
cache
.
stor
e
(
this
,
metadata
);
cache
->
sav
e
(
this
,
metadata
);
cache
.
stor
e
(
right_buddy
,
Metadata
(
INVALID_CHUNK
,
0
,
0
,
0
,
nullptr
,
nullptr
));
cache
->
sav
e
(
right_buddy
,
Metadata
(
INVALID_CHUNK
,
0
,
0
,
0
,
nullptr
,
nullptr
));
}
}
void
MemoryBlock
::
mark_as_free
(
MetadataCache
&
cache
)
{
void
MemoryBlock
::
mark_as_free
(
MetadataCache
*
cache
)
{
// check for double free or corruption
// check for double free or corruption
PADDLE_ASSERT
(
type
(
cache
)
!=
FREE_CHUNK
);
PADDLE_ASSERT
(
type
(
*
cache
)
!=
FREE_CHUNK
);
PADDLE_ASSERT
(
type
(
cache
)
!=
INVALID_CHUNK
);
PADDLE_ASSERT
(
type
(
*
cache
)
!=
INVALID_CHUNK
);
set_type
(
cache
,
FREE_CHUNK
);
set_type
(
cache
,
FREE_CHUNK
);
}
}
void
MemoryBlock
::
set_type
(
MetadataCache
&
cache
,
Type
t
)
{
void
MemoryBlock
::
set_type
(
MetadataCache
*
cache
,
Type
t
)
{
auto
metadata
=
cache
.
load
(
this
);
auto
metadata
=
cache
->
load
(
this
);
metadata
.
type
=
t
;
metadata
.
type
=
t
;
cache
->
save
(
this
,
metadata
);
cache
.
store
(
this
,
metadata
);
}
bool
MemoryBlock
::
has_left_buddy
(
MetadataCache
&
cache
)
const
{
return
left_buddy
(
cache
)
!=
nullptr
;
}
bool
MemoryBlock
::
has_right_buddy
(
MetadataCache
&
cache
)
const
{
return
right_buddy
(
cache
)
!=
nullptr
;
}
size_t
MemoryBlock
::
index
(
MetadataCache
&
cache
)
const
{
return
cache
.
load
(
this
).
index
;
}
}
void
*
MemoryBlock
::
data
()
const
{
void
*
MemoryBlock
::
data
()
const
{
...
...
paddle/fluid/memory/detail/memory_block.h
浏览文件 @
402a9f1f
...
@@ -11,7 +11,6 @@ distributed under the License is distributed on an "AS IS" BASIS,
...
@@ -11,7 +11,6 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
See the License for the specific language governing permissions and
limitations under the License. */
limitations under the License. */
#pragma once
#pragma once
#include <cstddef>
#include <cstddef>
...
@@ -20,10 +19,11 @@ namespace paddle {
...
@@ -20,10 +19,11 @@ namespace paddle {
namespace
memory
{
namespace
memory
{
namespace
detail
{
namespace
detail
{
// Forward
Declarations
// Forward
declaration.
class
MetadataCache
;
class
MetadataCache
;
/*! \brief A class used to interpret the contents of a memory block */
// MemoryBlock represents Each allocated memory block, which contains
// Metadata and the payload.
class
MemoryBlock
{
class
MemoryBlock
{
public:
public:
enum
Type
{
enum
Type
{
...
@@ -33,57 +33,96 @@ class MemoryBlock {
...
@@ -33,57 +33,96 @@ class MemoryBlock {
INVALID_CHUNK
// memory is invalid
INVALID_CHUNK
// memory is invalid
};
};
public:
// init saves the Metadata of the memory block in a MetadataCache.
void
init
(
MetadataCache
&
cache
,
Type
t
,
size_t
index
,
size_t
size
,
// If it is a CPU memory block, the MetadataCache writes the
// Metadata to the beginning of the block; or, if it is a GPU memory
// block, the MetadataCache writes the Meatadata to a std::map in
// the CPU.
void
init
(
MetadataCache
*
cache
,
Type
t
,
size_t
index
,
size_t
size
,
void
*
left_buddy
,
void
*
right_buddy
);
void
*
left_buddy
,
void
*
right_buddy
);
public:
// All these accessors returns fields in the Metadata of the memory
/*! \brief The type of the allocation */
// block. They all need a MetadataCache instance as their first
Type
type
(
MetadataCache
&
cache
)
const
;
// parameter because they read the Metadata from the cache.
Type
type
(
const
MetadataCache
&
cache
)
const
;
/*! \brief The size of the data region */
size_t
size
(
const
MetadataCache
&
cache
)
const
;
size_t
size
(
MetadataCache
&
cache
)
const
;
size_t
index
(
const
MetadataCache
&
cache
)
const
;
size_t
total_size
(
const
MetadataCache
&
cache
)
const
;
/*! \brief An index to track the allocator */
bool
has_left_buddy
(
const
MetadataCache
&
cache
)
const
;
size_t
index
(
MetadataCache
&
cache
)
const
;
bool
has_right_buddy
(
const
MetadataCache
&
cache
)
const
;
MemoryBlock
*
left_buddy
(
const
MetadataCache
&
cache
)
const
;
/*! \brief The total size of the block */
MemoryBlock
*
right_buddy
(
const
MetadataCache
&
cache
)
const
;
size_t
total_size
(
MetadataCache
&
cache
)
const
;
/*! \brief Check the left buddy of the block */
bool
has_left_buddy
(
MetadataCache
&
cache
)
const
;
/*! \brief Check the right buddy of the block */
bool
has_right_buddy
(
MetadataCache
&
cache
)
const
;
/
*! \brief Get the left buddy */
/
/ Split the allocation into left/right blocks.
MemoryBlock
*
left_buddy
(
MetadataCache
&
cache
)
const
;
void
split
(
MetadataCache
*
cache
,
size_t
size
)
;
/
*! \brief Get the right buddy */
/
/ Merge left and right blocks together.
MemoryBlock
*
right_buddy
(
MetadataCache
&
cache
)
const
;
void
merge
(
MetadataCache
*
cache
,
MemoryBlock
*
right_buddy
)
;
public:
// Mark the allocation as free.
/*! \brief Split the allocation into left/right blocks */
void
mark_as_free
(
MetadataCache
*
cache
);
void
split
(
MetadataCache
&
cache
,
size_t
size
);
/*! \brief Merge left and right blocks together */
void
merge
(
MetadataCache
&
cache
,
MemoryBlock
*
right_buddy
);
/
*! \brief Mark the allocation as free */
/
/ Change the type of the allocation.
void
mark_as_free
(
MetadataCache
&
cache
);
void
set_type
(
MetadataCache
*
cache
,
Type
t
);
/*! \brief Change the type of the allocation */
void
set_type
(
MetadataCache
&
cache
,
Type
t
);
public:
/*! \brief Get a pointer to the memory block's data */
void
*
data
()
const
;
void
*
data
()
const
;
/*! \brief Get a pointer to the memory block's metadata */
MemoryBlock
*
metadata
()
const
;
MemoryBlock
*
metadata
()
const
;
private:
// Metadata describes a MemoryBlock.
struct
Metadata
{
Metadata
(
MemoryBlock
::
Type
t
,
size_t
i
,
size_t
s
,
size_t
ts
,
MemoryBlock
*
l
,
MemoryBlock
*
r
);
Metadata
();
// Updates guard_begin and guard_end by hashes of the Metadata object.
void
update_guards
();
// Checks that guard_begin and guard_end are hashes of the Metadata object.
bool
check_guards
()
const
;
// TODO(gangliao): compress this
size_t
guard_begin
=
0
;
MemoryBlock
::
Type
type
=
MemoryBlock
::
INVALID_CHUNK
;
size_t
index
=
0
;
size_t
size
=
0
;
size_t
total_size
=
0
;
MemoryBlock
*
left_buddy
=
nullptr
;
MemoryBlock
*
right_buddy
=
nullptr
;
size_t
guard_end
=
0
;
};
};
// A cache for accessing memory block meta-data that may be expensive
// to access directly. This class exists to unify the metadata format
// between GPU and CPU allocations. It should be removed when the CPU
// can access all GPU allocations directly via UVM.
class
MetadataCache
{
public:
public:
static
size_t
overhead
();
explicit
MetadataCache
(
bool
uses_gpu
);
// Disable copying and assignment.
MetadataCache
(
const
MetadataCache
&
)
=
delete
;
MetadataCache
&
operator
=
(
const
MetadataCache
&
)
=
delete
;
// Returns the Metadata for a memory block. When MetadataCache is
// used to manage CPU memory, the Metadata resides at the beginning
// of the memory block; when used to manage GPU memory, the
// Meatadata resides in CPU memory indexed by cache_.
Metadata
load
(
const
MemoryBlock
*
memory_block
)
const
;
// Saves the Metadata of a memory block into the cache. For CPU
// memory block, writes the Metadata to the beginning of the memory
// block; whereas for GPU memory, writes it to cache_.
void
save
(
MemoryBlock
*
memory_block
,
const
Metadata
&
meta_data
);
// For GPU memory block, erases its Metadata from cache_.
void
invalidate
(
MemoryBlock
*
memory_block
);
private:
typedef
std
::
unordered_map
<
const
MemoryBlock
*
,
Metadata
>
MetadataMap
;
MetadataMap
cache_
;
bool
uses_gpu_
;
};
};
}
// namespace detail
}
// namespace detail
...
...
paddle/fluid/memory/detail/meta_cache.cc
浏览文件 @
402a9f1f
...
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
...
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
See the License for the specific language governing permissions and
limitations under the License. */
limitations under the License. */
#include "paddle/fluid/memory/detail/meta_cache.h"
#include "glog/logging.h"
#include "glog/logging.h"
#include "paddle/fluid/memory/detail/memory_block.h"
#include "paddle/fluid/memory/detail/memory_block.h"
#include "paddle/fluid/platform/assert.h"
#include "paddle/fluid/platform/assert.h"
...
@@ -23,7 +22,7 @@ namespace detail {
...
@@ -23,7 +22,7 @@ namespace detail {
MetadataCache
::
MetadataCache
(
bool
uses_gpu
)
:
uses_gpu_
(
uses_gpu
)
{}
MetadataCache
::
MetadataCache
(
bool
uses_gpu
)
:
uses_gpu_
(
uses_gpu
)
{}
Metadata
MetadataCache
::
load
(
const
MemoryBlock
*
block
)
{
Metadata
MetadataCache
::
load
(
const
MemoryBlock
*
block
)
const
{
if
(
uses_gpu_
)
{
if
(
uses_gpu_
)
{
auto
existing_metadata
=
cache_
.
find
(
block
);
auto
existing_metadata
=
cache_
.
find
(
block
);
PADDLE_ASSERT
(
existing_metadata
->
second
.
check_guards
());
PADDLE_ASSERT
(
existing_metadata
->
second
.
check_guards
());
...
@@ -36,8 +35,8 @@ Metadata MetadataCache::load(const MemoryBlock* block) {
...
@@ -36,8 +35,8 @@ Metadata MetadataCache::load(const MemoryBlock* block) {
}
}
}
}
void
MetadataCache
::
s
tor
e
(
MemoryBlock
*
block
,
void
MetadataCache
::
s
av
e
(
MemoryBlock
*
block
,
const
Metadata
&
original_metadata
)
{
const
Metadata
&
original_metadata
)
{
auto
metadata
=
original_metadata
;
auto
metadata
=
original_metadata
;
metadata
.
update_guards
();
metadata
.
update_guards
();
...
...
paddle/fluid/memory/detail/meta_cache.h
已删除
100644 → 0
浏览文件 @
544254fe
/* 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. */
#pragma once
#include "paddle/fluid/memory/detail/memory_block.h"
#include "paddle/fluid/memory/detail/meta_data.h"
#include <unordered_map>
namespace
paddle
{
namespace
memory
{
namespace
detail
{
/**
* \brief A cache for accessing memory block meta-data that may be expensive
* to access directly.
*
* \note This class exists to unify the metadata format between GPU and CPU
* allocations. It should be removed when the CPU can access all GPU
* allocations directly via UVM.
*/
class
MetadataCache
{
public:
explicit
MetadataCache
(
bool
uses_gpu
);
public:
/*! \brief Load the associated metadata for the specified memory block. */
Metadata
load
(
const
MemoryBlock
*
memory_block
);
/*! \brief Store the associated metadata for the specified memory block. */
void
store
(
MemoryBlock
*
memory_block
,
const
Metadata
&
meta_data
);
/*! \brief Indicate that the specified metadata will no longer be used. */
void
invalidate
(
MemoryBlock
*
memory_block
);
public:
MetadataCache
(
const
MetadataCache
&
)
=
delete
;
MetadataCache
&
operator
=
(
const
MetadataCache
&
)
=
delete
;
private:
bool
uses_gpu_
;
private:
typedef
std
::
unordered_map
<
const
MemoryBlock
*
,
Metadata
>
MetadataMap
;
private:
MetadataMap
cache_
;
};
}
// namespace detail
}
// namespace memory
}
// namespace paddle
paddle/fluid/memory/detail/meta_data.cc
浏览文件 @
402a9f1f
...
@@ -12,10 +12,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
...
@@ -12,10 +12,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
See the License for the specific language governing permissions and
limitations under the License. */
limitations under the License. */
#include "paddle/fluid/memory/detail/meta_data.h"
#include <functional>
#include <functional>
#include "paddle/fluid/memory/detail/memory_block.h"
namespace
paddle
{
namespace
paddle
{
namespace
memory
{
namespace
memory
{
namespace
detail
{
namespace
detail
{
...
@@ -37,25 +37,29 @@ Metadata::Metadata()
...
@@ -37,25 +37,29 @@ Metadata::Metadata()
left_buddy
(
nullptr
),
left_buddy
(
nullptr
),
right_buddy
(
nullptr
)
{}
right_buddy
(
nullptr
)
{}
namespace
{
template
<
class
T
>
template
<
class
T
>
inline
void
hash_combine
(
std
::
size_t
&
seed
,
const
T
&
v
)
{
inline
void
hash_combine
(
std
::
size_t
*
seed
,
const
T
&
v
)
{
std
::
hash
<
T
>
hasher
;
std
::
hash
<
T
>
hasher
;
seed
^=
hasher
(
v
)
+
0x9e3779b9
+
(
seed
<<
6
)
+
(
seed
>>
2
);
(
*
seed
)
^=
hasher
(
v
)
+
0x9e3779b9
+
((
*
seed
)
<<
6
)
+
((
*
seed
)
>>
2
);
}
}
inline
size_t
hash
(
const
Metadata
*
metadata
,
size_t
initial_seed
)
{
inline
size_t
hash
(
const
Metadata
&
metadata
,
size_t
initial_seed
)
{
size_t
seed
=
initial_seed
;
size_t
seed
=
initial_seed
;
hash_combine
(
seed
,
(
size_t
)
metadata
->
type
);
hash_combine
(
&
seed
,
static_cast
<
size_t
>
(
metadata
.
type
)
);
hash_combine
(
seed
,
metadata
->
index
);
hash_combine
(
&
seed
,
metadata
.
index
);
hash_combine
(
seed
,
metadata
->
size
);
hash_combine
(
&
seed
,
metadata
.
size
);
hash_combine
(
seed
,
metadata
->
total_size
);
hash_combine
(
&
seed
,
metadata
.
total_size
);
hash_combine
(
seed
,
metadata
->
left_buddy
);
hash_combine
(
&
seed
,
metadata
.
left_buddy
);
hash_combine
(
seed
,
metadata
->
right_buddy
);
hash_combine
(
&
seed
,
metadata
.
right_buddy
);
return
seed
;
return
seed
;
}
}
}
// namespace
void
Metadata
::
update_guards
()
{
void
Metadata
::
update_guards
()
{
guard_begin
=
hash
(
this
,
1
);
guard_begin
=
hash
(
this
,
1
);
guard_end
=
hash
(
this
,
2
);
guard_end
=
hash
(
this
,
2
);
...
...
paddle/fluid/memory/detail/meta_data.h
已删除
100644 → 0
浏览文件 @
544254fe
/* 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. */
#pragma once
#include "paddle/fluid/memory/detail/memory_block.h"
#include <stddef.h>
namespace
paddle
{
namespace
memory
{
namespace
detail
{
class
Metadata
{
public:
Metadata
(
MemoryBlock
::
Type
t
,
size_t
i
,
size_t
s
,
size_t
ts
,
MemoryBlock
*
l
,
MemoryBlock
*
r
);
Metadata
();
public:
/*! \brief Update the guards when metadata is changed */
void
update_guards
();
/*! \brief Check consistency to previous modification */
bool
check_guards
()
const
;
public:
// TODO(gangliao): compress this
// clang-format off
size_t
guard_begin
=
0
;
MemoryBlock
::
Type
type
=
MemoryBlock
::
INVALID_CHUNK
;
size_t
index
=
0
;
size_t
size
=
0
;
size_t
total_size
=
0
;
MemoryBlock
*
left_buddy
=
nullptr
;
MemoryBlock
*
right_buddy
=
nullptr
;
size_t
guard_end
=
0
;
// clang-format on
};
}
// namespace detail
}
// namespace memory
}
// namespace paddle
paddle/fluid/memory/detail/system_allocator.cc
浏览文件 @
402a9f1f
...
@@ -13,16 +13,16 @@ See the License for the specific language governing permissions and
...
@@ -13,16 +13,16 @@ See the License for the specific language governing permissions and
limitations under the License. */
limitations under the License. */
#include "paddle/fluid/memory/detail/system_allocator.h"
#include "paddle/fluid/memory/detail/system_allocator.h"
#include "paddle/fluid/platform/assert.h"
#include "paddle/fluid/platform/cpu_info.h"
#include "paddle/fluid/platform/enforce.h"
#include "paddle/fluid/platform/gpu_info.h"
#include <stdlib.h> // for malloc and free
#include <stdlib.h> // for malloc and free
#include <sys/mman.h> // for mlock and munlock
#include <sys/mman.h> // for mlock and munlock
#include <algorithm> // for std::max
#include <algorithm> // for std::max
#include "gflags/gflags.h"
#include "gflags/gflags.h"
#include "paddle/fluid/platform/assert.h"
#include "paddle/fluid/platform/cpu_info.h"
#include "paddle/fluid/platform/enforce.h"
#include "paddle/fluid/platform/gpu_info.h"
// If use_pinned_memory is true, CPUAllocator calls mlock, which
// If use_pinned_memory is true, CPUAllocator calls mlock, which
// returns pinned and locked memory as staging areas for data exchange
// returns pinned and locked memory as staging areas for data exchange
...
@@ -35,13 +35,13 @@ namespace paddle {
...
@@ -35,13 +35,13 @@ namespace paddle {
namespace
memory
{
namespace
memory
{
namespace
detail
{
namespace
detail
{
void
*
CPUAllocator
::
Alloc
(
size_t
&
index
,
size_t
size
)
{
void
*
CPUAllocator
::
Alloc
(
size_t
*
index
,
size_t
size
)
{
// According to http://www.cplusplus.com/reference/cstdlib/malloc/,
// According to http://www.cplusplus.com/reference/cstdlib/malloc/,
// malloc might not return nullptr if size is zero, but the returned
// malloc might not return nullptr if size is zero, but the returned
// pointer shall not be dereferenced -- so we make it nullptr.
// pointer shall not be dereferenced -- so we make it nullptr.
if
(
size
<=
0
)
return
nullptr
;
if
(
size
<=
0
)
return
nullptr
;
index
=
0
;
// unlock memory
*
index
=
0
;
// unlock memory
void
*
p
;
void
*
p
;
...
@@ -56,7 +56,7 @@ void* CPUAllocator::Alloc(size_t& index, size_t size) {
...
@@ -56,7 +56,7 @@ void* CPUAllocator::Alloc(size_t& index, size_t size) {
if
(
p
!=
nullptr
)
{
if
(
p
!=
nullptr
)
{
if
(
FLAGS_use_pinned_memory
)
{
if
(
FLAGS_use_pinned_memory
)
{
index
=
1
;
*
index
=
1
;
mlock
(
p
,
size
);
// lock memory
mlock
(
p
,
size
);
// lock memory
}
}
}
}
...
@@ -75,7 +75,7 @@ bool CPUAllocator::UseGpu() const { return false; }
...
@@ -75,7 +75,7 @@ bool CPUAllocator::UseGpu() const { return false; }
#ifdef PADDLE_WITH_CUDA
#ifdef PADDLE_WITH_CUDA
void
*
GPUAllocator
::
Alloc
(
size_t
&
index
,
size_t
size
)
{
void
*
GPUAllocator
::
Alloc
(
size_t
*
index
,
size_t
size
)
{
// CUDA documentation doesn't explain if cudaMalloc returns nullptr
// CUDA documentation doesn't explain if cudaMalloc returns nullptr
// if size is 0. We just make sure it does.
// if size is 0. We just make sure it does.
if
(
size
<=
0
)
return
nullptr
;
if
(
size
<=
0
)
return
nullptr
;
...
@@ -93,7 +93,7 @@ void* GPUAllocator::Alloc(size_t& index, size_t size) {
...
@@ -93,7 +93,7 @@ void* GPUAllocator::Alloc(size_t& index, size_t size) {
}
}
if
(
result
==
cudaSuccess
)
{
if
(
result
==
cudaSuccess
)
{
index
=
0
;
*
index
=
0
;
gpu_alloc_size_
+=
size
;
gpu_alloc_size_
+=
size
;
return
p
;
return
p
;
}
else
{
}
else
{
...
@@ -133,7 +133,7 @@ bool GPUAllocator::UseGpu() const { return true; }
...
@@ -133,7 +133,7 @@ bool GPUAllocator::UseGpu() const { return true; }
// PINNED memory allows direct DMA transfers by the GPU to and from system
// PINNED memory allows direct DMA transfers by the GPU to and from system
// memory. It’s locked to a physical address.
// memory. It’s locked to a physical address.
void
*
CUDAPinnedAllocator
::
Alloc
(
size_t
&
index
,
size_t
size
)
{
void
*
CUDAPinnedAllocator
::
Alloc
(
size_t
*
index
,
size_t
size
)
{
if
(
size
<=
0
)
return
nullptr
;
if
(
size
<=
0
)
return
nullptr
;
// NOTE: here, we use CUDAPinnedMaxAllocSize as the maximum memory size
// NOTE: here, we use CUDAPinnedMaxAllocSize as the maximum memory size
...
@@ -154,7 +154,7 @@ void* CUDAPinnedAllocator::Alloc(size_t& index, size_t size) {
...
@@ -154,7 +154,7 @@ void* CUDAPinnedAllocator::Alloc(size_t& index, size_t size) {
cudaError_t
result
=
cudaMallocHost
(
&
p
,
size
);
cudaError_t
result
=
cudaMallocHost
(
&
p
,
size
);
if
(
result
==
cudaSuccess
)
{
if
(
result
==
cudaSuccess
)
{
index
=
1
;
// PINNED memory
*
index
=
1
;
// PINNED memory
cuda_pinnd_alloc_size_
+=
size
;
cuda_pinnd_alloc_size_
+=
size
;
return
p
;
return
p
;
}
else
{
}
else
{
...
...
paddle/fluid/memory/detail/system_allocator.h
浏览文件 @
402a9f1f
...
@@ -29,14 +29,14 @@ namespace detail {
...
@@ -29,14 +29,14 @@ namespace detail {
class
SystemAllocator
{
class
SystemAllocator
{
public:
public:
virtual
~
SystemAllocator
()
{}
virtual
~
SystemAllocator
()
{}
virtual
void
*
Alloc
(
size_t
&
index
,
size_t
size
)
=
0
;
virtual
void
*
Alloc
(
size_t
*
index
,
size_t
size
)
=
0
;
virtual
void
Free
(
void
*
p
,
size_t
size
,
size_t
index
)
=
0
;
virtual
void
Free
(
void
*
p
,
size_t
size
,
size_t
index
)
=
0
;
virtual
bool
UseGpu
()
const
=
0
;
virtual
bool
UseGpu
()
const
=
0
;
};
};
class
CPUAllocator
:
public
SystemAllocator
{
class
CPUAllocator
:
public
SystemAllocator
{
public:
public:
virtual
void
*
Alloc
(
size_t
&
index
,
size_t
size
);
virtual
void
*
Alloc
(
size_t
*
index
,
size_t
size
);
virtual
void
Free
(
void
*
p
,
size_t
size
,
size_t
index
);
virtual
void
Free
(
void
*
p
,
size_t
size
,
size_t
index
);
virtual
bool
UseGpu
()
const
;
virtual
bool
UseGpu
()
const
;
};
};
...
@@ -46,7 +46,7 @@ class GPUAllocator : public SystemAllocator {
...
@@ -46,7 +46,7 @@ class GPUAllocator : public SystemAllocator {
public:
public:
explicit
GPUAllocator
(
int
gpu_id
)
:
gpu_id_
(
gpu_id
)
{}
explicit
GPUAllocator
(
int
gpu_id
)
:
gpu_id_
(
gpu_id
)
{}
virtual
void
*
Alloc
(
size_t
&
index
,
size_t
size
);
virtual
void
*
Alloc
(
size_t
*
index
,
size_t
size
);
virtual
void
Free
(
void
*
p
,
size_t
size
,
size_t
index
);
virtual
void
Free
(
void
*
p
,
size_t
size
,
size_t
index
);
virtual
bool
UseGpu
()
const
;
virtual
bool
UseGpu
()
const
;
...
@@ -58,7 +58,7 @@ class GPUAllocator : public SystemAllocator {
...
@@ -58,7 +58,7 @@ class GPUAllocator : public SystemAllocator {
class
CUDAPinnedAllocator
:
public
SystemAllocator
{
class
CUDAPinnedAllocator
:
public
SystemAllocator
{
public:
public:
virtual
void
*
Alloc
(
size_t
&
index
,
size_t
size
);
virtual
void
*
Alloc
(
size_t
*
index
,
size_t
size
);
virtual
void
Free
(
void
*
p
,
size_t
size
,
size_t
index
);
virtual
void
Free
(
void
*
p
,
size_t
size
,
size_t
index
);
virtual
bool
UseGpu
()
const
;
virtual
bool
UseGpu
()
const
;
...
...
paddle/fluid/memory/detail/system_allocator_test.cc
浏览文件 @
402a9f1f
...
@@ -22,11 +22,11 @@ limitations under the License. */
...
@@ -22,11 +22,11 @@ limitations under the License. */
DECLARE_bool
(
use_pinned_memory
);
DECLARE_bool
(
use_pinned_memory
);
void
TestAllocator
(
paddle
::
memory
::
detail
::
SystemAllocator
&
a
,
size_t
size
)
{
void
TestAllocator
(
paddle
::
memory
::
detail
::
SystemAllocator
*
a
,
size_t
size
)
{
bool
freed
=
false
;
bool
freed
=
false
;
{
{
size_t
index
;
size_t
index
;
void
*
p
=
a
.
Alloc
(
index
,
size
);
void
*
p
=
a
->
Alloc
(
index
,
size
);
if
(
size
>
0
)
{
if
(
size
>
0
)
{
EXPECT_NE
(
p
,
nullptr
);
EXPECT_NE
(
p
,
nullptr
);
}
else
{
}
else
{
...
@@ -36,7 +36,7 @@ void TestAllocator(paddle::memory::detail::SystemAllocator& a, size_t size) {
...
@@ -36,7 +36,7 @@ void TestAllocator(paddle::memory::detail::SystemAllocator& a, size_t size) {
int
*
i
=
static_cast
<
int
*>
(
p
);
int
*
i
=
static_cast
<
int
*>
(
p
);
std
::
shared_ptr
<
int
>
ptr
(
i
,
[
&
](
void
*
p
)
{
std
::
shared_ptr
<
int
>
ptr
(
i
,
[
&
](
void
*
p
)
{
freed
=
true
;
freed
=
true
;
a
.
Free
(
p
,
size
,
index
);
a
->
Free
(
p
,
size
,
index
);
});
});
}
}
EXPECT_TRUE
(
freed
);
EXPECT_TRUE
(
freed
);
...
@@ -45,21 +45,21 @@ void TestAllocator(paddle::memory::detail::SystemAllocator& a, size_t size) {
...
@@ -45,21 +45,21 @@ void TestAllocator(paddle::memory::detail::SystemAllocator& a, size_t size) {
TEST
(
CPUAllocator
,
NoLockMem
)
{
TEST
(
CPUAllocator
,
NoLockMem
)
{
FLAGS_use_pinned_memory
=
false
;
FLAGS_use_pinned_memory
=
false
;
paddle
::
memory
::
detail
::
CPUAllocator
a
;
paddle
::
memory
::
detail
::
CPUAllocator
a
;
TestAllocator
(
a
,
2048
);
TestAllocator
(
&
a
,
2048
);
TestAllocator
(
a
,
0
);
TestAllocator
(
&
a
,
0
);
}
}
TEST
(
CPUAllocator
,
LockMem
)
{
TEST
(
CPUAllocator
,
LockMem
)
{
FLAGS_use_pinned_memory
=
true
;
FLAGS_use_pinned_memory
=
true
;
paddle
::
memory
::
detail
::
CPUAllocator
a
;
paddle
::
memory
::
detail
::
CPUAllocator
a
;
TestAllocator
(
a
,
2048
);
TestAllocator
(
&
a
,
2048
);
TestAllocator
(
a
,
0
);
TestAllocator
(
&
a
,
0
);
}
}
#ifdef PADDLE_WITH_CUDA
#ifdef PADDLE_WITH_CUDA
TEST
(
GPUAllocator
,
Alloc
)
{
TEST
(
GPUAllocator
,
Alloc
)
{
paddle
::
memory
::
detail
::
GPUAllocator
a
(
0
);
paddle
::
memory
::
detail
::
GPUAllocator
a
(
0
);
TestAllocator
(
a
,
2048
);
TestAllocator
(
&
a
,
2048
);
TestAllocator
(
a
,
0
);
TestAllocator
(
&
a
,
0
);
}
}
#endif
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录