Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
Paddle
提交
661dbdbe
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看板
未验证
提交
661dbdbe
编写于
12月 01, 2021
作者:
H
Huihuang Zheng
提交者:
GitHub
12月 01, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Modify ShareTensorWithCinnBuffer by callback to save memory (#37493)
Modify ShareTensorWithCinnBuffer by callback to save memory
上级
8a4460f5
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
78 addition
and
87 deletion
+78
-87
paddle/fluid/framework/paddle2cinn/cinn_compiler.cc
paddle/fluid/framework/paddle2cinn/cinn_compiler.cc
+1
-0
paddle/fluid/operators/cinn_launch_op.cc
paddle/fluid/operators/cinn_launch_op.cc
+48
-34
paddle/fluid/operators/cinn_launch_op.h
paddle/fluid/operators/cinn_launch_op.h
+11
-17
paddle/fluid/operators/cinn_launch_op_test.cc
paddle/fluid/operators/cinn_launch_op_test.cc
+18
-36
未找到文件。
paddle/fluid/framework/paddle2cinn/cinn_compiler.cc
浏览文件 @
661dbdbe
...
...
@@ -209,6 +209,7 @@ std::unique_ptr<CinnCompiledObject> CinnCompiler::CompileGraph(
std
::
make_unique
<
GraphCompiler
>
(
target
,
scope
,
cinn_graph
);
GraphCompiler
::
CompileOptions
options
;
options
.
with_instantiate_variables
=
false
;
options
.
with_buffer_handle_instruction_inserted
=
true
;
auto
compiled_res
=
graph_compiler
->
Build
(
options
,
std
::
move
(
fetch_ids
),
stream
);
auto
compiled_obj
=
std
::
make_unique
<
CinnCompiledObject
>
();
...
...
paddle/fluid/operators/cinn_launch_op.cc
浏览文件 @
661dbdbe
...
...
@@ -13,7 +13,10 @@
// limitations under the License.
#include "paddle/fluid/operators/cinn_launch_op.h"
#include <functional>
#include <vector>
#include "paddle/fluid/string/string_helper.h"
DECLARE_bool
(
cudnn_deterministic
);
...
...
@@ -108,33 +111,9 @@ std::unordered_set<std::string> CinnLaunchContext::GetInternalVariableNames() {
return
all_parameters
;
}
void
CinnLaunchContext
::
MutableTensorData
(
const
std
::
string
&
var_name
,
const
platform
::
Place
&
place
,
LoDTensor
*
paddle_tensor
,
bool
is_internal_var
)
{
auto
cinn_name
=
var_name
;
if
(
!
is_internal_var
)
{
PADDLE_ENFORCE_EQ
(
IsVariableUsed
(
var_name
),
true
,
platform
::
errors
::
InvalidArgument
(
"Paddle variable(%s) not used by cinn"
,
var_name
));
cinn_name
=
paddle2cinn_varmap_
.
at
(
var_name
);
}
auto
cinn_tensor
=
GetCinnTensor
(
cinn_name
);
// TODO(CtfGo): support mutable corresponding c++ type after CINN ready
VLOG
(
4
)
<<
"Only support float in cinn_launch op now."
;
paddle_tensor
->
mutable_data
<
float
>
(
framework
::
make_ddim
(
cinn_tensor
->
shape
().
data
()),
place
);
}
void
CinnLaunchContext
::
CheckTensorEquivalent
(
const
std
::
string
&
paddle_name
,
const
LoDTensor
&
paddle_tensor
,
const
CinnTensor
&
cinn_tensor
)
{
PADDLE_ENFORCE_EQ
(
paddle_tensor
.
IsInitialized
(),
true
,
platform
::
errors
::
InvalidArgument
(
"Tensor in variable(%s) is not initialized."
,
paddle_name
));
// check dimension
auto
cinn_dims
=
framework
::
make_ddim
(
cinn_tensor
->
shape
().
data
());
PADDLE_ENFORCE_EQ
(
paddle_tensor
.
dims
(),
cinn_dims
,
...
...
@@ -147,27 +126,39 @@ void CinnLaunchContext::CheckTensorEquivalent(const std::string& paddle_name,
}
void
CinnLaunchContext
::
AssignExternalVariable
(
const
std
::
string
&
paddle_name
,
const
platform
::
Place
&
place
,
LoDTensor
*
paddle_tensor
)
{
PADDLE_ENFORCE_EQ
(
IsVariableUsed
(
paddle_name
),
true
,
platform
::
errors
::
InvalidArgument
(
"Paddle variable(%s) not used by cinn"
,
paddle_name
));
const
auto
&
cinn_name
=
paddle2cinn_varmap_
.
at
(
paddle_name
);
CheckTensorEquivalent
(
paddle_name
,
*
paddle_tensor
,
GetCinnTensor
(
cinn_name
));
return
SetArgument
(
cinn_name
,
paddle_tensor
);
CinnTensor
cinn_tensor
=
GetCinnTensor
(
cinn_name
);
if
(
!
paddle_tensor
->
IsInitialized
())
{
paddle_tensor
->
Resize
(
framework
::
make_ddim
(
cinn_tensor
->
shape
().
data
()));
}
CheckTensorEquivalent
(
paddle_name
,
*
paddle_tensor
,
cinn_tensor
);
return
SetArgument
(
cinn_name
,
place
,
/* free_mem_callback = */
false
,
paddle_tensor
);
}
void
CinnLaunchContext
::
AssignInternalVariable
(
const
std
::
string
&
cinn_name
,
const
platform
::
Place
&
place
,
LoDTensor
*
paddle_tensor
)
{
PADDLE_ENFORCE_GT
(
cinn_variable_names_
.
count
(
cinn_name
),
0
,
platform
::
errors
::
InvalidArgument
(
"Variable(%s) not found in cinn socpe."
,
cinn_name
));
CheckTensorEquivalent
(
cinn_name
,
*
paddle_tensor
,
GetCinnTensor
(
cinn_name
));
return
SetArgument
(
cinn_name
,
paddle_tensor
);
CinnTensor
cinn_tensor
=
GetCinnTensor
(
cinn_name
);
if
(
!
paddle_tensor
->
IsInitialized
())
{
paddle_tensor
->
Resize
(
framework
::
make_ddim
(
cinn_tensor
->
shape
().
data
()));
}
CheckTensorEquivalent
(
cinn_name
,
*
paddle_tensor
,
cinn_tensor
);
return
SetArgument
(
cinn_name
,
place
,
/* free_mem_callback = */
true
,
paddle_tensor
);
}
std
::
unique_ptr
<
cinn_buffer_t
>
CinnLaunchContext
::
ShareTensorWithCinnBuffer
(
LoDTensor
*
tensor
)
{
const
platform
::
Place
&
place
,
bool
free_mem_callback
,
LoDTensor
*
tensor
)
{
// convert paddle dimensions array to cinn format
std
::
vector
<
cinn_dimension_t
>
cinn_dims
(
tensor
->
dims
().
size
());
for
(
auto
i
=
0
;
i
<
tensor
->
dims
().
size
();
++
i
)
{
...
...
@@ -177,19 +168,42 @@ std::unique_ptr<cinn_buffer_t> CinnLaunchContext::ShareTensorWithCinnBuffer(
auto
cinn_buffer
=
std
::
make_unique
<
cinn_buffer_t
>
();
// assign size and memory
cinn_buffer
->
resize
(
cinn_dims
.
data
(),
cinn_dims
.
size
());
cinn_buffer
->
memory
=
reinterpret_cast
<
uint8_t
*>
(
tensor
->
data
<
float
>
());
cinn_buffer
->
external_malloc
=
new
std
::
function
<
int
(
void
*
,
cinn_buffer_t
*
)
>
(
[
place
,
tensor
](
void
*
ctx
,
cinn_buffer_t
*
buffer
)
{
buffer
->
memory
=
reinterpret_cast
<
uint8_t
*>
(
tensor
->
mutable_data
<
float
>
(
place
));
return
0
;
});
if
(
free_mem_callback
)
{
cinn_buffer
->
external_free
=
new
std
::
function
<
int
(
void
*
,
cinn_buffer_t
*
)
>
(
[
tensor
](
void
*
ctx
,
cinn_buffer_t
*
buffer
)
{
tensor
->
clear
();
return
0
;
});
return
cinn_buffer
;
}
cinn_buffer
->
external_free
=
new
std
::
function
<
int
(
void
*
,
cinn_buffer_t
*
)
>
(
[](
void
*
ctx
,
cinn_buffer_t
*
buffer
)
{
// Do nothing
return
0
;
});
return
cinn_buffer
;
}
void
CinnLaunchContext
::
SetArgument
(
const
std
::
string
&
cinn_name
,
const
platform
::
Place
&
place
,
bool
free_mem_callback
,
LoDTensor
*
paddle_tensor
)
{
auto
buffer
=
ShareTensorWithCinnBuffer
(
paddle_tensor
);
auto
buffer
=
ShareTensorWithCinnBuffer
(
place
,
free_mem_callback
,
paddle_tensor
);
name2argument_
.
emplace
(
cinn_name
,
buffer
.
get
());
hold_buffers_
.
emplace_back
(
std
::
move
(
buffer
));
VLOG
(
4
)
<<
"SetArgument-"
<<
name2argument_
.
size
()
<<
": "
<<
"name("
<<
cinn_name
<<
"), "
<<
"type("
<<
framework
::
DataTypeToString
(
paddle_tensor
->
type
())
<<
"), dims("
<<
paddle_tensor
->
dims
()
<<
")."
;
<<
"name("
<<
cinn_name
<<
"), dims("
<<
paddle_tensor
->
dims
()
<<
")."
;
}
const
std
::
map
<
std
::
string
,
cinn_pod_value_t
>&
...
...
paddle/fluid/operators/cinn_launch_op.h
浏览文件 @
661dbdbe
...
...
@@ -49,16 +49,13 @@ class CinnLaunchContext {
// Return whether a Paddle variable used on compiled kernels
bool
IsVariableUsed
(
const
std
::
string
&
var_name
);
// Allocate buffer to a Paddle tensor with assginment information from CINN
void
MutableTensorData
(
const
std
::
string
&
var_name
,
const
platform
::
Place
&
place
,
LoDTensor
*
paddle_tensor
,
bool
is_internal_var
=
false
);
// Assign tensor buffer to input or output variables
void
AssignExternalVariable
(
const
std
::
string
&
var_name
,
LoDTensor
*
tensor
);
void
AssignExternalVariable
(
const
std
::
string
&
var_name
,
const
platform
::
Place
&
place
,
LoDTensor
*
tensor
);
// Assign tensor buffer to internal variables
void
AssignInternalVariable
(
const
std
::
string
&
var_name
,
LoDTensor
*
tensor
);
void
AssignInternalVariable
(
const
std
::
string
&
var_name
,
const
platform
::
Place
&
place
,
LoDTensor
*
tensor
);
// Extract internal variable names from CinnScope
// by excluding used input and output variables
...
...
@@ -83,10 +80,12 @@ class CinnLaunchContext {
// Share the buffer of a Paddle tensor to CINN by delivering memory address
// to a cinn_buffer_t object
std
::
unique_ptr
<
cinn_buffer_t
>
ShareTensorWithCinnBuffer
(
LoDTensor
*
tensor
);
std
::
unique_ptr
<
cinn_buffer_t
>
ShareTensorWithCinnBuffer
(
const
platform
::
Place
&
place
,
bool
free_mem_callback
,
LoDTensor
*
tensor
);
// Set an argument with (cinn name)->(paddle tensor) pair
void
SetArgument
(
const
std
::
string
&
cinn_name
,
LoDTensor
*
paddle_tensor
);
void
SetArgument
(
const
std
::
string
&
cinn_name
,
const
platform
::
Place
&
place
,
bool
free_mem_callback
,
LoDTensor
*
paddle_tensor
);
private:
// a variable name map from paddle to cinn
...
...
@@ -198,7 +197,7 @@ class CinnLaunchOpKernel : public framework::OpKernel<T> {
}
launch_context
->
AssignExternalVariable
(
var_name
,
scope
.
GetVar
(
var_name
)
->
GetMutable
<
LoDTensor
>
());
var_name
,
place
,
scope
.
GetVar
(
var_name
)
->
GetMutable
<
LoDTensor
>
());
}
// 3.2 Prepare output variables: all output variables should
...
...
@@ -215,11 +214,7 @@ class CinnLaunchOpKernel : public framework::OpKernel<T> {
"Output variable(%s) not used by cinn"
,
var_name
));
auto
*
tensor
=
scope
.
GetVar
(
var_name
)
->
GetMutable
<
LoDTensor
>
();
if
(
!
tensor
->
IsInitialized
())
{
launch_context
->
MutableTensorData
(
var_name
,
place
,
tensor
);
}
launch_context
->
AssignExternalVariable
(
var_name
,
scope
.
GetVar
(
var_name
)
->
GetMutable
<
LoDTensor
>
());
launch_context
->
AssignExternalVariable
(
var_name
,
place
,
tensor
);
}
// 3.3 Prepare internal or temporary variables: Create a temporary
...
...
@@ -232,8 +227,7 @@ class CinnLaunchOpKernel : public framework::OpKernel<T> {
framework
::
Scope
*
temp_scope
=
scope
.
NewTmpScope
().
release
();
for
(
const
auto
&
var_name
:
internal_variable_names
)
{
auto
*
tensor
=
temp_scope
->
Var
(
var_name
)
->
GetMutable
<
LoDTensor
>
();
launch_context
->
MutableTensorData
(
var_name
,
place
,
tensor
,
true
);
launch_context
->
AssignInternalVariable
(
var_name
,
tensor
);
launch_context
->
AssignInternalVariable
(
var_name
,
place
,
tensor
);
}
// Step 4. Set CINN runtime FLAGS, such as FLAGS_cinn_cudnn_deterministic.
...
...
paddle/fluid/operators/cinn_launch_op_test.cc
浏览文件 @
661dbdbe
...
...
@@ -222,30 +222,9 @@ TEST(CinnLaunchContextTest, TestGetInternalVariableNames) {
auto
launch_context
=
std
::
make_unique
<
CinnLaunchContext
>
(
GetDefaultCompiledObj
());
auto
internal_variable_names
=
launch_context
->
GetInternalVariableNames
();
ASSERT_EQ
(
internal_variable_names
.
size
(),
1
);
EXPECT_EQ
(
*
internal_variable_names
.
begin
(),
"cinn_var2"
);
}
TEST
(
CinnLaunchContextTest
,
TestMutableTensorData
)
{
platform
::
CPUPlace
place
;
framework
::
Scope
scope
;
auto
*
tensor1
=
scope
.
Var
(
"var1"
)
->
GetMutable
<
LoDTensor
>
();
auto
*
tensor2
=
scope
.
Var
(
"var2"
)
->
GetMutable
<
LoDTensor
>
();
auto
launch_context
=
std
::
make_unique
<
CinnLaunchContext
>
(
GetDefaultCompiledObj
());
// mutable_data on external variable
ASSERT_NO_THROW
(
launch_context
->
MutableTensorData
(
"var1"
,
place
,
tensor1
));
ASSERT_TRUE
(
tensor1
->
IsInitialized
());
ASSERT_EQ
(
tensor1
->
dims
(),
framework
::
make_ddim
({
3
,
4
}));
ASSERT_THROW
(
launch_context
->
MutableTensorData
(
"not_exist"
,
place
,
tensor1
),
paddle
::
platform
::
EnforceNotMet
);
// mutable_data on internal variable
ASSERT_NO_THROW
(
launch_context
->
MutableTensorData
(
"cinn_var2"
,
place
,
tensor2
,
true
));
ASSERT_TRUE
(
tensor2
->
IsInitialized
());
ASSERT_EQ
(
tensor2
->
dims
(),
framework
::
make_ddim
({
6
,
7
,
8
}));
ASSERT_EQ
(
internal_variable_names
.
size
(),
3
);
EXPECT_NE
(
internal_variable_names
.
find
(
"cinn_var2"
),
internal_variable_names
.
end
());
}
TEST
(
CinnLaunchContextTest
,
TestCheckTensorEquivalent
)
{
...
...
@@ -255,12 +234,9 @@ TEST(CinnLaunchContextTest, TestCheckTensorEquivalent) {
framework
::
Scope
scope
;
auto
*
tensor1
=
scope
.
Var
(
"var1"
)
->
GetMutable
<
LoDTensor
>
();
// CheckTensorEquivalent: tensor is not initialized
ASSERT_THROW
(
launch_context
->
AssignExternalVariable
(
"var1"
,
tensor1
),
paddle
::
platform
::
EnforceNotMet
);
// CheckTensorEquivalent: tensor dimension not equivalent
tensor1
->
mutable_data
<
float
>
(
framework
::
make_ddim
({
3
,
5
}),
place
);
ASSERT_THROW
(
launch_context
->
AssignExternalVariable
(
"var1"
,
tensor1
),
ASSERT_THROW
(
launch_context
->
AssignExternalVariable
(
"var1"
,
place
,
tensor1
),
paddle
::
platform
::
EnforceNotMet
);
}
...
...
@@ -272,11 +248,12 @@ TEST(CinnLaunchContextTest, TestAssignVariablePreCondition) {
auto
*
tensor4
=
scope
.
Var
(
"var4"
)
->
GetMutable
<
LoDTensor
>
();
// not used
ASSERT_THROW
(
launch_context
->
AssignExternalVariable
(
"var4"
,
tensor4
),
ASSERT_THROW
(
launch_context
->
AssignExternalVariable
(
"var4"
,
place
,
tensor4
),
paddle
::
platform
::
EnforceNotMet
);
// not found
ASSERT_THROW
(
launch_context
->
AssignExternalVariable
(
"cinn_var4"
,
tensor4
),
paddle
::
platform
::
EnforceNotMet
);
ASSERT_THROW
(
launch_context
->
AssignExternalVariable
(
"cinn_var4"
,
place
,
tensor4
),
paddle
::
platform
::
EnforceNotMet
);
}
TEST
(
CinnLaunchContextTest
,
TestSetArgument
)
{
...
...
@@ -286,22 +263,25 @@ TEST(CinnLaunchContextTest, TestSetArgument) {
platform
::
CPUPlace
place
;
framework
::
Scope
scope
;
auto
*
tensor1
=
scope
.
Var
(
"var1"
)
->
GetMutable
<
LoDTensor
>
();
tensor1
->
mutable_data
<
float
>
(
framework
::
make_ddim
({
3
,
4
}),
place
);
auto
*
data1
=
tensor1
->
data
<
float
>
(
);
float
*
data1
=
tensor1
->
mutable_data
<
float
>
(
framework
::
make_ddim
({
3
,
4
}),
place
);
data1
[
0
]
=
9.99
f
;
data1
[
10
]
=
19.99
f
;
// assign external variable
ASSERT_NO_THROW
(
launch_context
->
AssignExternalVariable
(
"var1"
,
tensor1
));
ASSERT_NO_THROW
(
launch_context
->
AssignExternalVariable
(
"var1"
,
place
,
tensor1
));
auto
*
tensor2
=
scope
.
Var
(
"var2"
)
->
GetMutable
<
LoDTensor
>
();
tensor2
->
mutable_data
<
float
>
(
framework
::
make_ddim
({
6
,
7
,
8
}),
place
);
ASSERT_NO_THROW
(
launch_context
->
AssignInternalVariable
(
"cinn_var2"
,
tensor2
));
ASSERT_NO_THROW
(
launch_context
->
AssignInternalVariable
(
"cinn_var2"
,
place
,
tensor2
));
// FinalizeArguments not missed check
ASSERT_THROW
(
launch_context
->
FinalizeArguments
(),
paddle
::
platform
::
EnforceNotMet
);
auto
*
tensor3
=
scope
.
Var
(
"var3"
)
->
GetMutable
<
LoDTensor
>
();
tensor3
->
mutable_data
<
float
>
(
framework
::
make_ddim
({
10
,
16
}),
place
);
ASSERT_NO_THROW
(
launch_context
->
AssignExternalVariable
(
"var3"
,
tensor3
));
ASSERT_NO_THROW
(
launch_context
->
AssignExternalVariable
(
"var3"
,
place
,
tensor3
));
auto
name2argument
=
launch_context
->
FinalizeArguments
();
ASSERT_EQ
(
name2argument
.
size
(),
3
);
...
...
@@ -310,6 +290,8 @@ TEST(CinnLaunchContextTest, TestSetArgument) {
auto
*
cinn_buffer
=
static_cast
<
cinn_buffer_t
*>
(
name2argument
.
at
(
"cinn_var1"
));
ASSERT_EQ
(
cinn_buffer
->
memory
,
nullptr
);
cinn_buffer
->
external_malloc
->
operator
()(
nullptr
,
cinn_buffer
);
ASSERT_NE
(
cinn_buffer
->
memory
,
nullptr
);
ASSERT_EQ
(
cinn_buffer
->
num_elements
(),
12
);
auto
*
shadow_data
=
reinterpret_cast
<
float
*>
(
cinn_buffer
->
memory
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录