Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
638b69dc
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看板
未验证
提交
638b69dc
编写于
6月 20, 2022
作者:
X
xiongkun
提交者:
GitHub
6月 20, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Cherry pick] Einsum memory optimization PR #43397 (#43554)
* cherry pick from #43397 * fix code
上级
68d5c12b
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
70 addition
and
24 deletion
+70
-24
paddle/fluid/eager/nan_inf_utils.cc
paddle/fluid/eager/nan_inf_utils.cc
+1
-0
paddle/fluid/eager/nan_inf_utils.h
paddle/fluid/eager/nan_inf_utils.h
+2
-1
paddle/fluid/operators/einsum_op.cc
paddle/fluid/operators/einsum_op.cc
+15
-4
paddle/phi/infermeta/unary.cc
paddle/phi/infermeta/unary.cc
+8
-1
paddle/phi/infermeta/unary.h
paddle/phi/infermeta/unary.h
+2
-1
paddle/phi/kernels/einsum_kernel.h
paddle/phi/kernels/einsum_kernel.h
+2
-1
paddle/phi/kernels/impl/einsum_grad_impl.h
paddle/phi/kernels/impl/einsum_grad_impl.h
+0
-1
paddle/phi/kernels/impl/einsum_impl.h
paddle/phi/kernels/impl/einsum_impl.h
+9
-3
paddle/phi/ops/compat/einsum_sig.cc
paddle/phi/ops/compat/einsum_sig.cc
+1
-1
python/paddle/fluid/tests/unittests/test_einsum_op.py
python/paddle/fluid/tests/unittests/test_einsum_op.py
+4
-3
python/paddle/tensor/einsum.py
python/paddle/tensor/einsum.py
+9
-3
python/paddle/utils/code_gen/api.yaml
python/paddle/utils/code_gen/api.yaml
+1
-1
python/paddle/utils/code_gen/backward.yaml
python/paddle/utils/code_gen/backward.yaml
+16
-4
未找到文件。
paddle/fluid/eager/nan_inf_utils.cc
浏览文件 @
638b69dc
...
...
@@ -114,6 +114,7 @@ void CheckTensorHasNanOrInf(const std::string& api_name,
const
TupleOfTensorAndVector
&
tensors
)
{
CheckTensorHasNanOrInf
(
api_name
,
std
::
get
<
0
>
(
tensors
));
CheckTensorHasNanOrInf
(
api_name
,
std
::
get
<
1
>
(
tensors
));
CheckTensorHasNanOrInf
(
api_name
,
std
::
get
<
2
>
(
tensors
));
}
}
// namespace egr
paddle/fluid/eager/nan_inf_utils.h
浏览文件 @
638b69dc
...
...
@@ -31,7 +31,8 @@ using TupleOfFourTensors = std::tuple<Tensor, Tensor, Tensor, Tensor>;
using
TupleOfFiveTensors
=
std
::
tuple
<
Tensor
,
Tensor
,
Tensor
,
Tensor
,
Tensor
>
;
using
TupleOfSixTensors
=
std
::
tuple
<
Tensor
,
Tensor
,
Tensor
,
Tensor
,
Tensor
,
Tensor
>
;
using
TupleOfTensorAndVector
=
std
::
tuple
<
Tensor
,
std
::
vector
<
Tensor
>>
;
using
TupleOfTensorAndVector
=
std
::
tuple
<
Tensor
,
std
::
vector
<
Tensor
>
,
std
::
vector
<
Tensor
>>
;
void
CheckTensorHasNanOrInf
(
const
std
::
string
&
api_name
,
const
Tensor
&
tensor
);
...
...
paddle/fluid/operators/einsum_op.cc
浏览文件 @
638b69dc
...
...
@@ -40,6 +40,10 @@ class EinsumOpMaker : public framework::OpProtoAndCheckerMaker {
.
AsExtra
()
.
AsIntermediate
();
AddOutput
(
"XShape"
,
"(Tensor), The cache of the x_shape of: A and B."
)
.
AsDuplicable
()
.
AsExtra
()
.
AsIntermediate
();
AddAttr
<
std
::
string
>
(
"equation"
,
"(string) A einsum equation. such as `ij,jk->ik`"
"There must have `->` and the number of operands in "
...
...
@@ -58,8 +62,8 @@ class EinsumGradOp : public framework::OperatorWithKernel {
void
InferShape
(
framework
::
InferShapeContext
*
ctx
)
const
override
{
auto
x_name
=
"Operands"
;
auto
x_grad_name
=
framework
::
GradVarName
(
x_name
);
ctx
->
SetOutputsDim
(
x_grad_name
,
ctx
->
GetInputsDim
(
x_name
));
ctx
->
ShareAllLoD
(
x_name
,
x_grad_name
);
ctx
->
SetOutputsDim
(
x_grad_name
,
ctx
->
GetInputsDim
(
"Operands"
));
ctx
->
ShareAllLoD
(
"Operands"
,
x_grad_name
);
}
protected:
...
...
@@ -78,8 +82,15 @@ class EinsumGradMaker : public framework::SingleGradOpMaker<T> {
void
Apply
(
GradOpPtr
<
T
>
retv
)
const
override
{
retv
->
SetType
(
"einsum_grad"
);
retv
->
SetInput
(
"Operands"
,
this
->
Input
(
"Operands"
));
retv
->
SetInput
(
"InnerCache"
,
this
->
Output
(
"InnerCache"
));
if
(
this
->
HasOutput
(
"InnerCache"
))
{
retv
->
SetInput
(
"InnerCache"
,
this
->
Output
(
"InnerCache"
));
}
if
(
this
->
HasOutput
(
"XShape"
))
{
// add if for compatibility.
retv
->
SetInput
(
"Operands"
,
this
->
Output
(
"XShape"
));
// for memory save.
}
else
{
retv
->
SetInput
(
"Operands"
,
this
->
Input
(
"Operands"
));
}
retv
->
SetInput
(
framework
::
GradVarName
(
"Out"
),
this
->
OutputGrad
(
"Out"
));
retv
->
SetAttrMap
(
this
->
Attrs
());
retv
->
SetOutput
(
framework
::
GradVarName
(
"Operands"
),
...
...
paddle/phi/infermeta/unary.cc
浏览文件 @
638b69dc
...
...
@@ -402,7 +402,8 @@ void EighInferMeta(const MetaTensor& x,
void
EinsumInferMeta
(
const
std
::
vector
<
const
MetaTensor
*>&
inputs
,
const
std
::
string
&
equation
,
MetaTensor
*
out
,
std
::
vector
<
MetaTensor
*>
inner_cache
)
{
std
::
vector
<
MetaTensor
*>
inner_cache
,
std
::
vector
<
MetaTensor
*>
xshape
)
{
// collect the following informations to prepare einsum.
LabelMap
labelshape
(
0
);
LabelMap
labeltype
(
LabelType
::
Reduction
);
...
...
@@ -439,6 +440,12 @@ void EinsumInferMeta(const std::vector<const MetaTensor*>& inputs,
VLOG
(
3
)
<<
"Label Shape is : "
<<
label_to_string
(
all_labels
,
labelshape
);
out
->
set_dims
(
make_ddim
(
output_dims
));
out
->
set_dtype
(
inputs
[
0
]
->
dtype
());
for
(
size_t
i
=
0
;
i
<
xshape
.
size
();
++
i
)
{
if
(
xshape
[
i
]
!=
nullptr
)
{
xshape
[
i
]
->
set_dims
(
inputs
[
i
]
->
dims
());
xshape
[
i
]
->
set_dtype
(
inputs
[
i
]
->
dtype
());
}
}
}
void
ExpandInferMeta
(
const
MetaTensor
&
x
,
...
...
paddle/phi/infermeta/unary.h
浏览文件 @
638b69dc
...
...
@@ -83,7 +83,8 @@ void EighInferMeta(const MetaTensor& x,
void
EinsumInferMeta
(
const
std
::
vector
<
const
MetaTensor
*>&
inputs
,
const
std
::
string
&
equation
,
MetaTensor
*
out
,
std
::
vector
<
MetaTensor
*>
inner_cache
);
std
::
vector
<
MetaTensor
*>
inner_cache
,
std
::
vector
<
MetaTensor
*>
xshape
);
void
ExpandInferMeta
(
const
MetaTensor
&
x
,
const
IntArray
&
shape
,
...
...
paddle/phi/kernels/einsum_kernel.h
浏览文件 @
638b69dc
...
...
@@ -29,6 +29,7 @@ void EinsumKernelRaw(const Context& dev_ctx,
const
std
::
vector
<
const
DenseTensor
*>&
inputs
,
const
std
::
string
&
equation
,
DenseTensor
*
out
,
std
::
vector
<
DenseTensor
*>
cache
);
std
::
vector
<
DenseTensor
*>
inner_cache
,
std
::
vector
<
DenseTensor
*>
xshape
);
}
// namespace phi
paddle/phi/kernels/impl/einsum_grad_impl.h
浏览文件 @
638b69dc
...
...
@@ -177,7 +177,6 @@ void EinsumGradKernel(const Context& dev_ctx,
cache
[
0
].
ShareBufferWith
(
*
(
inner_cache
[
0
]));
cache
[
1
].
ShareBufferWith
(
*
(
inner_cache
[
1
]));
}
EinsumKernelImpl
<
T
,
Context
>
(
dev_ctx
,
all_labels
,
operands_for_A
,
...
...
paddle/phi/kernels/impl/einsum_impl.h
浏览文件 @
638b69dc
...
...
@@ -458,7 +458,7 @@ DenseTensor PerformContraction(
}
// reduction
DenseTensor
trans_t
;
if
(
FLAGS_einsum_opt
&&
use_cache
&&
cache
[
operand_idx
]
!=
nullptr
&&
if
(
use_cache
&&
cache
[
operand_idx
]
!=
nullptr
&&
cache
[
operand_idx
]
->
IsInitialized
())
{
trans_t
.
ShareBufferWith
(
*
(
cache
[
operand_idx
]));
VLOG
(
5
)
<<
"Cache Used!"
;
...
...
@@ -467,7 +467,7 @@ DenseTensor PerformContraction(
dev_ctx
,
t
,
perm
,
all_labels
,
ellipsis
,
label2type
);
trans_t
=
PerformTranspose
<
T
,
Context
>
(
dev_ctx
,
reduct_t
,
perm
,
reordered_all_labels
,
ellipsis
,
label2type
);
if
(
FLAGS_einsum_opt
&&
cache
[
operand_idx
]
!=
nullptr
)
if
(
cache
[
operand_idx
]
!=
nullptr
)
cache
[
operand_idx
]
->
ShareBufferWith
(
trans_t
);
}
auto
mul_dims
=
GetShapeByType
<
int
>
(
all_labels
,
...
...
@@ -598,6 +598,11 @@ void EinsumKernelImpl(const Context& dev_ctx,
out
);
// Reshape Procedure
}
else
if
(
inputs
.
size
()
==
1
)
{
if
(
cache
[
0
]
!=
nullptr
)
{
// For compatibility, may be cache is nullptr if
// loading the program from v2.3.0
(
*
cache
[
0
])
=
*
(
inputs
[
0
]);
// ShareBuffer for backward, because backward
// we can only see cached tensor.
}
auto
reduce_A
=
PerformReduction
<
T
,
Context
>
(
dev_ctx
,
*
inputs
[
0
],
label2perms
[
0
],
...
...
@@ -626,7 +631,8 @@ void EinsumKernelRaw(const Context& dev_ctx,
const
std
::
vector
<
const
DenseTensor
*>&
inputs
,
const
std
::
string
&
equation
,
DenseTensor
*
out
,
std
::
vector
<
DenseTensor
*>
cache
)
{
std
::
vector
<
DenseTensor
*>
cache
,
std
::
vector
<
DenseTensor
*>
xshape
)
{
std
::
vector
<
char
>
tmp
;
// for the sake of compatibility, we may load and run v2.3 EinsumOp. Output
// may have nullptr and the cache.size() is not equal to inputs.size(). refer
...
...
paddle/phi/ops/compat/einsum_sig.cc
浏览文件 @
638b69dc
...
...
@@ -18,7 +18,7 @@ namespace phi {
KernelSignature
EinsumOpArgumentMapping
(
const
ArgumentMappingContext
&
ctx
)
{
return
KernelSignature
(
"einsum"
,
{
"Operands"
},
{
"equation"
},
{
"Out"
,
"InnerCache"
});
"einsum"
,
{
"Operands"
},
{
"equation"
},
{
"Out"
,
"InnerCache"
,
"XShape"
});
}
KernelSignature
EinsumGradOpArgumentMapping
(
const
ArgumentMappingContext
&
ctx
)
{
...
...
python/paddle/fluid/tests/unittests/test_einsum_op.py
浏览文件 @
638b69dc
...
...
@@ -37,7 +37,9 @@ class TestEinsumBinary(OpTest):
self
.
outputs
=
{
'Out'
:
out
,
"InnerCache"
:
[(
'cache_'
+
str
(
i
),
np
.
array
([
1.0
]))
for
i
in
range
(
len
(
self
.
operands
))]
for
i
in
range
(
len
(
self
.
operands
))],
"XShape"
:
[(
'xshape_'
+
str
(
i
),
np
.
array
([
1.0
]))
for
i
in
range
(
len
(
self
.
operands
))],
}
def
init_input
(
self
):
...
...
@@ -46,14 +48,13 @@ class TestEinsumBinary(OpTest):
self
.
inputs
.
append
(
np
.
random
.
random
(
s
).
astype
(
t
))
def
set_mandatory
(
self
):
self
.
disable
=
False
self
.
shapes
=
[(
10
,
10
,
20
),
(
20
,
6
)]
self
.
types
=
[
np
.
float64
,
np
.
float64
]
self
.
equation
=
"mij,jk->ki"
def
test_check_output
(
self
):
if
not
self
.
disable
:
self
.
check_output
(
no_check_set
=
[
"InnerCache"
])
self
.
check_output
(
no_check_set
=
[
"InnerCache"
,
"XShape"
])
def
test_grad
(
self
):
if
not
self
.
disable
:
...
...
python/paddle/tensor/einsum.py
浏览文件 @
638b69dc
...
...
@@ -802,9 +802,10 @@ def gen_einsum_op(equation, *operands):
if
_in_legacy_dygraph
():
# dygraph
return
_C_ops
.
einsum
(
operands
,
len
(
operands
),
'equation'
,
equation
)[
0
]
return
_C_ops
.
einsum
(
operands
,
len
(
operands
),
len
(
operands
),
'equation'
,
equation
)[
0
]
# static graph
for
inp
in
operands
:
check_variable_and_dtype
(
inp
,
'dtype'
,
[
'float32'
,
'float64'
],
'einsum'
)
check_type
(
equation
,
'equation'
,
str
,
'einsum'
)
...
...
@@ -816,11 +817,16 @@ def gen_einsum_op(equation, *operands):
helper
.
create_variable_for_type_inference
(
dtype
=
operands
[
0
].
dtype
)
for
i
in
range
(
len
(
operands
))
]
xshape
=
[
helper
.
create_variable_for_type_inference
(
dtype
=
operands
[
0
].
dtype
)
for
i
in
range
(
len
(
operands
))
]
helper
.
append_op
(
type
=
'einsum'
,
inputs
=
{
'Operands'
:
operands
},
outputs
=
{
'Out'
:
out
,
"InnerCache"
:
caches
},
"InnerCache"
:
caches
,
"XShape"
:
xshape
},
attrs
=
attrs
)
return
out
...
...
python/paddle/utils/code_gen/api.yaml
浏览文件 @
638b69dc
...
...
@@ -547,7 +547,7 @@
-
api
:
einsum
args
:
(Tensor[] x, str equation)
output
:
Tensor, Tensor[]{x.size()}
output
:
Tensor, Tensor[]{x.size()}
, Tensor[]{x.size()}
infer_meta
:
func
:
EinsumInferMeta
param
:
[
x
,
equation
]
...
...
python/paddle/utils/code_gen/backward.yaml
浏览文件 @
638b69dc
-
backward_api
:
abs_double_grad
forward
:
abs_grad (Tensor x, Tensor grad_out) -> Tensor(grad_x)
args
:
(Tensor x, Tensor grad_x_grad)
output
:
Tensor(grad_out_grad)
infer_meta
:
func
:
UnchangedInferMeta
param
:
[
x
]
kernel
:
func
:
abs_double_grad
data_transform
:
skip_transform
:
grad_x_grad
-
backward_api
:
abs_grad
forward
:
abs (Tensor x) -> Tensor(out)
args
:
(Tensor x, Tensor out_grad)
...
...
@@ -447,12 +459,12 @@
skip_transform
:
out_w, out_w_grad
-
backward_api
:
einsum_grad
forward
:
einsum (Tensor[] x, str equation) -> Tensor(out), Tensor[](inner_cache)
args
:
(Tensor[] x, Tensor[] inner_cache, Tensor out_grad, str equation)
output
:
Tensor[](x_grad){x.size()}
forward
:
einsum (Tensor[] x, str equation) -> Tensor(out), Tensor[](inner_cache)
, Tensor[](x_shape)
args
:
(Tensor[] x
_shape
, Tensor[] inner_cache, Tensor out_grad, str equation)
output
:
Tensor[](x_grad){x
_shape
.size()}
infer_meta
:
func
:
UnchangedMultiInferMeta
param
:
[
x
]
param
:
[
x
_shape
]
kernel
:
func
:
einsum_grad
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录