Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
Paddle
提交
d50ae7ec
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看板
未验证
提交
d50ae7ec
编写于
11月 29, 2021
作者:
Z
Zhanlue Yang
提交者:
GitHub
11月 29, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Enabled AutoCodeGen for Eager Dygraph (#37639)
上级
87b97776
变更
13
显示空白变更内容
内联
并排
Showing
13 changed file
with
188 addition
and
30 deletion
+188
-30
paddle/fluid/eager/.gitignore
paddle/fluid/eager/.gitignore
+2
-0
paddle/fluid/eager/CMakeLists.txt
paddle/fluid/eager/CMakeLists.txt
+15
-2
paddle/fluid/eager/api/generated/.gitignore
paddle/fluid/eager/api/generated/.gitignore
+1
-0
paddle/fluid/eager/api/generated/CMakeLists.txt
paddle/fluid/eager/api/generated/CMakeLists.txt
+4
-0
paddle/fluid/eager/auto_code_generator/CMakeLists.txt
paddle/fluid/eager/auto_code_generator/CMakeLists.txt
+13
-2
paddle/fluid/eager/auto_code_generator/eager_generator.cc
paddle/fluid/eager/auto_code_generator/eager_generator.cc
+14
-22
paddle/fluid/eager/legacy/prepared_operator.cc
paddle/fluid/eager/legacy/prepared_operator.cc
+1
-1
paddle/fluid/eager/tests/CMakeLists.txt
paddle/fluid/eager/tests/CMakeLists.txt
+0
-3
paddle/fluid/eager/tests/task_tests/CMakeLists.txt
paddle/fluid/eager/tests/task_tests/CMakeLists.txt
+4
-0
paddle/fluid/eager/tests/task_tests/generated_test.cc
paddle/fluid/eager/tests/task_tests/generated_test.cc
+95
-0
paddle/fluid/eager/utils.cc
paddle/fluid/eager/utils.cc
+16
-0
paddle/fluid/eager/utils.h
paddle/fluid/eager/utils.h
+9
-0
paddle/fluid/framework/details/nan_inf_utils.h
paddle/fluid/framework/details/nan_inf_utils.h
+14
-0
未找到文件。
paddle/fluid/eager/.gitignore
0 → 100644
浏览文件 @
d50ae7ec
generated/**
autocodegen/generated_example/
\ No newline at end of file
paddle/fluid/eager/CMakeLists.txt
浏览文件 @
d50ae7ec
set
(
eager_deps pten pten_api hook_utils tensor_utils utils global_utils backward pten_tensor legacy autograd_meta grad_node_info grad_tensor_holder gradient_accumulation accumulation_node
)
set
(
fluid_deps tracer layer proto_desc operator op_registry variable_helper memcpy
)
set
(
generated_deps dygraph_function dygraph_node
)
if
(
NOT DEFINED ON_INFER
)
message
(
"Performing Eager Dygraph Auto Code Generation"
)
add_subdirectory
(
auto_code_generator
)
endif
()
add_subdirectory
(
api
)
add_subdirectory
(
accumulation
)
add_subdirectory
(
tests
)
add_subdirectory
(
legacy
)
cc_library
(
autograd_meta SRCS autograd_meta.cc DEPS pten pten_api
)
cc_library
(
grad_node_info SRCS grad_node_info.cc DEPS pten pten_api
)
cc_library
(
grad_tensor_holder SRCS grad_tensor_holder.cc DEPS grad_node_info gradient_accumulation
)
cc_library
(
autograd_meta SRCS autograd_meta.cc DEPS pten pten_api
)
cc_library
(
utils SRCS utils.cc DEPS pten pten_api global_utils layer proto_desc operator op_registry variable_helper memcpy scale_op autograd_meta
)
cc_library
(
legacy SRCS
${
DYGRAPH_LEGACY
}
DEPS global_utils proto_desc operator pten pten_api op_registry variable_helper memcpy
)
cc_library
(
backward SRCS backward.cc DEPS grad_tensor_holder utils autograd_meta grad_node_info
)
add_subdirectory
(
tests
)
paddle/fluid/eager/api/generated/.gitignore
0 → 100644
浏览文件 @
d50ae7ec
fluid_generated/**
paddle/fluid/eager/api/generated/CMakeLists.txt
浏览文件 @
d50ae7ec
add_subdirectory
(
eager_generated
)
if
(
NOT DEFINED ON_INFER
)
add_subdirectory
(
fluid_generated
)
endif
()
paddle/fluid/eager/auto_code_generator/CMakeLists.txt
浏览文件 @
d50ae7ec
...
...
@@ -6,13 +6,24 @@ target_link_libraries(eager_generator ${EAGER_GENERETOR_DEPS})
get_property
(
os_dependency_modules GLOBAL PROPERTY OS_DEPENDENCY_MODULES
)
target_link_libraries
(
eager_generator
${
os_dependency_modules
}
)
if
(
WITH_ROCM
)
target_link_libraries
(
eager_generator
${
ROCM_HIPRTC_LIB
}
)
endif
()
# Prepare file structure
message
(
"Generate dygraph file structure at path:
${
PADDLE_SOURCE_DIR
}
/paddle/fluid/eager/generated"
)
execute_process
(
COMMAND
"
${
PYTHON_EXECUTABLE
}
"
"
${
PADDLE_SOURCE_DIR
}
/paddle/fluid/eager/auto_code_generator/generate_file_structures.py"
"
${
PADDLE_SOURCE_DIR
}
/paddle/fluid/eager/"
)
add_custom_target
(
eager_codegen
if
(
WIN32
)
add_custom_target
(
eager_codegen
COMMAND
"
${
CMAKE_CURRENT_BINARY_DIR
}
/eager_generator.exe"
"
${
PADDLE_SOURCE_DIR
}
/paddle/fluid/eager/api/generated/fluid_generated"
DEPENDS eager_generator
VERBATIM
)
else
()
add_custom_target
(
eager_codegen
COMMAND
"
${
CMAKE_CURRENT_BINARY_DIR
}
/eager_generator"
"
${
PADDLE_SOURCE_DIR
}
/paddle/fluid/eager/api/generated/fluid_generated"
DEPENDS eager_generator
VERBATIM
)
endif
()
paddle/fluid/eager/auto_code_generator/eager_generator.cc
浏览文件 @
d50ae7ec
...
...
@@ -577,11 +577,6 @@ static std::string GenerateGradNodeCreationContent(
// If single output slotname and not duplicable,
// then generate: "egr::AutogradMeta* p_autograd_out =
// egr::EagerUtils::autograd_meta("op_proto->outputs()[0].name()")"
// TODO(zhanlve): in case of multiple slotname but none of which are
// duplicable,
// avoid constructing vector<AutogradMeta*>, generate seperate
// AutogradMeta* objects respectively.
std
::
string
get_autograd_meta_str
=
" // Prepare Autograd Meta
\n
"
;
for
(
const
proto
::
OpProto
::
Var
&
input
:
op_proto
.
inputs
())
{
const
std
::
string
&
input_name
=
input
.
name
();
...
...
@@ -607,11 +602,6 @@ static std::string GenerateGradNodeCreationContent(
// If single output slotname and not duplicable,
// then generate: "egr::AutogradMeta* p_autograd_out =
// egr::EagerUtils::autograd_meta("op_proto.outputs()[0].name()")"
// TODO(zhanlve): in case of multiple slotname but none of which are
// duplicable,
// avoid constructing vector<AutogradMeta*>, generate seperate
// AutogradMeta* objects respectively.
for
(
const
proto
::
OpProto
::
Var
&
output
:
op_proto
.
outputs
())
{
const
std
::
string
&
output_name
=
output
.
name
();
const
std
::
string
&
output_autograd_name
=
"p_autograd_"
+
output_name
;
...
...
@@ -725,9 +715,9 @@ static std::string GenerateGradNodeCreationContent(
// [Generation] GradNode Creation
const
char
*
GRAD_NODE_CREATION_TEMPLATE
=
" %s"
" bool require_any_grad = egr::ComputeRequireGrad(%s);
\n
"
" bool require_any_grad = egr::
EagerUtils::
ComputeRequireGrad(%s);
\n
"
" if(require_any_grad) {
\n
"
" egr::PassStopGradient(%s);
\n
"
" egr::
EagerUtils::
PassStopGradient(%s);
\n
"
"%s
\n
}"
;
std
::
string
grad_node_creation_body_str
=
paddle
::
string
::
Sprintf
(
GRAD_NODE_CREATION_TEMPLATE
,
prepare_autograd_meta_str
,
...
...
@@ -793,7 +783,7 @@ static std::pair<std::string, std::string> GenerateForwardFunctionContents(
Controller.Instance().GetExpectedPlace(), {});
// According to fwd_outputs_names
std::vector<egr::EagerTensor> Out0 = GetOutputs(outs["Out0"]);
std::vector<egr::EagerTensor> Out0 = G
GetOutput
etOutputs(outs["Out0"]);
egr::EagerTensor Out1 = GetOutputs(outs["Out1"][0]);
std::vector<egr::EagerTensor> Out2 = GetOutputs(outs["Out2"]);
...
...
@@ -830,7 +820,8 @@ static std::pair<std::string, std::string> GenerateForwardFunctionContents(
input_args_str_list
[
input_position
]
=
paddle
::
string
::
Sprintf
(
FWD_INS_ARG_TEMPLATE
,
input_name
);
}
const
char
*
FWD_INS_CONTENT_TEMPLATE
=
"{
\"
%s
\"
, egr::SyncToVars(%s) },"
;
const
char
*
FWD_INS_CONTENT_TEMPLATE
=
"{
\"
%s
\"
, egr::EagerUtils::SyncToVars(%s) },"
;
ins_contents_str
+=
paddle
::
string
::
Sprintf
(
FWD_INS_CONTENT_TEMPLATE
,
input_name
,
input_name
);
}
...
...
@@ -925,14 +916,14 @@ static std::pair<std::string, std::string> GenerateForwardFunctionContents(
if
(
output
.
duplicable
())
{
const
char
*
FWD_OUT_TENSORS_TEMPLATE
=
" std::vector<egr::EagerTensor> %s = "
"egr::GetOutputs(outs[
\"
%s
\"
]);
\n
"
;
"egr::
EagerUtils::
GetOutputs(outs[
\"
%s
\"
]);
\n
"
;
out_tensor_str
=
paddle
::
string
::
Sprintf
(
FWD_OUT_TENSORS_TEMPLATE
,
output_name
,
output_name
);
return_types
[
return_position
]
=
"std::vector<egr::EagerTensor>"
;
}
else
{
const
char
*
FWD_OUT_TENSOR_TEMPLATE
=
" egr::EagerTensor %s = "
"egr::GetOutput(outs[
\"
%s
\"
][0]);
\n
"
;
"egr::
EagerUtils::
GetOutput(outs[
\"
%s
\"
][0]);
\n
"
;
out_tensor_str
=
paddle
::
string
::
Sprintf
(
FWD_OUT_TENSOR_TEMPLATE
,
output_name
,
output_name
);
return_types
[
return_position
]
=
"egr::EagerTensor"
;
...
...
@@ -1093,7 +1084,8 @@ static std::string GenerateGradNodeCCContents(
grad_ins_fwd_slotname_map
.
at
(
grad_input_name
)
+
"_"
;
const
char
*
GRAD_INS_FWD_CONTENT_TEMPLATE
=
"{
\"
%s
\"
, "
"egr::SyncToVars(egr::EagerUtils::RecoverTensorWrapper(&this->%s, "
"egr::EagerUtils::SyncToVars(egr::EagerUtils::RecoverTensorWrapper(&"
"this->%s, "
"nullptr)) },"
;
ins_contents_str
+=
paddle
::
string
::
Sprintf
(
GRAD_INS_FWD_CONTENT_TEMPLATE
,
...
...
@@ -1104,7 +1096,7 @@ static std::string GenerateGradNodeCCContents(
size_t
fwd_output_position
=
fwd_outputs_name_pos_map
.
at
(
grad_ins_grad_slotname_map
.
at
(
grad_input_name
));
const
char
*
GRAD_INS_GRAD_CONTENT_TEMPLATE
=
"{
\"
%s
\"
, egr::SyncToVars(grads[%d]) },"
;
"{
\"
%s
\"
, egr::
EagerUtils::
SyncToVars(grads[%d]) },"
;
ins_contents_str
+=
paddle
::
string
::
Sprintf
(
GRAD_INS_GRAD_CONTENT_TEMPLATE
,
grad_input_name
,
fwd_output_position
);
...
...
@@ -1206,7 +1198,7 @@ static std::string GenerateGradNodeCCContents(
fwd_inputs_name_pos_map
.
at
(
grad_outs_slotname_map
.
at
(
grad_out_name
));
const
char
*
BWD_OUTPUT_TEMPLATE
=
" outputs[%d] = GetOutputs(outs[
\"
%s
\"
]);
\n
"
;
" outputs[%d] =
egr::EagerUtils::
GetOutputs(outs[
\"
%s
\"
]);
\n
"
;
outputs_str
+=
paddle
::
string
::
Sprintf
(
BWD_OUTPUT_TEMPLATE
,
fwd_input_position
,
grad_out_name
);
}
...
...
@@ -1526,6 +1518,9 @@ static void DygraphCodeGeneration(const std::string& output_dir) {
GenerateForwardHFile
(
output_dir
,
dygraph_forward_api_str
);
}
}
// namespace framework
}
// namespace paddle
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
!=
2
)
{
std
::
cerr
<<
"argc must be 2"
<<
std
::
endl
;
...
...
@@ -1537,6 +1532,3 @@ int main(int argc, char* argv[]) {
return
0
;
}
}
// namespace framework
}
// namespace paddle
paddle/fluid/eager/legacy/prepared_operator.cc
浏览文件 @
d50ae7ec
...
...
@@ -20,7 +20,7 @@
#include "paddle/fluid/framework/pten_utils.h"
#include "paddle/utils/small_vector.h"
#ifdef PADDLE_WITH_XPU
#include "paddle/fluid/platform/xpu/xpu_op_list.h"
#include "paddle/fluid/platform/
device/
xpu/xpu_op_list.h"
#endif
DECLARE_bool
(
check_nan_inf
);
DECLARE_bool
(
run_pten_kernel
);
...
...
paddle/fluid/eager/tests/CMakeLists.txt
浏览文件 @
d50ae7ec
set
(
eager_deps pten pten_api hook_utils tensor_utils utils global_utils backward pten_tensor autograd_meta grad_node_info grad_tensor_holder gradient_accumulation accumulation_node
)
set
(
fluid_deps tracer layer proto_desc operator op_registry variable_helper memcpy
)
add_subdirectory
(
data_structure_tests
)
add_subdirectory
(
task_tests
)
paddle/fluid/eager/tests/task_tests/CMakeLists.txt
浏览文件 @
d50ae7ec
...
...
@@ -5,3 +5,7 @@ cc_test(test_egr_task_backward SRCS backward_test.cc DEPS ${eager_deps} ${fluid_
cc_test
(
test_egr_task_hook SRCS hook_test.cc DEPS
${
eager_deps
}
${
fluid_deps
}
eager_scale scale_node
)
cc_test
(
test_egr_task_cross_batch SRCS cross_batch_accumulation_test.cc DEPS
${
eager_deps
}
${
fluid_deps
}
eager_scale scale_node
)
cc_test
(
test_egr_task_fwd_bwd_joint SRCS fwd_bwd_joint_test.cc DEPS
${
eager_deps
}
${
fluid_deps
}
eager_scale scale_node
)
if
(
NOT DEFINED ON_INFER
)
cc_test
(
test_egr_task_autocodegen SRCS generated_test.cc DEPS
${
eager_deps
}
${
fluid_deps
}
${
generated_deps
}
)
endif
()
paddle/fluid/eager/tests/task_tests/generated_test.cc
0 → 100644
浏览文件 @
d50ae7ec
// Copyright (c) 2021 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.
// Eager Dygraph
#include <chrono>
#include "gtest/gtest.h"
#include "paddle/fluid/eager/api/all.h"
#include "paddle/fluid/eager/api/utils/tensor_utils.h"
#include "paddle/fluid/eager/autograd_meta.h"
#include "paddle/fluid/eager/backward.h"
#include "paddle/fluid/eager/utils.h"
#include "paddle/fluid/eager/tests/test_utils.h"
#include "paddle/fluid/imperative/tracer.h"
#include "paddle/fluid/eager/api/generated/fluid_generated/dygraph_forward_api.h"
#include "paddle/pten/core/kernel_registry.h"
// TODO(jiabin): remove nolint here!!!
using
namespace
egr
;
// NOLINT
namespace
eager_test
{
TEST
(
Generated
,
Sigmoid
)
{
// Prepare Device Contexts
InitEnv
(
paddle
::
platform
::
CPUPlace
());
VLOG
(
6
)
<<
"Init Env"
;
// 1. Prepare Input
paddle
::
framework
::
DDim
ddim
=
paddle
::
framework
::
make_ddim
({
2
,
4
,
4
,
4
});
VLOG
(
6
)
<<
"Make Dim"
;
egr
::
EagerTensor
tensor
=
CreateTensorWithValue
(
ddim
,
paddle
::
platform
::
CPUPlace
(),
pten
::
DataType
::
FLOAT32
,
pten
::
DataLayout
::
NCHW
,
0.0
,
true
);
VLOG
(
6
)
<<
"Make EagerTensor"
;
RetainGradForTensor
(
tensor
);
VLOG
(
6
)
<<
"Retain Grad for Tensor"
;
auto
output_tensor
=
sigmoid_dygraph_function
(
tensor
,
{});
VLOG
(
6
)
<<
"Run Backward"
;
CompareVariableWithValue
<
float
>
(
output_tensor
,
0.5
);
std
::
vector
<
egr
::
EagerTensor
>
target_tensors
=
{
output_tensor
};
VLOG
(
6
)
<<
"Runing Backward"
;
RunBackward
(
target_tensors
,
{});
VLOG
(
6
)
<<
"Finish Backward"
;
CompareGradVariableWithValue
<
float
>
(
tensor
,
0.25
);
}
TEST
(
Generated
,
Matmul_v2
)
{
// Prepare Device Contexts
InitEnv
(
paddle
::
platform
::
CPUPlace
());
auto
tracer
=
std
::
make_shared
<
paddle
::
imperative
::
Tracer
>
();
paddle
::
imperative
::
SetCurrentTracer
(
tracer
);
// 1. Prepare Input
paddle
::
framework
::
DDim
ddimX
=
paddle
::
framework
::
make_ddim
({
4
,
16
});
egr
::
EagerTensor
X
=
CreateTensorWithValue
(
ddimX
,
paddle
::
platform
::
CPUPlace
(),
pten
::
DataType
::
FLOAT32
,
pten
::
DataLayout
::
NCHW
,
3.0
,
true
);
RetainGradForTensor
(
X
);
paddle
::
framework
::
DDim
ddimY
=
paddle
::
framework
::
make_ddim
({
16
,
20
});
egr
::
EagerTensor
Y
=
CreateTensorWithValue
(
ddimY
,
paddle
::
platform
::
CPUPlace
(),
pten
::
DataType
::
FLOAT32
,
pten
::
DataLayout
::
NCHW
,
2.0
,
true
);
RetainGradForTensor
(
Y
);
auto
output_tensor
=
matmul_v2_dygraph_function
(
X
,
Y
,
{{
"trans_x"
,
false
},
{
"trans_y"
,
false
}});
CompareVariableWithValue
<
float
>
(
output_tensor
,
96
);
std
::
vector
<
egr
::
EagerTensor
>
target_tensors
=
{
output_tensor
};
RunBackward
(
target_tensors
,
{});
CompareGradVariableWithValue
<
float
>
(
X
,
2.0
*
20
);
CompareGradVariableWithValue
<
float
>
(
Y
,
3.0
*
4
);
}
}
// namespace eager_test
paddle/fluid/eager/utils.cc
浏览文件 @
d50ae7ec
...
...
@@ -14,6 +14,7 @@
#include "paddle/fluid/eager/utils.h"
#include "paddle/fluid/eager/api/utils/global_utils.h"
#include "paddle/fluid/eager/tensor_wrapper.h"
#include "paddle/pten/api/all.h"
#include "paddle/pten/common/layout.h"
...
...
@@ -188,4 +189,19 @@ egr::EagerTensor EagerUtils::GetOutput(
return
EagerTensor
((
*
(
out
.
get
())));
}
EagerTensor
EagerUtils
::
RecoverTensorWrapper
(
TensorWrapper
*
tw
,
const
std
::
shared_ptr
<
GradNodeBase
>&
grad_node
)
{
return
tw
->
recover
(
grad_node
);
}
std
::
vector
<
EagerTensor
>
EagerUtils
::
RecoverTensorWrapper
(
std
::
vector
<
TensorWrapper
>*
tw
,
const
std
::
shared_ptr
<
GradNodeBase
>&
grad_node
)
{
std
::
vector
<
EagerTensor
>
ret
;
for
(
auto
&
t
:
*
tw
)
{
ret
.
emplace_back
(
t
.
recover
(
grad_node
));
}
return
ret
;
}
}
// namespace egr
paddle/fluid/eager/utils.h
浏览文件 @
d50ae7ec
...
...
@@ -22,6 +22,8 @@
namespace
egr
{
class
TensorWrapper
;
/**
* EagerUtils is utils used to do some static conversion or autograd
* members access, this class is desinged to be a full static functional
...
...
@@ -131,6 +133,13 @@ class EagerUtils {
iter
.
apply
(
std
::
forward
<
Args
>
(
args
)...);
}
// TensorWrapper Utils
static
egr
::
EagerTensor
RecoverTensorWrapper
(
egr
::
TensorWrapper
*
tw
,
const
std
::
shared_ptr
<
GradNodeBase
>&
grad_node
);
static
std
::
vector
<
egr
::
EagerTensor
>
RecoverTensorWrapper
(
std
::
vector
<
egr
::
TensorWrapper
>*
tw
,
const
std
::
shared_ptr
<
GradNodeBase
>&
grad_node
);
// Intermidate needed remove this once we don't need legacy
static
std
::
vector
<
std
::
shared_ptr
<
egr
::
EagerTensor
>>
SyncToVars
(
const
egr
::
EagerTensor
&
tensor
);
...
...
paddle/fluid/framework/details/nan_inf_utils.h
浏览文件 @
d50ae7ec
...
...
@@ -17,6 +17,7 @@
#include <string>
#include <vector>
#include "paddle/fluid/eager/legacy/type_def.h"
#include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/framework/scope.h"
#include "paddle/fluid/imperative/type_defs.h"
...
...
@@ -53,6 +54,19 @@ void CheckOpHasNanOrInfInDygraph(const std::string& op_type,
}
}
template
<
typename
TensorType
>
static
void
CheckOpHasNanOrInfInEager
(
const
std
::
string
&
op_type
,
const
egr
::
NameMap
<
TensorType
>&
op_outs
,
platform
::
Place
place
)
{
for
(
const
auto
&
pair
:
op_outs
)
{
for
(
const
auto
&
tensor
:
pair
.
second
)
{
auto
*
var
=
tensor
->
MutableVar
();
if
(
var
==
nullptr
)
continue
;
CheckVarHasNanOrInf
(
op_type
,
tensor
->
name
(),
var
,
place
);
}
}
}
#ifdef PADDLE_WITH_ASCEND_CL
void
NPUAllocAndClearFloatStatus
(
const
framework
::
OperatorBase
&
op
,
const
framework
::
ScopeBase
&
scope
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录