Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
04e3b62f
P
Paddle
项目概览
PaddlePaddle
/
Paddle
1 年多 前同步成功
通知
2302
Star
20931
Fork
5422
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
04e3b62f
编写于
11月 26, 2021
作者:
Z
Zhanlue Yang
提交者:
GitHub
11月 26, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Eager] Supported Eager Dygraph Forward & AutoGrad functions (#37323)
上级
a0b895c0
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
615 addition
and
3 deletion
+615
-3
paddle/fluid/eager/CMakeLists.txt
paddle/fluid/eager/CMakeLists.txt
+2
-2
paddle/fluid/eager/api/CMakeLists.txt
paddle/fluid/eager/api/CMakeLists.txt
+3
-0
paddle/fluid/eager/api/all.h
paddle/fluid/eager/api/all.h
+1
-0
paddle/fluid/eager/api/generated/CMakeLists.txt
paddle/fluid/eager/api/generated/CMakeLists.txt
+1
-0
paddle/fluid/eager/api/generated/eager_generated/CMakeLists.txt
.../fluid/eager/api/generated/eager_generated/CMakeLists.txt
+2
-0
paddle/fluid/eager/api/generated/eager_generated/backwards/CMakeLists.txt
...er/api/generated/eager_generated/backwards/CMakeLists.txt
+1
-0
paddle/fluid/eager/api/generated/eager_generated/backwards/scale_node.cc
...ger/api/generated/eager_generated/backwards/scale_node.cc
+172
-0
paddle/fluid/eager/api/generated/eager_generated/backwards/scale_node.h
...ager/api/generated/eager_generated/backwards/scale_node.h
+54
-0
paddle/fluid/eager/api/generated/eager_generated/forwards/CMakeLists.txt
...ger/api/generated/eager_generated/forwards/CMakeLists.txt
+1
-0
paddle/fluid/eager/api/generated/eager_generated/forwards/scale.cc
...uid/eager/api/generated/eager_generated/forwards/scale.cc
+100
-0
paddle/fluid/eager/api/generated/eager_generated/forwards/scale.h
...luid/eager/api/generated/eager_generated/forwards/scale.h
+23
-0
paddle/fluid/eager/tests/CMakeLists.txt
paddle/fluid/eager/tests/CMakeLists.txt
+3
-1
paddle/fluid/eager/tests/task_tests/CMakeLists.txt
paddle/fluid/eager/tests/task_tests/CMakeLists.txt
+1
-0
paddle/fluid/eager/tests/task_tests/forward_autograd_test.cc
paddle/fluid/eager/tests/task_tests/forward_autograd_test.cc
+251
-0
未找到文件。
paddle/fluid/eager/CMakeLists.txt
浏览文件 @
04e3b62f
add_subdirectory
(
accumulation
)
add_subdirectory
(
api
)
add_subdirectory
(
accumulation
)
add_subdirectory
(
tests
)
cc_library
(
grad_node_info SRCS grad_node_info.cc DEPS pten pten_api
)
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
(
utils SRCS utils.cc DEPS pten pten_api global_utils layer proto_desc operator op_registry variable_helper memcpy scale_op autograd_meta
)
paddle/fluid/eager/api/CMakeLists.txt
浏览文件 @
04e3b62f
add_subdirectory
(
utils
)
add_subdirectory
(
generated
)
cc_library
(
eager_api SRCS all.cc DEPS global_utils eager_scale
)
paddle/fluid/eager/api/all.h
浏览文件 @
04e3b62f
...
...
@@ -14,4 +14,5 @@
//
#pragma once
#include "paddle/fluid/eager/api/generated/eager_generated/forwards/scale.h"
#include "paddle/fluid/eager/api/utils/global_utils.h"
paddle/fluid/eager/api/generated/CMakeLists.txt
0 → 100644
浏览文件 @
04e3b62f
add_subdirectory
(
eager_generated
)
paddle/fluid/eager/api/generated/eager_generated/CMakeLists.txt
0 → 100644
浏览文件 @
04e3b62f
add_subdirectory
(
backwards
)
add_subdirectory
(
forwards
)
paddle/fluid/eager/api/generated/eager_generated/backwards/CMakeLists.txt
0 → 100644
浏览文件 @
04e3b62f
cc_library
(
scale_node SRCS scale_node.cc DEPS global_utils pten pten_api grad_node_info
)
paddle/fluid/eager/api/generated/eager_generated/backwards/scale_node.cc
0 → 100644
浏览文件 @
04e3b62f
// 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.
#include "paddle/fluid/eager/api/generated/eager_generated/backwards/scale_node.h"
#include "paddle/fluid/eager/api/utils/global_utils.h"
#include "paddle/fluid/eager/eager_tensor.h"
#include "paddle/pten/api/all.h"
#include "paddle/fluid/platform/device_context.h"
#include "paddle/fluid/platform/enforce.h"
#include "paddle/fluid/platform/errors.h"
#include "glog/logging.h"
namespace
egr
{
template
<
typename
DeviceContext
>
static
void
ScaleDeviceDispatch
(
const
pten
::
DenseTensor
&
dense_tensor
,
const
DeviceContext
&
dev_ctx
,
float
scale
,
float
bias
,
bool
bias_after_scale
,
pten
::
DenseTensor
*
dense_out
)
{
switch
(
dense_tensor
.
dtype
())
{
case
pten
::
DataType
::
FLOAT64
:
{
pten
::
Scale
<
double
>
(
dev_ctx
,
dense_tensor
/* tensor */
,
scale
/* scale */
,
bias
/* bias */
,
bias_after_scale
/* bias_after_scale */
,
dense_out
/* out tensor */
);
break
;
}
case
pten
::
DataType
::
FLOAT32
:
{
pten
::
Scale
<
float
>
(
dev_ctx
,
dense_tensor
/* tensor */
,
scale
/* scale */
,
bias
/* bias */
,
bias_after_scale
/* bias_after_scale */
,
dense_out
/* out tensor */
);
break
;
}
case
pten
::
DataType
::
INT64
:
{
pten
::
Scale
<
int64_t
>
(
dev_ctx
,
dense_tensor
/* tensor */
,
scale
/* scale */
,
bias
/* bias */
,
bias_after_scale
/* bias_after_scale */
,
dense_out
/* out tensor */
);
break
;
}
case
pten
::
DataType
::
INT32
:
{
pten
::
Scale
<
int32_t
>
(
dev_ctx
,
dense_tensor
/* tensor */
,
scale
/* scale */
,
bias
/* bias */
,
bias_after_scale
/* bias_after_scale */
,
dense_out
/* out tensor */
);
break
;
}
default:
{
PADDLE_THROW
(
paddle
::
platform
::
errors
::
Fatal
(
"Detected unsupported data type."
"Only Float64, Float32, Int64, Int32 are supported for now."
));
break
;
}
}
}
void
ScaleAPI
(
const
egr
::
EagerTensor
&
x
,
float
scale
,
float
bias
,
bool
bias_after_scale
,
egr
::
EagerTensor
*
out
)
{
// TODO(jiabin): Support multiple tensor here, Create DenseTensor is not a
// proper way to Demo it
// Run Forward Function
auto
dense_tensor
=
std
::
dynamic_pointer_cast
<
pten
::
DenseTensor
>
(
x
.
impl
());
// Init output tensor
auto
tensor_meta
=
pten
::
DenseTensorMeta
(
dense_tensor
->
dtype
(),
dense_tensor
->
dims
(),
dense_tensor
->
layout
());
auto
place
=
dense_tensor
->
place
();
size_t
bytes_size
=
paddle
::
framework
::
product
(
dense_tensor
->
dims
())
*
SizeOf
(
dense_tensor
->
dtype
());
auto
dense_out
=
std
::
make_shared
<
pten
::
DenseTensor
>
(
pten
::
make_intrusive
<
paddle
::
experimental
::
SharedStorage
>
(
paddle
::
memory
::
Alloc
(
place
,
bytes_size
),
0
),
std
::
move
(
tensor_meta
));
// Handle Device Context
const
paddle
::
platform
::
Place
&
expected_kernel_place
=
Controller
::
Instance
().
GetExpectedPlace
();
paddle
::
platform
::
DeviceContextPool
&
pool
=
paddle
::
platform
::
DeviceContextPool
::
Instance
();
if
(
expected_kernel_place
==
paddle
::
platform
::
CPUPlace
())
{
auto
*
dev_ctx
=
dynamic_cast
<
paddle
::
platform
::
CPUDeviceContext
*>
(
pool
.
Get
(
expected_kernel_place
));
if
(
!
dev_ctx
)
{
PADDLE_THROW
(
paddle
::
platform
::
errors
::
Fatal
(
"Cannot convert device_context to CPUDeviceContext."
"This indicates backend mismatch."
"Pleas double check your expected place"
));
}
ScaleDeviceDispatch
<
paddle
::
platform
::
CPUDeviceContext
>
(
*
dense_tensor
.
get
(),
*
dev_ctx
,
scale
,
bias
,
bias_after_scale
,
dense_out
.
get
());
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
}
else
if
(
expected_kernel_place
==
paddle
::
platform
::
CUDAPlace
())
{
auto
*
dev_ctx
=
dynamic_cast
<
paddle
::
platform
::
CUDADeviceContext
*>
(
pool
.
Get
(
expected_kernel_place
));
if
(
!
dev_ctx
)
{
PADDLE_THROW
(
paddle
::
platform
::
errors
::
Fatal
(
"Cannot convert device_context to CUDADeviceContext."
"This indicates backend mismatch."
"Pleas double check your expected place"
));
}
ScaleDeviceDispatch
<
paddle
::
platform
::
CUDADeviceContext
>
(
*
dense_tensor
.
get
(),
*
dev_ctx
,
scale
,
bias
,
bias_after_scale
,
dense_out
.
get
());
#endif
}
else
{
PADDLE_THROW
(
paddle
::
platform
::
errors
::
Fatal
(
"Detected unsupported backend."
"Only CPU and CUDA Backend are supported for now."
"Please double check if your backend falls into the above two "
"categories."
));
}
out
->
set_impl
(
dense_out
);
}
void
GradNodeScale
::
SetTensorWrappers_X
(
const
std
::
vector
<
egr
::
EagerTensor
>&
tensors
)
{
// Does nothing for scale
}
void
GradNodeScale
::
SetAttributes_scale
(
float
scale
)
{
scale_
=
scale
;
}
std
::
vector
<
std
::
vector
<
egr
::
EagerTensor
>>
GradNodeScale
::
operator
()(
const
std
::
vector
<
std
::
vector
<
egr
::
EagerTensor
>>&
grads
)
{
// 1. Check Output Size
PADDLE_ENFORCE
(
((
grads
.
size
()
==
1
)
&&
(
grads
[
0
].
size
()
==
1
)),
paddle
::
platform
::
errors
::
Fatal
(
"ScaleGradNode takes exactly 1 grad tensor."
"However received: %d"
,
"This indicates an issue with Eager Dygraph Backward logic"
,
grads
.
size
()));
std
::
vector
<
std
::
vector
<
egr
::
EagerTensor
>>
outs
;
// 2. Create needed out parttern
egr
::
EagerTensor
out
;
// Apply Gradient Hooks
if
(
GradientHooksRegistered
())
{
// TODO(jiabin): Shall we apply hook slot by slot here or accept
// vector<vector<pten::tensor>> to apply all hooks?
std
::
vector
<
std
::
vector
<
egr
::
EagerTensor
>>
hooked_grads
=
ApplyGradientHooks
(
grads
);
ScaleAPI
(
/* slot by slot set */
hooked_grads
[
0
][
0
],
scale_
,
0.0
/* bias */
,
true
/* bias_after_scale */
,
&
out
);
}
else
{
ScaleAPI
(
grads
[
0
][
0
],
scale_
,
0.0
/* bias */
,
true
/* bias_after_scale */
,
&
out
);
}
// Apply Reduce Hooks
if
(
ReduceHooksRegistered
())
{
ApplyReduceHooks
();
}
return
{{
out
}};
}
}
// namespace egr
paddle/fluid/eager/api/generated/eager_generated/backwards/scale_node.h
0 → 100644
浏览文件 @
04e3b62f
// 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.
#pragma once
#include "paddle/fluid/eager/grad_node_info.h"
#include "paddle/fluid/eager/tensor_wrapper.h"
/*
Each Operation has a specific GradNode inheritted from GradNodeBase
A specific GradNode defines
1. Input Tensors
2. overrides operator() to perform actual backward computations
TODO: Generate GradNode via auto-code-generation
*/
namespace
egr
{
void
ScaleAPI
(
const
egr
::
EagerTensor
&
x
,
float
scale
,
float
bias
,
bool
bias_after_scale
,
egr
::
EagerTensor
*
out
);
class
GradNodeScale
:
public
GradNodeBase
{
public:
// Constructor: configure fwd input tensors to grad node
GradNodeScale
(
size_t
bwd_in_slot_num
,
size_t
bwd_out_slot_num
)
:
GradNodeBase
(
bwd_in_slot_num
,
bwd_out_slot_num
)
{}
~
GradNodeScale
()
override
=
default
;
// Functor: perform backward computations
virtual
std
::
vector
<
std
::
vector
<
egr
::
EagerTensor
>>
operator
()(
const
std
::
vector
<
std
::
vector
<
egr
::
EagerTensor
>>&
grads
)
override
;
void
SetTensorWrappers_X
(
const
std
::
vector
<
egr
::
EagerTensor
>&
tensors
);
void
SetAttributes_scale
(
float
scale
);
// Members: define fwd input tensors
// For Scale there is no fwd input tensor needed
private:
float
scale_
{
1.0
};
};
}
// namespace egr
paddle/fluid/eager/api/generated/eager_generated/forwards/CMakeLists.txt
0 → 100644
浏览文件 @
04e3b62f
cc_library
(
eager_scale SRCS scale.cc DEPS pten_api pten autograd_meta scale_node
)
paddle/fluid/eager/api/generated/eager_generated/forwards/scale.cc
0 → 100644
浏览文件 @
04e3b62f
// 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.
/**
* This File should be automatically generated by coding auto generator.
* All ops C++ autograd logic is defined here, in Python-C extension API
* system we try to avoid any autograd related code, and move them all to
* here.
*
* Currently, we just manually do some fwd autograd here. And we will replace
* them with auto code generator later.
* **/
#include "paddle/fluid/eager/api/generated/eager_generated/forwards/scale.h"
#include "paddle/fluid/eager/api/generated/eager_generated/backwards/scale_node.h"
#include "paddle/fluid/eager/autograd_meta.h"
#include "paddle/fluid/eager/eager_tensor.h"
#include "paddle/fluid/eager/utils.h"
#include "paddle/pten/api/all.h"
#include "paddle/pten/include/core.h"
namespace
egr
{
egr
::
EagerTensor
scale
(
const
egr
::
EagerTensor
&
x
,
float
scale
,
float
bias
,
bool
bias_after_scale
,
bool
trace_backward
)
{
// 1. Run Forward
// 1.1 Create outputs
egr
::
EagerTensor
out
;
// 1.2 Need by original op, we assemble ins, outs, attrs here
// 1.3 Call forward C++ api
ScaleAPI
(
x
,
scale
,
bias
,
bias_after_scale
,
&
out
);
// 2. Build Backward Depends
// 2.1 Get AutogradMetas for all ins and outs
auto
p_autograd_in
=
EagerUtils
::
unsafe_autograd_meta
(
x
);
// NOTE: Call EagerUtils::multi_autograd_meta when we have vector of outputs
auto
p_autograd_out
=
EagerUtils
::
autograd_meta
(
&
out
);
// 2.2 Add GradNode
// 2.2.1 ComputeRequireGrad
// TODO(jiabin) : make this function accept different kinds of input
// TODO(zhanlve): which one is more efficient:
// 1. construct a vector of pointers
// 2. call "ComputeRequireGrad" multiple times
bool
require_any_grad
=
EagerUtils
::
ComputeRequireGrad
(
trace_backward
,
p_autograd_in
);
if
(
require_any_grad
)
{
EagerUtils
::
PassStopGradient
(
false
/*generate_grad*/
,
p_autograd_out
);
// 2.2.2 Set OutRankInfo for outputs this needs to be as same as Edges's
// input_rank_
/** Note:
// 1. We provide EagerUtils::SetMultiOutRank(vector<AutogradMeta*>),
// since we have some of Operator has servel slot name with duplicate
outputs.
// 2. We call AutogradMeta's SetOutput Rank only when we have single output
with
// single slot name.
**/
p_autograd_out
->
SetSingleOutRankWithSlot
(
0
,
0
);
// Init GradNode
auto
scale_node
=
std
::
make_shared
<
GradNodeScale
>
(
/* fwd_in_slot_num */
1
,
/* bwd_in_slot_num */
1
);
// Pass Attributes to GradNode
scale_node
->
SetAttributes_scale
(
scale
);
// Set Next Edges
scale_node
->
AddEdges
(
*
p_autograd_in
,
/*slot id*/
0
);
// Set TensorWrappers
scale_node
->
SetTensorWrappers_X
({
x
});
// Set Grad out rank as same as fwd input and set stop gradient to bwd
scale_node
->
SetGradOutMeta
(
*
p_autograd_in
,
/*slot id*/
0
);
// Set Grad out rank as same as fwd input and set stop gradient to bwd
scale_node
->
SetGradInMeta
(
*
p_autograd_out
,
/*slot id*/
0
);
// Set History for output set current Grad Node for
EagerUtils
::
SetHistory
(
p_autograd_out
,
scale_node
);
}
return
out
;
}
}
// namespace egr
paddle/fluid/eager/api/generated/eager_generated/forwards/scale.h
0 → 100644
浏览文件 @
04e3b62f
// 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.
#pragma once
#include "paddle/fluid/eager/eager_tensor.h"
namespace
egr
{
egr
::
EagerTensor
scale
(
const
egr
::
EagerTensor
&
x
,
float
scale
,
float
bias
,
bool
bias_after_scale
,
bool
trace_backward
);
}
// namespace egr
paddle/fluid/eager/tests/CMakeLists.txt
浏览文件 @
04e3b62f
set
(
eager_deps pten pten_api utils tensor_utils global_utils pten_tensor autograd_meta grad_node_info grad_tensor_holder gradient_accumulation accumulation_node
)
set
(
eager_deps pten pten_api tensor_utils utils global_utils 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
浏览文件 @
04e3b62f
cc_test
(
test_egr_task_tensor_utils SRCS tensor_utils_test.cc DEPS
${
eager_deps
}
)
cc_test
(
test_egr_task_eager_utils SRCS eager_utils_test.cc DEPS
${
eager_deps
}
)
cc_test
(
test_egr_task_forward_autograd SRCS forward_autograd_test.cc DEPS
${
eager_deps
}
${
fluid_deps
}
eager_scale scale_node
)
paddle/fluid/eager/tests/task_tests/forward_autograd_test.cc
0 → 100644
浏览文件 @
04e3b62f
// 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.
#include <sstream>
#include "glog/logging.h"
#include "gtest/gtest.h"
#include "paddle/fluid/eager/api/all.h"
#include "paddle/fluid/eager/api/generated/eager_generated/backwards/scale_node.h"
#include "paddle/fluid/eager/api/utils/tensor_utils.h"
#include "paddle/fluid/eager/autograd_meta.h"
#include "paddle/fluid/eager/grad_node_info.h"
#include "paddle/fluid/eager/tests/test_utils.h"
#include "paddle/pten/core/dense_tensor.h"
#include "paddle/pten/core/tensor_meta.h"
// TODO(jiabin): remove nolint here!!!
using
namespace
egr
;
// NOLINT
namespace
eager_test
{
TEST
(
Forward
,
SingleNode
)
{
// Prepare Device Contexts
InitEnv
(
paddle
::
platform
::
CPUPlace
());
// Prepare Inputs
std
::
vector
<
egr
::
EagerTensor
>
target_tensors
;
paddle
::
framework
::
DDim
ddim
=
paddle
::
framework
::
make_ddim
({
4
,
16
,
16
,
32
});
// Create Target Tensor
egr
::
EagerTensor
t
=
CreateTensorWithValue
(
ddim
,
paddle
::
platform
::
CPUPlace
(),
pten
::
DataType
::
FLOAT32
,
pten
::
DataLayout
::
NCHW
,
5.0
/*value*/
,
false
/*is_leaf*/
);
target_tensors
.
emplace_back
(
std
::
move
(
t
));
egr
::
EagerTensor
&
tensor
=
target_tensors
[
0
];
EagerUtils
::
autograd_meta
(
&
tensor
)
->
SetStopGradient
(
false
);
// Run Forward
float
scale
=
2.0
;
float
bias
=
3.0
;
egr
::
EagerTensor
out
=
egr
::
scale
(
tensor
,
scale
,
bias
,
true
/*bias_after_scale*/
,
true
/*trace_backward*/
);
// Examine Forward Output
CompareTensorWithValue
<
float
>
(
out
,
13.0
);
// Examine GradNode
{
// 1. GradNode
AutogradMeta
*
meta
=
EagerUtils
::
autograd_meta
(
&
out
);
GradNodeBase
*
grad_node
=
meta
->
GradNode
();
GradNodeScale
*
scale_node
=
dynamic_cast
<
GradNodeScale
*>
(
grad_node
);
CHECK_NOTNULL
(
scale_node
);
CHECK_EQ
(
static_cast
<
int
>
(
meta
->
OutRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
meta
->
OutRankInfo
().
second
),
0
);
}
}
/*
inp
|
Node0
|
Node1
|
out
*/
TEST
(
Forward
,
LinearNodes
)
{
InitEnv
(
paddle
::
platform
::
CPUPlace
());
// Prepare Inputs
std
::
vector
<
egr
::
EagerTensor
>
target_tensors
;
paddle
::
framework
::
DDim
ddim
=
paddle
::
framework
::
make_ddim
({
4
,
16
,
16
,
32
});
// Create Target Tensor
egr
::
EagerTensor
t
=
CreateTensorWithValue
(
ddim
,
paddle
::
platform
::
CPUPlace
(),
pten
::
DataType
::
FLOAT32
,
pten
::
DataLayout
::
NCHW
,
5.0
/*value*/
,
false
/*is_leaf*/
);
target_tensors
.
emplace_back
(
std
::
move
(
t
));
egr
::
EagerTensor
&
tensor
=
target_tensors
[
0
];
EagerUtils
::
autograd_meta
(
&
tensor
)
->
SetStopGradient
(
false
);
// Run Forward Node 0
float
scale0
=
2.0
;
float
bias0
=
3.0
;
egr
::
EagerTensor
out0
=
egr
::
scale
(
tensor
,
scale0
,
bias0
,
true
/*bias_after_scale*/
,
true
/*trace_backward*/
);
// Run Forward Node 1
float
scale1
=
5.0
;
float
bias1
=
10.0
;
egr
::
EagerTensor
out1
=
egr
::
scale
(
out0
,
scale1
,
bias1
,
true
/*bias_after_scale*/
,
true
/*trace_backward*/
);
// Examine Forward Output 0
CompareTensorWithValue
<
float
>
(
out0
,
13.0
);
// Examine Forward Output 1
CompareTensorWithValue
<
float
>
(
out1
,
75.0
);
// Examine GradNode
{
// 1. GradNode
// Node 0
AutogradMeta
*
meta0
=
EagerUtils
::
autograd_meta
(
&
out0
);
GradNodeBase
*
grad_node0
=
meta0
->
GradNode
();
GradNodeScale
*
scale_node0
=
dynamic_cast
<
GradNodeScale
*>
(
grad_node0
);
CHECK_NOTNULL
(
scale_node0
);
CHECK_EQ
(
static_cast
<
int
>
(
meta0
->
OutRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
meta0
->
OutRankInfo
().
second
),
0
);
// Node 1
AutogradMeta
*
meta1
=
EagerUtils
::
autograd_meta
(
&
out1
);
GradNodeBase
*
grad_node1
=
meta1
->
GradNode
();
GradNodeScale
*
scale_node1
=
dynamic_cast
<
GradNodeScale
*>
(
grad_node1
);
CHECK_NOTNULL
(
scale_node1
);
CHECK_EQ
(
static_cast
<
int
>
(
meta1
->
OutRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
meta1
->
OutRankInfo
().
second
),
0
);
// 2. TensorWrapper: No TensorWrapper for ScaleNode
// 3. NextEdges: Node 1 -> Node 0
const
std
::
vector
<
std
::
vector
<
Edge
>>&
node1_edges
=
grad_node1
->
GetEdges
();
const
auto
&
node1_edge
=
node1_edges
[
0
];
CHECK_EQ
(
static_cast
<
int
>
(
node1_edge
[
0
].
GetEdgeRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
node1_edge
[
0
].
GetEdgeRankInfo
().
second
),
0
);
CHECK_EQ
(
node1_edge
[
0
].
GetGradNode
(),
grad_node0
);
}
}
/*
inp
|
Node0
____|____
| |
Node1 Node2
| |
out1 out2
*/
TEST
(
Forward
,
BranchedNodes
)
{
InitEnv
(
paddle
::
platform
::
CPUPlace
());
// Prepare Inputs
std
::
vector
<
egr
::
EagerTensor
>
target_tensors
;
paddle
::
framework
::
DDim
ddim
=
paddle
::
framework
::
make_ddim
({
4
,
16
,
16
,
32
});
// Create Target Tensor
egr
::
EagerTensor
t
=
CreateTensorWithValue
(
ddim
,
paddle
::
platform
::
CPUPlace
(),
pten
::
DataType
::
FLOAT32
,
pten
::
DataLayout
::
NCHW
,
5.0
/*value*/
,
false
/*is_leaf*/
);
target_tensors
.
emplace_back
(
std
::
move
(
t
));
egr
::
EagerTensor
&
tensor
=
target_tensors
[
0
];
EagerUtils
::
autograd_meta
(
&
tensor
)
->
SetStopGradient
(
false
);
// Run Forward Node 0
float
scale0
=
2.0
;
float
bias0
=
3.0
;
egr
::
EagerTensor
out0
=
egr
::
scale
(
tensor
,
scale0
,
bias0
,
true
/*bias_after_scale*/
,
true
/*trace_backward*/
);
// Run Forward Node 1
float
scale1
=
5.0
;
float
bias1
=
10.0
;
egr
::
EagerTensor
out1
=
egr
::
scale
(
out0
,
scale1
,
bias1
,
true
/*bias_after_scale*/
,
true
/*trace_backward*/
);
// Run Forward Node 2
float
scale2
=
10.0
;
float
bias2
=
20.0
;
egr
::
EagerTensor
out2
=
egr
::
scale
(
out0
,
scale2
,
bias2
,
true
/*bias_after_scale*/
,
true
/*trace_backward*/
);
// Examine Forward Output 0
CompareTensorWithValue
<
float
>
(
out0
,
13.0
);
// Examine Forward Output 1
CompareTensorWithValue
<
float
>
(
out1
,
75.0
);
// Examine Forward Output 2
CompareTensorWithValue
<
float
>
(
out2
,
150.0
);
// Examine GradNode
{
// 1. GradNode
// Node 0
AutogradMeta
*
meta0
=
EagerUtils
::
autograd_meta
(
&
out0
);
GradNodeBase
*
grad_node0
=
meta0
->
GradNode
();
GradNodeScale
*
scale_node0
=
dynamic_cast
<
GradNodeScale
*>
(
grad_node0
);
CHECK_NOTNULL
(
scale_node0
);
CHECK_EQ
(
static_cast
<
int
>
(
meta0
->
OutRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
meta0
->
OutRankInfo
().
second
),
0
);
// Node 1
AutogradMeta
*
meta1
=
EagerUtils
::
autograd_meta
(
&
out1
);
GradNodeBase
*
grad_node1
=
meta1
->
GradNode
();
GradNodeScale
*
scale_node1
=
dynamic_cast
<
GradNodeScale
*>
(
grad_node1
);
CHECK_NOTNULL
(
scale_node1
);
CHECK_EQ
(
static_cast
<
int
>
(
meta1
->
OutRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
meta1
->
OutRankInfo
().
second
),
0
);
// Node 2
AutogradMeta
*
meta2
=
EagerUtils
::
autograd_meta
(
&
out2
);
GradNodeBase
*
grad_node2
=
meta2
->
GradNode
();
GradNodeScale
*
scale_node2
=
dynamic_cast
<
GradNodeScale
*>
(
grad_node2
);
CHECK_NOTNULL
(
scale_node2
);
CHECK_EQ
(
static_cast
<
int
>
(
meta2
->
OutRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
meta2
->
OutRankInfo
().
second
),
0
);
// 2. TensorWrapper: No TensorWrapper for ScaleNode
// 3. NextEdges
// Node 1 -> Node 0
const
std
::
vector
<
std
::
vector
<
Edge
>>&
node1_edges
=
grad_node1
->
GetEdges
();
const
Edge
&
node1_edge
=
node1_edges
[
0
][
0
];
CHECK_EQ
(
static_cast
<
int
>
(
node1_edge
.
GetEdgeRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
node1_edge
.
GetEdgeRankInfo
().
second
),
0
);
CHECK_EQ
(
node1_edge
.
GetGradNode
(),
grad_node0
);
// Node 2 -> Node 0
const
std
::
vector
<
std
::
vector
<
Edge
>>&
node2_edges
=
grad_node2
->
GetEdges
();
const
Edge
&
node2_edge
=
node2_edges
[
0
][
0
];
CHECK_EQ
(
static_cast
<
int
>
(
node2_edge
.
GetEdgeRankInfo
().
first
),
0
);
CHECK_EQ
(
static_cast
<
int
>
(
node2_edge
.
GetEdgeRankInfo
().
second
),
0
);
CHECK_EQ
(
node2_edge
.
GetGradNode
(),
grad_node0
);
}
}
}
// namespace eager_test
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录