Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
Paddle
提交
2a422506
P
Paddle
项目概览
BaiXuePrincess
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
2a422506
编写于
12月 11, 2020
作者:
A
Aurelius84
提交者:
GitHub
12月 11, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Polish hash function of executor cache key (#29556)
* Add more value to calculate hash key * fix size_t * polish code
上级
760d015c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
38 addition
and
15 deletion
+38
-15
paddle/fluid/framework/executor_cache.cc
paddle/fluid/framework/executor_cache.cc
+1
-1
paddle/fluid/framework/executor_cache.h
paddle/fluid/framework/executor_cache.h
+37
-14
未找到文件。
paddle/fluid/framework/executor_cache.cc
浏览文件 @
2a422506
...
...
@@ -79,7 +79,7 @@ std::shared_ptr<framework::ExecutorPrepareContext> GetExecutorInfoFromCache(
auto
*
program
=
ctx
.
Attr
<
BlockDesc
*>
(
"global_block"
)
->
Program
();
auto
&
cached_exe_info
=
framework
::
ExecutorInfoCache
::
Instance
();
auto
cache_key
=
framework
::
ExecutorInfoCache
::
Key
Type
(
program
,
is_grad
);
auto
cache_key
=
framework
::
ExecutorInfoCache
::
Key
Info
(
program
,
is_grad
);
if
(
!
cached_exe_info
.
Has
(
cache_key
))
{
VLOG
(
1
)
<<
"create exe_info for program: "
<<
program
...
...
paddle/fluid/framework/executor_cache.h
浏览文件 @
2a422506
...
...
@@ -34,16 +34,29 @@ class ExecutorInfoCache {
* The ExecutorPrepareContext is different while running forward program and
* backward program. We add bool value into cached key to distinguish this.
*/
using
KeyType
=
std
::
pair
<
const
framework
::
ProgramDesc
*
,
/*is_grad*/
bool
>
;
using
KeyInfo
=
std
::
pair
<
const
framework
::
ProgramDesc
*
,
/*is_grad*/
bool
>
;
using
KeyType
=
size_t
;
struct
HashPair
{
template
<
class
T1
,
class
T2
>
size_t
operator
()(
const
std
::
pair
<
T1
,
T2
>&
p
)
const
noexcept
{
size_t
operator
()(
const
KeyInfo
&
key
)
const
noexcept
{
size_t
seed
=
10
;
hash_combine
(
&
seed
,
p
.
first
);
hash_combine
(
&
seed
,
p
.
second
);
auto
*
prog_desc
=
key
.
first
;
/*
* Note(Aurelius84): DO NOT use only ProgramDesc* to calculate hash value
* because a new program will hold same pointer address after an older
* program is destructed with a small probability. Add op size while
* hashing because program may contains at least one block.
*/
hash_combine
(
&
seed
,
prog_desc
);
for
(
size_t
i
=
0
;
i
<
prog_desc
->
Size
();
++
i
)
{
hash_combine
(
&
seed
,
&
prog_desc
->
Block
(
i
));
hash_combine
(
&
seed
,
prog_desc
->
Block
(
i
).
OpSize
());
}
hash_combine
(
&
seed
,
key
.
second
);
VLOG
(
1
)
<<
"hash value is : "
<<
seed
<<
" of pointer "
<<
prog_desc
;
return
seed
;
}
template
<
typename
T
>
void
hash_combine
(
size_t
*
seed
,
const
T
&
val
)
const
{
std
::
hash
<
T
>
hasher
;
...
...
@@ -54,35 +67,45 @@ class ExecutorInfoCache {
static
ExecutorInfoCache
&
Instance
();
std
::
shared_ptr
<
framework
::
ExecutorPrepareContext
>
Get
(
const
KeyType
&
key
)
const
{
const
KeyInfo
&
key
)
const
{
KeyType
key_value
=
key_hash_func_
(
key
);
PADDLE_ENFORCE_EQ
(
Has
(
key
),
true
,
Has
(
key
_value
),
true
,
platform
::
errors
::
NotFound
(
"(programDesc: %s, is_grad: %s) doesn't exist in ExecutorInfoCache"
,
key
.
first
,
key
.
second
));
return
info_map_
.
at
(
key
);
return
info_map_
.
at
(
key_value
);
}
bool
Has
(
const
KeyInfo
&
key
)
const
{
KeyType
key_value
=
key_hash_func_
(
key
);
return
Has
(
key_value
);
}
bool
Has
(
const
KeyType
&
key
)
const
{
return
info_map_
.
find
(
key
)
!=
info_map_
.
end
();
}
void
Insert
(
const
Key
Type
&
key
,
void
Insert
(
const
Key
Info
&
key
,
std
::
shared_ptr
<
framework
::
ExecutorPrepareContext
>
exe_ctx
)
{
KeyType
key_value
=
key_hash_func_
(
key
);
PADDLE_ENFORCE_NE
(
Has
(
key
),
true
,
Has
(
key
_value
),
true
,
platform
::
errors
::
NotFound
(
"(programDesc: %s, is_grad: %s) has existed in ExecutorInfoCache"
,
key
.
first
,
key
.
second
));
info_map_
.
insert
(
std
::
make_pair
(
key
,
exe_ctx
));
info_map_
.
insert
({
key_value
,
exe_ctx
});
}
private:
ExecutorInfoCache
()
=
default
;
std
::
unordered_map
<
KeyType
,
std
::
shared_ptr
<
framework
::
ExecutorPrepareContext
>
,
HashPair
>
HashPair
key_hash_func_
;
// Note: we shall avoid using raw pointer as key but use hash code,
// beacause pointer doesn't hold resource indeed.
std
::
unordered_map
<
KeyType
,
std
::
shared_ptr
<
framework
::
ExecutorPrepareContext
>>
info_map_
;
DISABLE_COPY_AND_ASSIGN
(
ExecutorInfoCache
);
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录