|
|
|
@ -65,9 +65,23 @@ std::string LoDToString(const LoD &lod) {
|
|
|
|
|
|
|
|
|
|
LoD SliceInLevel(const LoD &in, size_t level, size_t elem_begin,
|
|
|
|
|
size_t elem_end) {
|
|
|
|
|
PADDLE_ENFORCE_LT(level, in.size());
|
|
|
|
|
PADDLE_ENFORCE_LT(elem_begin, elem_end);
|
|
|
|
|
PADDLE_ENFORCE_LT(elem_end, in[level].size());
|
|
|
|
|
PADDLE_ENFORCE_LT(level, in.size(),
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"The input LoDTensor's lod level should be less than "
|
|
|
|
|
"the LoD size, but received level is %d, LoD is %s.",
|
|
|
|
|
level, in));
|
|
|
|
|
PADDLE_ENFORCE_LT(
|
|
|
|
|
elem_begin, elem_end,
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"The index to start slicing should be less than the index to end "
|
|
|
|
|
"slicing, but received start index is %d, end index is %d.",
|
|
|
|
|
elem_begin, elem_end));
|
|
|
|
|
PADDLE_ENFORCE_LT(
|
|
|
|
|
elem_end, in[level].size(),
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"The index to end slicing should be less than the input LoD size, "
|
|
|
|
|
"but received end index is %d, LoD size is %d.",
|
|
|
|
|
elem_end, in[level].size()));
|
|
|
|
|
|
|
|
|
|
LoD res;
|
|
|
|
|
res.resize(in.size() - level);
|
|
|
|
@ -185,8 +199,17 @@ LoDAndOffset GetSubLoDAndAbsoluteOffset(const LoD &lod, size_t start_idx,
|
|
|
|
|
LoD sub_lod;
|
|
|
|
|
|
|
|
|
|
for (size_t level_idx = start_level; level_idx < lod.size(); ++level_idx) {
|
|
|
|
|
PADDLE_ENFORCE_LE(start_idx, end_idx);
|
|
|
|
|
PADDLE_ENFORCE_LT(end_idx, lod[level_idx].size());
|
|
|
|
|
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]);
|
|
|
|
@ -202,7 +225,10 @@ LoDAndOffset GetSubLoDAndAbsoluteOffset(const LoD &lod, size_t start_idx,
|
|
|
|
|
void AppendLoD(LoD *lod, const LoD &lod_length) {
|
|
|
|
|
PADDLE_ENFORCE(
|
|
|
|
|
lod->empty() || lod->size() == lod_length.size(),
|
|
|
|
|
"The lod_length should has the same size with the appended lod.");
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"The input LoD length should be equal to the appended LoD size, but "
|
|
|
|
|
"received input LoD length is %d, actual LoD size is %d.",
|
|
|
|
|
lod_length, lod->size()));
|
|
|
|
|
if (lod->empty()) {
|
|
|
|
|
for (size_t i = 0; i < lod_length.size(); ++i) {
|
|
|
|
|
lod->emplace_back(1, 0); // size = 1, value = 0;
|
|
|
|
@ -254,11 +280,11 @@ void DeserializeFromStream(std::istream &is, LoDTensor *tensor,
|
|
|
|
|
is.read(reinterpret_cast<char *>(&version), sizeof(version));
|
|
|
|
|
PADDLE_ENFORCE_EQ(framework::IsTensorVersionSupported(version), true,
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"tensor version %u is not supported.", version));
|
|
|
|
|
"Tensor version %u is not supported.", version));
|
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
|
version, 0U,
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"tensor version %u is not supported, Only version 0 is supported",
|
|
|
|
|
"Tensor version %u is not supported, only version 0 is supported.",
|
|
|
|
|
version));
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
@ -280,11 +306,11 @@ void DeserializeFromStream(std::istream &is, LoDTensor *tensor,
|
|
|
|
|
is.read(reinterpret_cast<char *>(&version), sizeof(version));
|
|
|
|
|
PADDLE_ENFORCE_EQ(framework::IsTensorVersionSupported(version), true,
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"tensor version %u is not supported.", version));
|
|
|
|
|
"Tensor version %u is not supported.", version));
|
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
|
version, 0U,
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"tensor version %u is not supported, Only version 0 is supported",
|
|
|
|
|
"Tensor version %u is not supported, only version 0 is supported.",
|
|
|
|
|
version));
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
@ -310,7 +336,7 @@ 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"));
|
|
|
|
|
"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;
|
|
|
|
@ -342,7 +368,9 @@ std::vector<LoDTensor> LoDTensor::SplitLoDTensor(
|
|
|
|
|
auto end = std::min<size_t>((i + 1) * step_width, batch_size);
|
|
|
|
|
PADDLE_ENFORCE_LT(begin, end,
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"begin must be less than end, this may be a bug"));
|
|
|
|
|
"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()) {
|
|
|
|
@ -376,7 +404,9 @@ std::vector<LoDTensor> LoDTensor::SplitLoDTensor(
|
|
|
|
|
void LoDTensor::MergeLoDTensor(
|
|
|
|
|
const std::vector<const LoDTensor *> &lod_tensors,
|
|
|
|
|
platform::Place dst_place) {
|
|
|
|
|
PADDLE_ENFORCE(!lod_tensors.empty());
|
|
|
|
|
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;
|
|
|
|
@ -395,15 +425,35 @@ void LoDTensor::MergeLoDTensor(
|
|
|
|
|
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());
|
|
|
|
|
PADDLE_ENFORCE_EQ(new_layout, t->layout());
|
|
|
|
|
PADDLE_ENFORCE_EQ(framework::product(new_dim) / new_dim[0],
|
|
|
|
|
framework::product(t->dims()) / t->dims()[0]);
|
|
|
|
|
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());
|
|
|
|
|
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();
|
|
|
|
|