Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
a99fd15e
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看板
提交
a99fd15e
编写于
12月 14, 2021
作者:
J
jim19930609
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Moved LoDTensor methods/members to Tensor
上级
19a833c8
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
259 addition
and
254 deletion
+259
-254
paddle/fluid/framework/lod_tensor.cc
paddle/fluid/framework/lod_tensor.cc
+3
-178
paddle/fluid/framework/lod_tensor.h
paddle/fluid/framework/lod_tensor.h
+9
-73
paddle/fluid/framework/mixed_vector.h
paddle/fluid/framework/mixed_vector.h
+1
-2
paddle/fluid/framework/tensor.cc
paddle/fluid/framework/tensor.cc
+177
-0
paddle/fluid/framework/tensor.h
paddle/fluid/framework/tensor.h
+69
-1
未找到文件。
paddle/fluid/framework/lod_tensor.cc
浏览文件 @
a99fd15e
...
@@ -151,7 +151,8 @@ bool CheckLoD(const LoD &in, int tensor_height) {
...
@@ -151,7 +151,8 @@ bool CheckLoD(const LoD &in, int tensor_height) {
}
}
// check: the lowest level's last offset should equals `tensor_height` if
// check: the lowest level's last offset should equals `tensor_height` if
// tensor_height>0.
// tensor_height>0.
if
(
tensor_height
>
0
&&
(
size_t
)
tensor_height
!=
in
.
back
().
back
())
if
(
tensor_height
>
0
&&
static_cast
<
size_t
>
(
tensor_height
)
!=
in
.
back
().
back
())
return
false
;
return
false
;
// check: the higher level's last offset should equals the lower level's
// check: the higher level's last offset should equals the lower level's
...
@@ -184,42 +185,13 @@ bool CheckAbsLoD(const LoD &in, int tensor_height) {
...
@@ -184,42 +185,13 @@ bool CheckAbsLoD(const LoD &in, int tensor_height) {
if
(
level
.
front
()
!=
0
)
return
false
;
if
(
level
.
front
()
!=
0
)
return
false
;
if
(
tensor_height
<
0
)
{
if
(
tensor_height
<
0
)
{
tensor_height
=
level
.
back
();
tensor_height
=
level
.
back
();
}
else
if
(
(
size_t
)
tensor_height
!=
level
.
back
())
{
}
else
if
(
static_cast
<
size_t
>
(
tensor_height
)
!=
level
.
back
())
{
return
false
;
return
false
;
}
}
}
}
return
true
;
return
true
;
}
}
using
LoDAndOffset
=
std
::
pair
<
LoD
,
std
::
pair
<
size_t
,
size_t
>>
;
LoDAndOffset
GetSubLoDAndAbsoluteOffset
(
const
LoD
&
lod
,
size_t
start_idx
,
size_t
end_idx
,
size_t
start_level
)
{
LoD
sub_lod
;
for
(
size_t
level_idx
=
start_level
;
level_idx
<
lod
.
size
();
++
level_idx
)
{
PADDLE_ENFORCE_LE
(
start_idx
,
end_idx
,
platform
::
errors
::
InvalidArgument
(
"The start index should be less than the end index, "
"but received start index is %d, end index is %d."
,
start_idx
,
end_idx
));
PADDLE_ENFORCE_LT
(
end_idx
,
lod
[
level_idx
].
size
(),
platform
::
errors
::
InvalidArgument
(
"The end index should be less than the LoD level size, but "
"received end index is %d, LoD level size is %d."
,
end_idx
,
lod
[
level_idx
].
size
()));
std
::
vector
<
size_t
>
level_lens
;
for
(
size_t
i
=
start_idx
;
i
<
end_idx
;
++
i
)
{
level_lens
.
push_back
(
lod
[
level_idx
][
i
+
1
]
-
lod
[
level_idx
][
i
]);
}
sub_lod
.
emplace_back
(
level_lens
);
start_idx
=
lod
[
level_idx
][
start_idx
];
end_idx
=
lod
[
level_idx
][
end_idx
];
}
return
LoDAndOffset
{
sub_lod
,
{
start_idx
,
end_idx
}};
}
void
AppendLoD
(
LoD
*
lod
,
const
LoD
&
lod_length
)
{
void
AppendLoD
(
LoD
*
lod
,
const
LoD
&
lod_length
)
{
PADDLE_ENFORCE
(
PADDLE_ENFORCE
(
lod
->
empty
()
||
lod
->
size
()
==
lod_length
.
size
(),
lod
->
empty
()
||
lod
->
size
()
==
lod_length
.
size
(),
...
@@ -347,153 +319,6 @@ void DeserializeFromStream(std::istream &is, LoDTensor *tensor,
...
@@ -347,153 +319,6 @@ void DeserializeFromStream(std::istream &is, LoDTensor *tensor,
TensorFromStream
(
is
,
static_cast
<
Tensor
*>
(
tensor
),
dev_ctx
);
TensorFromStream
(
is
,
static_cast
<
Tensor
*>
(
tensor
),
dev_ctx
);
}
}
std
::
vector
<
LoDTensor
>
LoDTensor
::
SplitLoDTensor
(
const
std
::
vector
<
platform
::
Place
>
places
)
const
{
PADDLE_ENFORCE_GT
(
places
.
size
(),
0
,
platform
::
errors
::
InvalidArgument
(
"Place number cannot be empty when splitting."
));
check_memory_size
();
size_t
batch_size
=
lod
().
empty
()
?
static_cast
<
size_t
>
(
dims
()[
0
])
:
lod
()[
0
].
size
()
-
1
;
// if batch_size is 0, just return #places.size() copys of empty
// tensors.
if
(
batch_size
==
0
)
{
std
::
vector
<
LoDTensor
>
empty_results
;
empty_results
.
reserve
(
places
.
size
());
for
(
size_t
i
=
0
;
i
<
places
.
size
();
++
i
)
{
LoDTensor
dst
;
dst
.
Resize
(
dims
());
dst
.
mutable_data
(
places
[
i
],
type
());
if
(
!
lod
().
empty
())
{
dst
.
set_lod
(
lod
());
}
empty_results
.
emplace_back
(
std
::
move
(
dst
));
}
return
empty_results
;
}
auto
step_width
=
(
batch_size
+
places
.
size
()
-
1
)
/
places
.
size
();
auto
result_size
=
(
batch_size
+
step_width
-
1
)
/
step_width
;
std
::
vector
<
LoDTensor
>
results
;
results
.
reserve
(
result_size
);
for
(
size_t
i
=
0
;
i
<
result_size
;
++
i
)
{
auto
begin
=
i
*
step_width
;
auto
end
=
std
::
min
<
size_t
>
((
i
+
1
)
*
step_width
,
batch_size
);
PADDLE_ENFORCE_LT
(
begin
,
end
,
platform
::
errors
::
InvalidArgument
(
"The begin index must be less than the end index, "
"but received begin index is %d, end index is %d."
,
begin
,
end
));
LoDTensor
dst
;
if
(
lod
().
empty
())
{
auto
src
=
Slice
(
begin
,
end
);
auto
&
dst_place
=
places
[
i
];
framework
::
TensorCopy
(
src
,
dst_place
,
&
dst
);
}
else
{
auto
lod_and_offset
=
GetSubLoDAndAbsoluteOffset
(
lod
(),
begin
,
end
,
0
);
auto
&
offset
=
lod_and_offset
.
second
;
auto
src
=
Slice
(
offset
.
first
,
offset
.
second
);
auto
&
dst_place
=
places
[
i
];
framework
::
TensorCopy
(
src
,
dst_place
,
&
dst
);
LoD
my_lod
;
for
(
auto
&
l
:
lod_and_offset
.
first
)
{
std
::
vector
<
size_t
>
v
{
0
};
for
(
auto
&
ll
:
l
)
{
v
.
push_back
(
ll
+
v
.
back
());
}
my_lod
.
emplace_back
(
v
);
}
dst
.
set_lod
(
my_lod
);
}
results
.
emplace_back
(
std
::
move
(
dst
));
}
return
results
;
}
void
LoDTensor
::
MergeLoDTensor
(
const
std
::
vector
<
const
LoDTensor
*>
&
lod_tensors
,
platform
::
Place
dst_place
)
{
PADDLE_ENFORCE_EQ
(
lod_tensors
.
empty
(),
false
,
platform
::
errors
::
InvalidArgument
(
"The LoDTensors to be merged are empty."
));
framework
::
DDim
new_dim
=
lod_tensors
[
0
]
->
dims
();
proto
::
VarType
::
Type
new_type
=
proto
::
VarType
::
FP32
;
framework
::
DataLayout
new_layout
=
lod_tensors
[
0
]
->
layout
();
for
(
auto
*
t
:
lod_tensors
)
{
if
(
t
->
numel
()
&&
t
->
IsInitialized
())
{
new_dim
=
t
->
dims
();
new_type
=
t
->
type
();
new_layout
=
t
->
layout
();
break
;
}
}
LoD
new_lod
=
lod_tensors
[
0
]
->
lod
();
for
(
size_t
i
=
1
;
i
<
lod_tensors
.
size
();
++
i
)
{
auto
*
t
=
lod_tensors
[
i
];
if
(
t
->
numel
()
&&
t
->
IsInitialized
())
{
PADDLE_ENFORCE_EQ
(
new_type
,
t
->
type
(),
platform
::
errors
::
InvalidArgument
(
"LoDTensor data type does not match, expected type is %s, actual "
"type is %s."
,
DataTypeToString
(
new_type
),
DataTypeToString
(
t
->
type
())));
PADDLE_ENFORCE_EQ
(
new_layout
,
t
->
layout
(),
platform
::
errors
::
InvalidArgument
(
"LoDTensor layout does not match, expected layout is %s, "
"actual layout is %s."
,
DataLayoutToString
(
new_layout
),
DataLayoutToString
(
t
->
layout
())));
PADDLE_ENFORCE_EQ
(
framework
::
product
(
new_dim
)
/
new_dim
[
0
],
framework
::
product
(
t
->
dims
())
/
t
->
dims
()[
0
],
platform
::
errors
::
InvalidArgument
(
"LoDTensor dimension does not match, all dimensions except the "
"first dimension need to be equal,"
"but expected dimension is %s, actual dimension is %s."
,
new_dim
,
t
->
dims
()));
new_dim
[
0
]
+=
t
->
dims
()[
0
];
}
auto
&
lod
=
t
->
lod
();
PADDLE_ENFORCE_EQ
(
new_lod
.
size
(),
lod
.
size
(),
platform
::
errors
::
InvalidArgument
(
"The LoD information of LoDTensor does not match, "
"expected LoD is %s, actual LoD is %s."
,
new_lod
,
lod
));
for
(
size_t
j
=
0
;
j
<
lod
.
size
();
++
j
)
{
auto
&
sub_lod
=
new_lod
[
j
];
size_t
offset
=
sub_lod
.
back
();
for
(
size_t
k
=
1
;
k
<
lod
[
j
].
size
();
++
k
)
{
sub_lod
.
push_back
(
lod
[
j
][
k
]
+
offset
);
}
}
}
Resize
(
new_dim
);
set_layout
(
new_layout
);
set_lod
(
new_lod
);
mutable_data
(
dst_place
,
new_type
);
int
begin
=
0
;
for
(
auto
*
src
:
lod_tensors
)
{
int
end
=
begin
+
src
->
dims
()[
0
];
if
(
end
==
begin
)
{
continue
;
}
auto
dst
=
Slice
(
begin
,
end
);
framework
::
TensorCopy
(
*
src
,
dst_place
,
&
dst
);
begin
=
end
;
}
}
LoD
ConvertToLengthBasedLoD
(
const
LoD
&
offset_lod
)
{
LoD
ConvertToLengthBasedLoD
(
const
LoD
&
offset_lod
)
{
LoD
length_lod
;
LoD
length_lod
;
length_lod
.
reserve
(
offset_lod
.
size
());
length_lod
.
reserve
(
offset_lod
.
size
());
...
...
paddle/fluid/framework/lod_tensor.h
浏览文件 @
a99fd15e
...
@@ -39,6 +39,8 @@ class DeviceContext;
...
@@ -39,6 +39,8 @@ class DeviceContext;
namespace
paddle
{
namespace
paddle
{
namespace
framework
{
namespace
framework
{
using
LoD
=
std
::
vector
<
Vector
<
size_t
>>
;
/*
/*
* LoD is short for Level of Details.
* LoD is short for Level of Details.
*
*
...
@@ -54,7 +56,6 @@ namespace framework {
...
@@ -54,7 +56,6 @@ namespace framework {
* 0 2 4 7
* 0 2 4 7
* 0 2 5 7 10 12 15 20
* 0 2 5 7 10 12 15 20
*/
*/
using
LoD
=
std
::
vector
<
Vector
<
size_t
>>
;
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoD
&
lod
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoD
&
lod
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoDTensor
&
t
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoDTensor
&
t
);
...
@@ -108,64 +109,14 @@ bool CheckAbsLoD(const LoD& in, int tensor_height = -1);
...
@@ -108,64 +109,14 @@ bool CheckAbsLoD(const LoD& in, int tensor_height = -1);
*/
*/
class
LoDTensor
:
public
Tensor
{
class
LoDTensor
:
public
Tensor
{
public:
public:
LoDTensor
()
:
Tensor
()
{}
explicit
LoDTensor
(
const
LoD
&
lod
)
:
lod_
(
lod
)
{}
void
set_lod
(
const
LoD
&
lod
)
{
lod_
=
lod
;
}
const
LoD
&
lod
()
const
{
return
lod_
;
}
LoD
*
mutable_lod
()
{
return
&
lod_
;
}
/*
* Get the start offset and end offset of an element from LoD.
*/
std
::
pair
<
size_t
,
size_t
>
lod_element
(
size_t
level
,
size_t
elem
)
const
{
PADDLE_ENFORCE_LT
(
level
,
NumLevels
(),
platform
::
errors
::
InvalidArgument
(
"The input level of LoD is invalid, it should be less than LoD "
"size. The input level is %zu, the LoD size is %zu."
,
level
,
NumLevels
()));
PADDLE_ENFORCE_LT
(
elem
,
NumElements
(
level
),
platform
::
errors
::
InvalidArgument
(
"The input element of LoD is invalid, it should be "
"less than the number of elements in its level."
"The input element is %zu, the number of elements in "
"its level is %zu."
,
elem
,
NumElements
(
level
)));
return
std
::
make_pair
((
lod_
)[
level
][
elem
],
(
lod_
)[
level
][
elem
+
1
]);
}
/*
* Number of LoDTensor's levels, each level has units of data, for example,
* in the sentence's view, article, paragraph, sentence are 3 levels.
*/
size_t
NumLevels
()
const
{
return
lod_
.
size
();
}
/*
* Number of elements in a level.
*/
size_t
NumElements
(
size_t
level
=
0
)
const
{
PADDLE_ENFORCE_LT
(
level
,
NumLevels
(),
platform
::
errors
::
InvalidArgument
(
"The input level of LoD is invalid, it should be less than LoD "
"size. The input level is %zu, the LoD size is %zu."
,
level
,
NumLevels
()));
// the last offset is the end of last element
return
(
lod_
)[
level
].
size
()
-
1
;
}
// Split LoDTensor and copy to each place specified in places.
std
::
vector
<
LoDTensor
>
SplitLoDTensor
(
const
std
::
vector
<
platform
::
Place
>
places
)
const
;
void
MergeLoDTensor
(
const
std
::
vector
<
const
LoDTensor
*>&
lod_tensors
,
void
MergeLoDTensor
(
const
std
::
vector
<
const
LoDTensor
*>&
lod_tensors
,
platform
::
Place
place
);
platform
::
Place
place
)
{
std
::
vector
<
const
Tensor
*>
tmp
;
private:
for
(
const
LoDTensor
*
lod_tensor
:
lod_tensors
)
{
LoD
lod_
;
tmp
.
push_back
(
lod_tensor
);
}
Tensor
::
MergeLoDTensor
(
tmp
,
place
);
}
};
};
/*
/*
...
@@ -210,21 +161,6 @@ LoDTensor LodExpand(const LoDTensor& source, const LoD& lod, size_t level,
...
@@ -210,21 +161,6 @@ LoDTensor LodExpand(const LoDTensor& source, const LoD& lod, size_t level,
return
tensor
;
return
tensor
;
}
}
// Get the absolute offset of a lod[start_level][start_idx:end_idx] and
// relative length of details for every levels(i.e., [start_level: ]).
//
// For example,
// lod = [[0, 3, 4, 8], [0, 9, 10, 11, 13, 17, 19, 22, 24]]
// start_level = 0
// start_idx = 1
// end_idx = 3
//
// Returns:
// LoD = [[1, 4], [2, 4, 2, 3, 2]]
// pair<size_t, size_t> = {11, 24}
std
::
pair
<
LoD
,
std
::
pair
<
size_t
,
size_t
>>
GetSubLoDAndAbsoluteOffset
(
const
LoD
&
lod
,
size_t
start_idx
,
size_t
end_idx
,
size_t
start_level
);
void
AppendLoD
(
LoD
*
lod
,
const
LoD
&
lod_length
);
void
AppendLoD
(
LoD
*
lod
,
const
LoD
&
lod_length
);
/*
/*
...
...
paddle/fluid/framework/mixed_vector.h
浏览文件 @
a99fd15e
...
@@ -23,10 +23,9 @@ limitations under the License. */
...
@@ -23,10 +23,9 @@ limitations under the License. */
#include "glog/logging.h"
#include "glog/logging.h"
#include "paddle/fluid/framework/details/cow_ptr.h"
#include "paddle/fluid/framework/details/cow_ptr.h"
#include "paddle/fluid/framework/tensor.h"
#include "paddle/fluid/framework/tensor_util.h"
#include "paddle/fluid/memory/malloc.h"
#include "paddle/fluid/memory/malloc.h"
#include "paddle/fluid/memory/memcpy.h"
#include "paddle/fluid/memory/memcpy.h"
#include "paddle/fluid/platform/device_context.h"
#include "paddle/utils/none.h"
#include "paddle/utils/none.h"
#include "paddle/utils/optional.h"
#include "paddle/utils/optional.h"
...
...
paddle/fluid/framework/tensor.cc
浏览文件 @
a99fd15e
...
@@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
...
@@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. */
limitations under the License. */
#include "paddle/fluid/framework/tensor.h"
#include "paddle/fluid/framework/tensor.h"
#include "paddle/fluid/framework/tensor_util.h"
DECLARE_bool
(
use_stream_safe_cuda_allocator
);
DECLARE_bool
(
use_stream_safe_cuda_allocator
);
...
@@ -235,5 +236,181 @@ void Tensor::ResetHolderWithType(std::shared_ptr<memory::Allocation> holder,
...
@@ -235,5 +236,181 @@ void Tensor::ResetHolderWithType(std::shared_ptr<memory::Allocation> holder,
void
Tensor
::
set_type
(
const
proto
::
VarType
::
Type
&
type
)
{
type_
=
type
;
}
void
Tensor
::
set_type
(
const
proto
::
VarType
::
Type
&
type
)
{
type_
=
type
;
}
/* ---------------------------------------- */
/* -------------- LoDTensor --------------- */
/* ---------------------------------------- */
using
LoDAndOffset
=
std
::
pair
<
LoD
,
std
::
pair
<
size_t
,
size_t
>>
;
LoDAndOffset
GetSubLoDAndAbsoluteOffset
(
const
LoD
&
lod
,
size_t
start_idx
,
size_t
end_idx
,
size_t
start_level
)
{
LoD
sub_lod
;
for
(
size_t
level_idx
=
start_level
;
level_idx
<
lod
.
size
();
++
level_idx
)
{
PADDLE_ENFORCE_LE
(
start_idx
,
end_idx
,
platform
::
errors
::
InvalidArgument
(
"The start index should be less than the end index, "
"but received start index is %d, end index is %d."
,
start_idx
,
end_idx
));
PADDLE_ENFORCE_LT
(
end_idx
,
lod
[
level_idx
].
size
(),
platform
::
errors
::
InvalidArgument
(
"The end index should be less than the LoD level size, but "
"received end index is %d, LoD level size is %d."
,
end_idx
,
lod
[
level_idx
].
size
()));
std
::
vector
<
size_t
>
level_lens
;
for
(
size_t
i
=
start_idx
;
i
<
end_idx
;
++
i
)
{
level_lens
.
push_back
(
lod
[
level_idx
][
i
+
1
]
-
lod
[
level_idx
][
i
]);
}
sub_lod
.
emplace_back
(
level_lens
);
start_idx
=
lod
[
level_idx
][
start_idx
];
end_idx
=
lod
[
level_idx
][
end_idx
];
}
return
LoDAndOffset
{
sub_lod
,
{
start_idx
,
end_idx
}};
}
std
::
vector
<
Tensor
>
Tensor
::
SplitLoDTensor
(
const
std
::
vector
<
platform
::
Place
>
places
)
const
{
PADDLE_ENFORCE_GT
(
places
.
size
(),
0
,
platform
::
errors
::
InvalidArgument
(
"Place number cannot be empty when splitting."
));
check_memory_size
();
size_t
batch_size
=
lod
().
empty
()
?
static_cast
<
size_t
>
(
dims
()[
0
])
:
lod
()[
0
].
size
()
-
1
;
// if batch_size is 0, just return #places.size() copys of empty
// tensors.
if
(
batch_size
==
0
)
{
std
::
vector
<
Tensor
>
empty_results
;
empty_results
.
reserve
(
places
.
size
());
for
(
size_t
i
=
0
;
i
<
places
.
size
();
++
i
)
{
Tensor
dst
;
dst
.
Resize
(
dims
());
dst
.
mutable_data
(
places
[
i
],
type
());
if
(
!
lod
().
empty
())
{
dst
.
set_lod
(
lod
());
}
empty_results
.
emplace_back
(
std
::
move
(
dst
));
}
return
empty_results
;
}
auto
step_width
=
(
batch_size
+
places
.
size
()
-
1
)
/
places
.
size
();
auto
result_size
=
(
batch_size
+
step_width
-
1
)
/
step_width
;
std
::
vector
<
Tensor
>
results
;
results
.
reserve
(
result_size
);
for
(
size_t
i
=
0
;
i
<
result_size
;
++
i
)
{
auto
begin
=
i
*
step_width
;
auto
end
=
std
::
min
<
size_t
>
((
i
+
1
)
*
step_width
,
batch_size
);
PADDLE_ENFORCE_LT
(
begin
,
end
,
platform
::
errors
::
InvalidArgument
(
"The begin index must be less than the end index, "
"but received begin index is %d, end index is %d."
,
begin
,
end
));
Tensor
dst
;
if
(
lod
().
empty
())
{
auto
src
=
Slice
(
begin
,
end
);
auto
&
dst_place
=
places
[
i
];
framework
::
TensorCopy
(
src
,
dst_place
,
&
dst
);
}
else
{
auto
lod_and_offset
=
GetSubLoDAndAbsoluteOffset
(
lod
(),
begin
,
end
,
0
);
auto
&
offset
=
lod_and_offset
.
second
;
auto
src
=
Slice
(
offset
.
first
,
offset
.
second
);
auto
&
dst_place
=
places
[
i
];
framework
::
TensorCopy
(
src
,
dst_place
,
&
dst
);
LoD
my_lod
;
for
(
auto
&
l
:
lod_and_offset
.
first
)
{
std
::
vector
<
size_t
>
v
{
0
};
for
(
auto
&
ll
:
l
)
{
v
.
push_back
(
ll
+
v
.
back
());
}
my_lod
.
emplace_back
(
v
);
}
dst
.
set_lod
(
my_lod
);
}
results
.
emplace_back
(
std
::
move
(
dst
));
}
return
results
;
}
void
Tensor
::
MergeLoDTensor
(
const
std
::
vector
<
const
Tensor
*>&
lod_tensors
,
platform
::
Place
dst_place
)
{
PADDLE_ENFORCE_EQ
(
lod_tensors
.
empty
(),
false
,
platform
::
errors
::
InvalidArgument
(
"The LoDTensors to be merged are empty."
));
framework
::
DDim
new_dim
=
lod_tensors
[
0
]
->
dims
();
proto
::
VarType
::
Type
new_type
=
proto
::
VarType
::
FP32
;
framework
::
DataLayout
new_layout
=
lod_tensors
[
0
]
->
layout
();
for
(
auto
*
t
:
lod_tensors
)
{
if
(
t
->
numel
()
&&
t
->
IsInitialized
())
{
new_dim
=
t
->
dims
();
new_type
=
t
->
type
();
new_layout
=
t
->
layout
();
break
;
}
}
LoD
new_lod
=
lod_tensors
[
0
]
->
lod
();
for
(
size_t
i
=
1
;
i
<
lod_tensors
.
size
();
++
i
)
{
auto
*
t
=
lod_tensors
[
i
];
if
(
t
->
numel
()
&&
t
->
IsInitialized
())
{
PADDLE_ENFORCE_EQ
(
new_type
,
t
->
type
(),
platform
::
errors
::
InvalidArgument
(
"LoDTensor data type does not match, expected type is %s, actual "
"type is %s."
,
DataTypeToString
(
new_type
),
DataTypeToString
(
t
->
type
())));
PADDLE_ENFORCE_EQ
(
new_layout
,
t
->
layout
(),
platform
::
errors
::
InvalidArgument
(
"LoDTensor layout does not match, expected layout is %s, "
"actual layout is %s."
,
DataLayoutToString
(
new_layout
),
DataLayoutToString
(
t
->
layout
())));
PADDLE_ENFORCE_EQ
(
framework
::
product
(
new_dim
)
/
new_dim
[
0
],
framework
::
product
(
t
->
dims
())
/
t
->
dims
()[
0
],
platform
::
errors
::
InvalidArgument
(
"LoDTensor dimension does not match, all dimensions except the "
"first dimension need to be equal,"
"but expected dimension is %s, actual dimension is %s."
,
new_dim
,
t
->
dims
()));
new_dim
[
0
]
+=
t
->
dims
()[
0
];
}
auto
&
lod
=
t
->
lod
();
PADDLE_ENFORCE_EQ
(
new_lod
.
size
(),
lod
.
size
(),
platform
::
errors
::
InvalidArgument
(
"The LoD information of LoDTensor does not match"
));
for
(
size_t
j
=
0
;
j
<
lod
.
size
();
++
j
)
{
auto
&
sub_lod
=
new_lod
[
j
];
size_t
offset
=
sub_lod
.
back
();
for
(
size_t
k
=
1
;
k
<
lod
[
j
].
size
();
++
k
)
{
sub_lod
.
push_back
(
lod
[
j
][
k
]
+
offset
);
}
}
}
Resize
(
new_dim
);
set_layout
(
new_layout
);
set_lod
(
new_lod
);
mutable_data
(
dst_place
,
new_type
);
int
begin
=
0
;
for
(
auto
*
src
:
lod_tensors
)
{
int
end
=
begin
+
src
->
dims
()[
0
];
if
(
end
==
begin
)
{
continue
;
}
auto
dst
=
Slice
(
begin
,
end
);
framework
::
TensorCopy
(
*
src
,
dst_place
,
&
dst
);
begin
=
end
;
}
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle
}
// namespace paddle
paddle/fluid/framework/tensor.h
浏览文件 @
a99fd15e
...
@@ -24,6 +24,7 @@ limitations under the License. */
...
@@ -24,6 +24,7 @@ limitations under the License. */
#include "paddle/fluid/framework/data_layout.h"
#include "paddle/fluid/framework/data_layout.h"
#include "paddle/fluid/framework/ddim.h"
#include "paddle/fluid/framework/ddim.h"
#include "paddle/fluid/framework/framework.pb.h"
#include "paddle/fluid/framework/framework.pb.h"
#include "paddle/fluid/framework/mixed_vector.h"
#include "paddle/fluid/memory/memory.h"
#include "paddle/fluid/memory/memory.h"
#include "paddle/fluid/platform/device_context.h"
#include "paddle/fluid/platform/device_context.h"
#include "paddle/fluid/platform/enforce.h"
#include "paddle/fluid/platform/enforce.h"
...
@@ -41,7 +42,7 @@ namespace paddle {
...
@@ -41,7 +42,7 @@ namespace paddle {
namespace
framework
{
namespace
framework
{
class
LoDTensor
;
using
LoD
=
std
::
vector
<
Vector
<
size_t
>>
;
/*
/*
NOTE(liym27): [ What is TensorInplaceVersion used for? ]
NOTE(liym27): [ What is TensorInplaceVersion used for? ]
...
@@ -326,8 +327,75 @@ class Tensor {
...
@@ -326,8 +327,75 @@ class Tensor {
*/
*/
size_t
offset_
;
size_t
offset_
;
std
::
shared_ptr
<
TensorInplaceVersion
>
inplace_version_counter_
;
std
::
shared_ptr
<
TensorInplaceVersion
>
inplace_version_counter_
;
/* ---------------------------------------------------------- */
/* --------------- Reserved for LoDTensor ------------------- */
/* ---------------------------------------------------------- */
public:
explicit
Tensor
(
const
LoD
&
lod
)
:
lod_
(
lod
)
{}
void
set_lod
(
const
LoD
&
lod
)
{
lod_
=
lod
;
}
const
LoD
&
lod
()
const
{
return
lod_
;
}
LoD
*
mutable_lod
()
{
return
&
lod_
;
}
std
::
pair
<
size_t
,
size_t
>
lod_element
(
size_t
level
,
size_t
elem
)
const
{
PADDLE_ENFORCE_LT
(
level
,
NumLevels
(),
platform
::
errors
::
InvalidArgument
(
"The input level of LoD is invalid, it should be less than LoD "
"size. The input level is %zu, the LoD size is %zu."
,
level
,
NumLevels
()));
PADDLE_ENFORCE_LT
(
elem
,
NumElements
(
level
),
platform
::
errors
::
InvalidArgument
(
"The input element of LoD is invalid, it should be "
"less than the number of elements in its level."
"The input element is %zu, the number of elements in "
"its level is %zu."
,
elem
,
NumElements
(
level
)));
return
std
::
make_pair
((
lod_
)[
level
][
elem
],
(
lod_
)[
level
][
elem
+
1
]);
}
size_t
NumLevels
()
const
{
return
lod_
.
size
();
}
size_t
NumElements
(
size_t
level
=
0
)
const
{
PADDLE_ENFORCE_LT
(
level
,
NumLevels
(),
platform
::
errors
::
InvalidArgument
(
"The input level of LoD is invalid, it should be less than LoD "
"size. The input level is %zu, the LoD size is %zu."
,
level
,
NumLevels
()));
// the last offset is the end of last element
return
(
lod_
)[
level
].
size
()
-
1
;
}
// Split LoDTensor and copy to each place specified in places.
std
::
vector
<
Tensor
>
SplitLoDTensor
(
const
std
::
vector
<
platform
::
Place
>
places
)
const
;
void
MergeLoDTensor
(
const
std
::
vector
<
const
Tensor
*>&
lod_tensors
,
platform
::
Place
place
);
private:
LoD
lod_
;
};
};
// Get the absolute offset of a lod[start_level][start_idx:end_idx] and
// relative length of details for every levels(i.e., [start_level: ]).
//
// For example,
// lod = [[0, 3, 4, 8], [0, 9, 10, 11, 13, 17, 19, 22, 24]]
// start_level = 0
// start_idx = 1
// end_idx = 3
//
// Returns:
// LoD = [[1, 4], [2, 4, 2, 3, 2]]
// pair<size_t, size_t> = {11, 24}
std
::
pair
<
LoD
,
std
::
pair
<
size_t
,
size_t
>>
GetSubLoDAndAbsoluteOffset
(
const
LoD
&
lod
,
size_t
start_idx
,
size_t
end_idx
,
size_t
start_level
);
}
// namespace framework
}
// namespace framework
}
// namespace paddle
}
// namespace paddle
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录