未验证 提交 8c44ad47 编写于 作者: 石晓伟 提交者: GitHub

change the meta modification rules, test=develop (#37255)

上级 ba1e0dd8
...@@ -10,4 +10,5 @@ cc_library(kernel_factory SRCS kernel_factory.cc DEPS enforce) ...@@ -10,4 +10,5 @@ cc_library(kernel_factory SRCS kernel_factory.cc DEPS enforce)
cc_library(kernel_context SRCS kernel_context.cc DEPS enforce device_context) cc_library(kernel_context SRCS kernel_context.cc DEPS enforce device_context)
cc_library(tensor_base SRCS tensor_base.cc allocator.cc storage.cc DEPS enforce) cc_library(tensor_base SRCS tensor_base.cc allocator.cc storage.cc DEPS enforce)
cc_library(dense_tensor SRCS dense_tensor.cc DEPS tensor_base) cc_library(tensor_meta SRCS tensor_meta.cc DEPS enforce)
cc_library(dense_tensor SRCS dense_tensor.cc DEPS tensor_meta tensor_base)
...@@ -49,7 +49,14 @@ class CompatibleDenseTensorUtils { ...@@ -49,7 +49,14 @@ class CompatibleDenseTensorUtils {
static DenseTensor Slice(DenseTensor* tensor, static DenseTensor Slice(DenseTensor* tensor,
int64_t begin_idx, int64_t begin_idx,
int64_t end_idx) { int64_t end_idx) {
tensor->check_memory_size(); size_t bytes = tensor->numel() * SizeOf(tensor->dtype());
PADDLE_ENFORCE_GE(tensor->capacity(),
bytes,
paddle::platform::errors::InvalidArgument(
"The memory size %d should be enough to meet the "
"volume required by metadata %d.",
tensor->capacity(),
bytes));
PADDLE_ENFORCE_GE(begin_idx, PADDLE_ENFORCE_GE(begin_idx,
0, 0,
paddle::platform::errors::OutOfRange( paddle::platform::errors::OutOfRange(
......
...@@ -112,29 +112,18 @@ const void* DenseTensor::data() const { ...@@ -112,29 +112,18 @@ const void* DenseTensor::data() const {
return storage_->data(); return storage_->data();
} }
void DenseTensor::check_memory_size() const { void DenseTensor::set_meta(DenseTensorMeta&& meta) {
size_t bytes = numel() * SizeOf(dtype()); PADDLE_ENFORCE(!meta_.valid(),
PADDLE_ENFORCE_GE(memory_size(), paddle::platform::errors::InvalidArgument(
bytes, "Only when the original attribute of Tensor is "
paddle::platform::errors::InvalidArgument( "incomplete, can it be reset."));
"The memory size %d should be enough to meet the " meta_ = std::move(meta);
"volume required by metadata %d.",
memory_size(),
bytes));
}
void DenseTensor::Resize(const DDim& dims) {
if (product(dims) == product(meta_.dims)) {
set_dims(dims);
} else {
meta_.dims = dims;
storage_->Clear();
}
} }
void DenseTensor::set_dims(const DDim& dims) { void DenseTensor::Resize(const DDim& dims, const LoD& lod) {
CHECK(product(dims) == product(meta_.dims));
meta_.dims = dims; meta_.dims = dims;
meta_.lod = lod;
mutable_data();
} }
#define DATA_MEMBER_FUNC_INSTANTIATION(dtype) \ #define DATA_MEMBER_FUNC_INSTANTIATION(dtype) \
......
...@@ -88,9 +88,6 @@ class DenseTensor : public TensorBase, ...@@ -88,9 +88,6 @@ class DenseTensor : public TensorBase,
return meta_.lod; return meta_.lod;
} }
/// \brief Set the lod of the tensor.
void set_lod(const std::vector<std::vector<size_t>>& lod) { meta_.lod = lod; }
/// \brief Returns the data type of the tensor. /// \brief Returns the data type of the tensor.
/// \return The data type of the tensor. /// \return The data type of the tensor.
DataType dtype() const noexcept override { return meta_.type; } DataType dtype() const noexcept override { return meta_.type; }
...@@ -107,6 +104,11 @@ class DenseTensor : public TensorBase, ...@@ -107,6 +104,11 @@ class DenseTensor : public TensorBase,
/// \return The meta information of the tensor. /// \return The meta information of the tensor.
const DenseTensorMeta& meta() const noexcept { return meta_; } const DenseTensorMeta& meta() const noexcept { return meta_; }
/// \brief Sets the meta information of the tensor. Only when the original
/// attribute of Tensor is incomplete, can it be reset.
/// \param meta The meta information of the tensor.
void set_meta(DenseTensorMeta&& meta);
/// \brief Test whether the metadata is valid. /// \brief Test whether the metadata is valid.
/// \return Whether the metadata is valid. /// \return Whether the metadata is valid.
bool valid() const noexcept override { return meta_.valid(); } bool valid() const noexcept override { return meta_.valid(); }
...@@ -121,25 +123,16 @@ class DenseTensor : public TensorBase, ...@@ -121,25 +123,16 @@ class DenseTensor : public TensorBase,
/// \return Whether the storage is shared with other objects. /// \return Whether the storage is shared with other objects.
bool IsSharedWith(const DenseTensor& b) const; bool IsSharedWith(const DenseTensor& b) const;
/// \brief Change the dims information in the metadata. If the new size is /// \brief Change the shape information in the metadata. If the new size is
/// inconsistent with the original value, the storage area will be released /// larger than the original value, the storage area will be reallocated.
/// to avoid wrong access.
/// \param dims The new dims of the dense tensor. /// \param dims The new dims of the dense tensor.
void Resize(const DDim& dims); /// \param lod The new lod of the dense tensor.
void Resize(const DDim& dims, const LoD& lod = {});
/// \brief Change the dims information in the metadata.
/// \param dims The new dims of the dense tensor. The product of the dims
/// elements must be consistent with the original value.
void set_dims(const DDim& dims);
/// \brief Returns the actual storage size occupied by tensor, may be larger /// \brief Returns the actual storage size occupied by tensor, may be larger
/// than its shape dims. /// than its shape dims.
/// \return The actual storage size occupied by tensor. /// \return The actual storage size occupied by tensor.
size_t memory_size() const { return storage_->size(); } size_t capacity() const { return storage_->size(); }
/// \brief Check that the storage area is large enough to hold the data of the
/// metadata size, and throw an exception if the conditions are not met.
void check_memory_size() const;
/// \brief Release the storage area for other purposes. Because of the /// \brief Release the storage area for other purposes. Because of the
/// destruction of encapsulation, we do not support two dense tensors directly /// destruction of encapsulation, we do not support two dense tensors directly
......
/* 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/pten/core/tensor_meta.h"
namespace pten {
DenseTensorMeta::DenseTensorMeta(DataType type, const DDim& dims)
: dims(dims), type(type) {}
DenseTensorMeta::DenseTensorMeta(DataType type,
const DDim& dims,
DataLayout layout)
: dims(dims), type(type), layout(layout) {}
DenseTensorMeta::DenseTensorMeta(DataType type,
const DDim& dims,
DataLayout layout,
const std::vector<std::vector<size_t>>& lod)
: dims(dims), type(type), layout(layout), lod(lod) {}
bool DenseTensorMeta::valid() const noexcept {
bool valid{true};
valid = valid && (type != DataType::UNDEFINED);
valid = valid && (layout != DataLayout::UNDEFINED);
valid = valid && (is_scalar || product(dims) >= 0);
return valid;
}
bool operator==(const DenseTensorMeta& lhs, const DenseTensorMeta& rhs) {
bool ret = true;
return ret && (lhs.is_scalar == rhs.is_scalar) && (lhs.dims == rhs.dims) &&
(lhs.type == rhs.type) && (lhs.layout == rhs.layout) &&
(lhs.lod == rhs.lod) && (lhs.offset == rhs.offset);
}
} // namespace pten
...@@ -52,42 +52,12 @@ struct DenseTensorMeta { ...@@ -52,42 +52,12 @@ struct DenseTensorMeta {
/// During the entire life cycle of a DenseTensor, the following attributes /// During the entire life cycle of a DenseTensor, the following attributes
/// marked with `const` are expected to remain unchanged. /// marked with `const` are expected to remain unchanged.
const bool is_scalar{false}; bool is_scalar{false};
DDim dims; DDim dims;
const DataType type{DataType::UNDEFINED}; DataType type{DataType::UNDEFINED};
const DataLayout layout{DataLayout::NCHW}; DataLayout layout{DataLayout::NCHW};
LoD lod; LoD lod;
size_t offset{0}; size_t offset{0};
}; };
inline DenseTensorMeta::DenseTensorMeta(DataType type, const DDim& dims)
: dims(dims), type(type) {}
inline DenseTensorMeta::DenseTensorMeta(DataType type,
const DDim& dims,
DataLayout layout)
: dims(dims), type(type), layout(layout) {}
inline DenseTensorMeta::DenseTensorMeta(
DataType type,
const DDim& dims,
DataLayout layout,
const std::vector<std::vector<size_t>>& lod)
: dims(dims), type(type), layout(layout), lod(lod) {}
inline bool DenseTensorMeta::valid() const noexcept {
bool valid{true};
valid = valid && (type != DataType::UNDEFINED);
valid = valid && (layout != DataLayout::UNDEFINED);
valid = valid && (is_scalar || product(dims) >= 0);
return valid;
}
inline bool operator==(const DenseTensorMeta& lhs, const DenseTensorMeta& rhs) {
bool ret = true;
return ret && (lhs.is_scalar == rhs.is_scalar) && (lhs.dims == rhs.dims) &&
(lhs.type == rhs.type) && (lhs.layout == rhs.layout) &&
(lhs.lod == rhs.lod) && (lhs.offset == rhs.offset);
}
} // namespace pten } // namespace pten
...@@ -44,17 +44,27 @@ void FlattenWithXShape(const CPUContext& dev_ctx, ...@@ -44,17 +44,27 @@ void FlattenWithXShape(const CPUContext& dev_ctx,
general::SetXShape(x, xshape); general::SetXShape(x, xshape);
} }
void ReshapeFromVectorValImpl(const CPUContext& dev_ctx,
const DenseTensor& x,
const std::vector<int64_t>& shape,
DenseTensor* out,
bool set_lod) {
auto out_meta = InferShapeFromVecValue(x.meta(), shape);
if (&x != out) {
pten::Copy(dev_ctx, x, out);
}
if (set_lod) {
out->Resize(out_meta.dims, out_meta.lod);
} else {
out->Resize(out_meta.dims);
}
}
void ReshapeFromVectorVal(const CPUContext& dev_ctx, void ReshapeFromVectorVal(const CPUContext& dev_ctx,
const DenseTensor& x, const DenseTensor& x,
const std::vector<int64_t>& shape, const std::vector<int64_t>& shape,
DenseTensor* out) { DenseTensor* out) {
auto out_meta = InferShapeFromVecValue(x.meta(), shape); ReshapeFromVectorValImpl(dev_ctx, x, shape, out, false);
if (&x == out) {
out->Resize(out_meta.dims);
return;
}
pten::Copy(dev_ctx, x, out);
out->Resize(out_meta.dims);
} }
void ReshapeFromVectorValWithXShape(const CPUContext& dev_ctx, void ReshapeFromVectorValWithXShape(const CPUContext& dev_ctx,
...@@ -73,8 +83,7 @@ void ReshapeFromDT(const CPUContext& dev_ctx, ...@@ -73,8 +83,7 @@ void ReshapeFromDT(const CPUContext& dev_ctx,
auto* shape_data = shape.data<int>(); auto* shape_data = shape.data<int>();
auto vector_shape = auto vector_shape =
std::vector<int64_t>(shape_data, shape_data + shape.numel()); std::vector<int64_t>(shape_data, shape_data + shape.numel());
ReshapeFromVectorVal(dev_ctx, x, vector_shape, out); ReshapeFromVectorValImpl(dev_ctx, x, vector_shape, out, true);
out->set_lod(x.lod());
} }
void ReshapeFromDTWithXShape(const CPUContext& dev_ctx, void ReshapeFromDTWithXShape(const CPUContext& dev_ctx,
......
...@@ -44,18 +44,27 @@ void FlattenWithXShape(const CUDAContext& dev_ctx, ...@@ -44,18 +44,27 @@ void FlattenWithXShape(const CUDAContext& dev_ctx,
general::SetXShape(x, xshape); general::SetXShape(x, xshape);
} }
void ReshapeFromVectorValImpl(const CUDAContext& dev_ctx,
const DenseTensor& x,
const std::vector<int64_t>& shape,
DenseTensor* out,
bool set_lod) {
auto out_meta = InferShapeFromVecValue(x.meta(), shape);
if (&x != out) {
pten::Copy(dev_ctx, x, false, out);
}
if (set_lod) {
out->Resize(out_meta.dims, out_meta.lod);
} else {
out->Resize(out_meta.dims);
}
}
void ReshapeFromVectorVal(const CUDAContext& dev_ctx, void ReshapeFromVectorVal(const CUDAContext& dev_ctx,
const DenseTensor& x, const DenseTensor& x,
const std::vector<int64_t>& shape, const std::vector<int64_t>& shape,
DenseTensor* out) { DenseTensor* out) {
auto out_meta = InferShapeFromVecValue(x.meta(), shape); ReshapeFromVectorValImpl(dev_ctx, x, shape, out, false);
if (&x == out) {
LOG(INFO) << "out_meta dims:" << out_meta.dims;
out->Resize(out_meta.dims);
return;
}
pten::Copy(dev_ctx, x, false, out);
out->Resize(out_meta.dims);
} }
void ReshapeFromVectorValWithXShape(const CUDAContext& dev_ctx, void ReshapeFromVectorValWithXShape(const CUDAContext& dev_ctx,
...@@ -74,8 +83,7 @@ void ReshapeFromDT(const CUDAContext& dev_ctx, ...@@ -74,8 +83,7 @@ void ReshapeFromDT(const CUDAContext& dev_ctx,
auto* shape_data = shape.data<int>(); auto* shape_data = shape.data<int>();
auto vector_shape = auto vector_shape =
std::vector<int64_t>(shape_data, shape_data + shape.numel()); std::vector<int64_t>(shape_data, shape_data + shape.numel());
ReshapeFromVectorVal(dev_ctx, x, vector_shape, out); ReshapeFromVectorValImpl(dev_ctx, x, vector_shape, out, true);
out->set_lod(x.lod());
} }
void ReshapeFromDTWithXShape(const CUDAContext& dev_ctx, void ReshapeFromDTWithXShape(const CUDAContext& dev_ctx,
......
...@@ -26,8 +26,7 @@ inline void SetXShape(const DenseTensor& x, DenseTensor* xshape) { ...@@ -26,8 +26,7 @@ inline void SetXShape(const DenseTensor& x, DenseTensor* xshape) {
for (int i = 0; i < in_dims.size(); ++i) { for (int i = 0; i < in_dims.size(); ++i) {
xshape_dims[i + 1] = in_dims[i]; xshape_dims[i + 1] = in_dims[i];
} }
xshape->Resize(paddle::framework::make_ddim(xshape_dims)); xshape->Resize(paddle::framework::make_ddim(xshape_dims), x.meta().lod);
xshape->set_lod(x.meta().lod);
} }
} // namespace general } // namespace general
......
...@@ -47,8 +47,7 @@ void FlattenWithXShape(const XPUContext& dev_ctx, ...@@ -47,8 +47,7 @@ void FlattenWithXShape(const XPUContext& dev_ctx,
for (int i = 0; i < in_dims.size(); ++i) { for (int i = 0; i < in_dims.size(); ++i) {
xshape_dims[i + 1] = in_dims[i]; xshape_dims[i + 1] = in_dims[i];
} }
xshape->Resize(paddle::framework::make_ddim(xshape_dims)); xshape->Resize(paddle::framework::make_ddim(xshape_dims), x.meta().lod);
xshape->set_lod(x.lod());
} }
void ReshapeFromVectorVal(const XPUContext& dev_ctx, void ReshapeFromVectorVal(const XPUContext& dev_ctx,
......
...@@ -112,14 +112,11 @@ TEST(dense_tensor, resize) { ...@@ -112,14 +112,11 @@ TEST(dense_tensor, resize) {
auto alloc = std::make_shared<FancyAllocator>(); auto alloc = std::make_shared<FancyAllocator>();
DenseTensor tensor_0(alloc, meta); DenseTensor tensor_0(alloc, meta);
CHECK_EQ(tensor_0.memory_size(), 2u); CHECK_EQ(tensor_0.capacity(), 2u);
tensor_0.check_memory_size();
tensor_0.Resize({1, 2, 3}); tensor_0.Resize({1, 2, 3});
CHECK_EQ(tensor_0.memory_size(), 0u); CHECK_EQ(tensor_0.capacity(), 6u);
tensor_0.set_dims({2, 3});
CHECK_EQ(tensor_0.memory_size(), 0u);
tensor_0.mutable_data<int8_t>(); tensor_0.mutable_data<int8_t>();
CHECK_EQ(tensor_0.memory_size(), 6u); CHECK_EQ(tensor_0.capacity(), 6u);
auto storage = tensor_0.release(); auto storage = tensor_0.release();
CHECK_EQ(storage->size(), 6u); CHECK_EQ(storage->size(), 6u);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册