Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
53619873
P
Paddle
项目概览
Crayon鑫
/
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看板
未验证
提交
53619873
编写于
5月 09, 2020
作者:
Y
Yiqun Liu
提交者:
GitHub
5月 09, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement the new profiler api. (#24344)
上级
a851b97a
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
241 addition
and
56 deletion
+241
-56
python/paddle/fluid/tests/unittests/test_profiler.py
python/paddle/fluid/tests/unittests/test_profiler.py
+114
-42
python/paddle/utils/__init__.py
python/paddle/utils/__init__.py
+5
-7
python/paddle/utils/profiler.py
python/paddle/utils/profiler.py
+122
-7
未找到文件。
python/paddle/fluid/tests/unittests/test_profiler.py
浏览文件 @
53619873
...
...
@@ -18,6 +18,7 @@ import unittest
import
os
import
tempfile
import
numpy
as
np
import
paddle.utils
as
utils
import
paddle.fluid
as
fluid
import
paddle.fluid.profiler
as
profiler
import
paddle.fluid.layers
as
layers
...
...
@@ -31,16 +32,9 @@ class TestProfiler(unittest.TestCase):
def
setUpClass
(
cls
):
os
.
environ
[
'CPU_NUM'
]
=
str
(
4
)
def
net_profiler
(
self
,
state
,
option
,
iter_range
=
None
,
use_parallel_executor
=
False
):
profile_path
=
os
.
path
.
join
(
tempfile
.
gettempdir
(),
"profile"
)
open
(
profile_path
,
"w"
).
write
(
""
)
def
build_program
(
self
,
compile_program
=
True
):
startup_program
=
fluid
.
Program
()
main_program
=
fluid
.
Program
()
with
fluid
.
program_guard
(
main_program
,
startup_program
):
image
=
fluid
.
layers
.
data
(
name
=
'x'
,
shape
=
[
784
],
dtype
=
'float32'
)
hidden1
=
fluid
.
layers
.
fc
(
input
=
image
,
size
=
64
,
act
=
'relu'
)
...
...
@@ -70,34 +64,19 @@ class TestProfiler(unittest.TestCase):
optimizer
=
fluid
.
optimizer
.
Momentum
(
learning_rate
=
0.001
,
momentum
=
0.9
)
opts
=
optimizer
.
minimize
(
avg_cost
,
startup_program
=
startup_program
)
place
=
fluid
.
CPUPlace
()
if
state
==
'CPU'
else
fluid
.
CUDAPlace
(
0
)
exe
=
fluid
.
Executor
(
place
)
exe
.
run
(
startup_program
)
if
use_parallel_executor
:
pe
=
fluid
.
ParallelExecutor
(
state
!=
'CPU'
,
loss_name
=
avg_cost
.
name
,
main_program
=
main_program
)
if
compile_program
:
train_program
=
fluid
.
compiler
.
CompiledProgram
(
main_program
).
with_data_parallel
(
loss_name
=
avg_cost
.
name
)
else
:
train_program
=
main_program
return
train_program
,
startup_program
,
avg_cost
,
batch_size
,
batch_acc
pass_acc_calculator
=
fluid
.
average
.
WeightedAverage
()
with
profiler
.
profiler
(
state
,
'total'
,
profile_path
,
option
)
as
prof
:
for
iter
in
range
(
10
):
if
iter
==
2
:
profiler
.
reset_profiler
()
x
=
np
.
random
.
random
((
32
,
784
)).
astype
(
"float32"
)
y
=
np
.
random
.
randint
(
0
,
10
,
(
32
,
1
)).
astype
(
"int64"
)
def
get_profile_path
(
self
):
profile_path
=
os
.
path
.
join
(
tempfile
.
gettempdir
(),
"profile"
)
open
(
profile_path
,
"w"
).
write
(
""
)
return
profile_path
if
use_parallel_executor
:
pe
.
run
(
feed
=
{
'x'
:
x
,
'y'
:
y
},
fetch_list
=
[
avg_cost
.
name
])
continue
outs
=
exe
.
run
(
main_program
,
feed
=
{
'x'
:
x
,
'y'
:
y
},
fetch_list
=
[
avg_cost
,
batch_acc
,
batch_size
])
acc
=
np
.
array
(
outs
[
1
])
b_size
=
np
.
array
(
outs
[
2
])
pass_acc_calculator
.
add
(
value
=
acc
,
weight
=
b_size
)
pass_acc
=
pass_acc_calculator
.
eval
()
def
check_profile_result
(
self
,
profile_path
):
data
=
open
(
profile_path
,
'rb'
).
read
()
if
(
len
(
data
)
>
0
):
profile_pb
=
profiler_pb2
.
Profile
()
...
...
@@ -115,22 +94,115 @@ class TestProfiler(unittest.TestCase):
event
.
name
.
startswith
(
"Runtime API"
)):
print
(
"Warning: unregister"
,
event
.
name
)
def
run_iter
(
self
,
exe
,
main_program
,
fetch_list
,
pass_acc_calculator
):
x
=
np
.
random
.
random
((
32
,
784
)).
astype
(
"float32"
)
y
=
np
.
random
.
randint
(
0
,
10
,
(
32
,
1
)).
astype
(
"int64"
)
outs
=
exe
.
run
(
main_program
,
feed
=
{
'x'
:
x
,
'y'
:
y
},
fetch_list
=
fetch_list
)
acc
=
np
.
array
(
outs
[
1
])
b_size
=
np
.
array
(
outs
[
2
])
pass_acc_calculator
.
add
(
value
=
acc
,
weight
=
b_size
)
pass_acc
=
pass_acc_calculator
.
eval
()
def
net_profiler
(
self
,
exe
,
state
,
tracer_option
,
batch_range
=
None
,
use_parallel_executor
=
False
,
use_new_api
=
False
):
main_program
,
startup_program
,
avg_cost
,
batch_size
,
batch_acc
=
self
.
build_program
(
compile_program
=
use_parallel_executor
)
exe
.
run
(
startup_program
)
profile_path
=
self
.
get_profile_path
()
if
not
use_new_api
:
with
profiler
.
profiler
(
state
,
'total'
,
profile_path
,
tracer_option
):
pass_acc_calculator
=
fluid
.
average
.
WeightedAverage
()
for
iter
in
range
(
10
):
if
iter
==
2
:
profiler
.
reset_profiler
()
self
.
run_iter
(
exe
,
main_program
,
[
avg_cost
,
batch_acc
,
batch_size
],
pass_acc_calculator
)
else
:
options
=
utils
.
ProfilerOptions
(
options
=
{
'state'
:
state
,
'sorted_key'
:
'total'
,
'tracer_level'
:
tracer_option
,
'batch_range'
:
[
0
,
10
]
if
batch_range
is
None
else
batch_range
,
'profile_path'
:
profile_path
})
with
utils
.
Profiler
(
enabled
=
True
,
options
=
options
)
as
prof
:
pass_acc_calculator
=
fluid
.
average
.
WeightedAverage
()
for
iter
in
range
(
10
):
self
.
run_iter
(
exe
,
main_program
,
[
avg_cost
,
batch_acc
,
batch_size
],
pass_acc_calculator
)
utils
.
get_profiler
().
record_step
()
if
batch_range
is
None
and
iter
==
2
:
utils
.
get_profiler
().
reset
()
self
.
check_profile_result
(
profile_path
)
def
test_cpu_profiler
(
self
):
self
.
net_profiler
(
'CPU'
,
"Default"
)
exe
=
fluid
.
Executor
(
fluid
.
CPUPlace
())
for
use_new_api
in
[
False
,
True
]:
self
.
net_profiler
(
exe
,
'CPU'
,
"Default"
,
batch_range
=
[
5
,
10
],
use_new_api
=
use_new_api
)
#self.net_profiler('CPU', "Default", use_parallel_executor=True)
@
unittest
.
skipIf
(
not
core
.
is_compiled_with_cuda
(),
"profiler is enabled only with GPU"
)
def
test_cuda_profiler
(
self
):
self
.
net_profiler
(
'GPU'
,
"OpDetail"
)
exe
=
fluid
.
Executor
(
fluid
.
CUDAPlace
(
0
))
for
use_new_api
in
[
False
,
True
]:
self
.
net_profiler
(
exe
,
'GPU'
,
"OpDetail"
,
batch_range
=
[
0
,
100
],
use_new_api
=
use_new_api
)
#self.net_profiler('GPU', "OpDetail", use_parallel_executor=True)
@
unittest
.
skipIf
(
not
core
.
is_compiled_with_cuda
(),
"profiler is enabled only with GPU"
)
def
test_all_profiler
(
self
):
self
.
net_profiler
(
'All'
,
"AllOpDetail"
)
exe
=
fluid
.
Executor
(
fluid
.
CUDAPlace
(
0
))
for
use_new_api
in
[
False
,
True
]:
self
.
net_profiler
(
exe
,
'All'
,
"AllOpDetail"
,
batch_range
=
None
,
use_new_api
=
use_new_api
)
#self.net_profiler('All', "AllOpDetail", use_parallel_executor=True)
class
TestProfilerAPIError
(
unittest
.
TestCase
):
def
test_errors
(
self
):
options
=
utils
.
ProfilerOptions
()
self
.
assertTrue
(
options
[
'profile_path'
]
is
None
)
self
.
assertTrue
(
options
[
'timeline_path'
]
is
None
)
options
=
options
.
with_state
(
'All'
)
self
.
assertTrue
(
options
[
'state'
]
==
'All'
)
try
:
print
(
options
[
'test'
])
except
ValueError
:
pass
global_profiler
=
utils
.
get_profiler
()
with
utils
.
Profiler
(
enabled
=
True
)
as
prof
:
self
.
assertTrue
(
utils
.
get_profiler
()
==
prof
)
self
.
assertTrue
(
global_profiler
!=
prof
)
if
__name__
==
'__main__'
:
unittest
.
main
()
python/paddle/utils/__init__.py
浏览文件 @
53619873
...
...
@@ -13,15 +13,13 @@
# limitations under the License.
from
.plot
import
Ploter
from
.profiler
import
ProfilerOptions
from
.profiler
import
Profiler
from
.profiler
import
get_profiler
__all__
=
[
'dump_config'
,
'Ploter'
]
#TODO: define new api under this directory
# __all__ = ['profiler',
# 'profiler.cuda_profiler',
# 'profiler.profiler',
# 'profiler.reset_profiler',
# 'profiler.start_profiler',
# 'profiler.stop_profiler',
# 'unique_name',
# __all__ = ['unique_name',
# 'load_op_library',
# 'require_version']
python/paddle/utils/profiler.py
浏览文件 @
53619873
# Copyright (c) 20
16
PaddlePaddle Authors. All Rights Reserved
# Copyright (c) 20
20
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.
...
...
@@ -12,9 +12,124 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#TODO: define new api of profiler
# __all__ = ['cuda_profiler',
# 'profiler',
# 'reset_profiler',
# 'start_profiler',
# 'stop_profiler']
from
__future__
import
print_function
import
sys
import
warnings
from
..fluid
import
core
from
..fluid.profiler
import
*
__all__
=
[
'ProfilerOptions'
,
'Profiler'
,
'get_profiler'
]
class
ProfilerOptions
(
object
):
def
__init__
(
self
,
options
=
None
):
self
.
options
=
{
'state'
:
'All'
,
'sorted_key'
:
'default'
,
'tracer_level'
:
'Default'
,
'batch_range'
:
[
0
,
sys
.
maxsize
],
'output_thread_detail'
:
False
,
'profile_path'
:
'none'
,
'timeline_path'
:
'none'
,
'op_summary_path'
:
'none'
}
if
options
is
not
None
:
for
key
in
self
.
options
.
keys
():
if
options
.
get
(
key
,
None
)
is
not
None
:
self
.
options
[
key
]
=
options
[
key
]
# function to set one specified option
def
with_state
(
self
,
state
):
self
.
options
[
'state'
]
=
state
return
self
def
__getitem__
(
self
,
name
):
if
self
.
options
.
get
(
name
,
None
)
is
None
:
raise
ValueError
(
"ProfilerOptions does not have an option named %s."
%
name
)
else
:
if
isinstance
(
self
.
options
[
name
],
str
)
and
self
.
options
[
name
]
==
'none'
:
return
None
else
:
return
self
.
options
[
name
]
_current_profiler
=
None
class
Profiler
(
object
):
def
__init__
(
self
,
enabled
=
True
,
options
=
None
):
if
options
is
not
None
:
self
.
profiler_options
=
options
else
:
self
.
profiler_options
=
ProfilerOptions
()
self
.
batch_id
=
0
self
.
enabled
=
enabled
def
__enter__
(
self
):
# record current profiler
global
_current_profiler
self
.
previous_profiler
=
_current_profiler
_current_profiler
=
self
if
self
.
enabled
:
if
self
.
profiler_options
[
'batch_range'
][
0
]
==
0
:
self
.
start
()
return
self
def
__exit__
(
self
,
exception_type
,
exception_value
,
traceback
):
global
_current_profiler
_current_profiler
=
self
.
previous_profiler
if
self
.
enabled
:
self
.
stop
()
def
start
(
self
):
if
self
.
enabled
:
try
:
start_profiler
(
state
=
self
.
profiler_options
[
'state'
],
tracer_option
=
self
.
profiler_options
[
'tracer_level'
])
except
Exception
as
e
:
warnings
.
warn
(
"Profiler is not enabled becuase following exception:
\n
{}"
.
format
(
e
))
def
stop
(
self
):
if
self
.
enabled
:
try
:
stop_profiler
(
sorted_key
=
self
.
profiler_options
[
'sorted_key'
],
profile_path
=
self
.
profiler_options
[
'profile_path'
])
except
Exception
as
e
:
warnings
.
warn
(
"Profiler is not disabled becuase following exception:
\n
{}"
.
format
(
e
))
def
reset
(
self
):
if
self
.
enabled
and
core
.
is_profiler_enabled
():
reset_profiler
()
def
record_step
(
self
,
change_profiler_status
=
True
):
if
not
self
.
enabled
:
return
self
.
batch_id
=
self
.
batch_id
+
1
if
change_profiler_status
:
if
self
.
batch_id
==
self
.
profiler_options
[
'batch_range'
][
0
]:
if
core
.
is_profiler_enabled
():
self
.
reset
()
else
:
self
.
start
()
if
self
.
batch_id
==
self
.
profiler_options
[
'batch_range'
][
1
]:
self
.
stop
()
def
get_profiler
():
global
_current_profiler
if
_current_profiler
is
None
:
_current_profiler
=
Profiler
()
return
_current_profiler
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录