Skip to content

Commit d711d9e

Browse files
authored
[Eager][PHI] Fix eager Tensor deepcopy for 0 size Tensor (#68862)
1 parent a89551b commit d711d9e

22 files changed

+106
-3
lines changed

paddle/fluid/eager/eager_tensor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ class VariableCompatTensor
130130

131131
bool valid() const override { return IsInitialized(); }
132132

133+
bool has_allocation() const override { return IsInitialized(); }
134+
133135
bool initialized() const override { return IsInitialized(); }
134136

135137
void* AllocateFrom(phi::Allocator* allocator UNUSED,

paddle/fluid/pir/dialect/operator/ir/ir_selected_rows.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ class IrSelectedRows
7474

7575
bool valid() const noexcept override { return true; }
7676

77+
bool has_allocation() const override {
78+
PADDLE_THROW(::common::errors::Unavailable(
79+
"`has_allocation` is only available at runtime"));
80+
}
81+
7782
bool initialized() const override { return true; }
7883

7984
void* AllocateFrom(phi::Allocator* allocator,

paddle/fluid/pir/dialect/operator/ir/ir_sparse_tensor.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ class IrSparseCooTensor
7575

7676
bool valid() const noexcept override { return true; }
7777

78+
bool has_allocation() const override {
79+
PADDLE_THROW(::common::errors::Unavailable(
80+
"`has_allocation` is only available at runtime"));
81+
}
82+
7883
bool initialized() const override { return true; }
7984

8085
void* AllocateFrom(phi::Allocator* allocator,
@@ -151,6 +156,8 @@ class IrSparseCsrTensor
151156

152157
bool valid() const noexcept override { return true; }
153158

159+
bool has_allocation() const override { return true; }
160+
154161
bool initialized() const override { return true; }
155162

156163
void* AllocateFrom(phi::Allocator* allocator,

paddle/fluid/pir/dialect/operator/ir/ir_tensor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ class IrTensor : public phi::TensorBase,
7373

7474
bool valid() const noexcept override { return true; }
7575

76+
bool has_allocation() const override {
77+
PADDLE_THROW(::common::errors::Unavailable(
78+
"`has_allocation` is only available at runtime"));
79+
}
80+
7681
bool initialized() const override { return true; }
7782

7883
void* AllocateFrom(phi::Allocator* allocator,

paddle/fluid/pybind/eager_method.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,11 +693,11 @@ static PyObject* tensor_method_copy_(TensorObject* self,
693693
egr::EagerUtils::autograd_meta(&(self->tensor))
694694
->SetPersistable(
695695
egr::EagerUtils::autograd_meta(&(src_tensor))->Persistable());
696-
if (src_tensor.initialized()) {
696+
if (src_tensor.has_allocation()) {
697697
self->tensor.copy_(src_tensor, src_tensor.place(), blocking);
698698
}
699699
} else {
700-
if (src_tensor.initialized()) {
700+
if (src_tensor.has_allocation()) {
701701
eager_gil_scoped_release guard;
702702
self->tensor.copy_(src_tensor, self->tensor.place(), blocking);
703703
}

paddle/phi/api/include/tensor.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,13 @@ class PADDLE_API Tensor final {
498498
*/
499499
bool defined() const;
500500

501+
/**
502+
* @brief Determine whether Tensor has allocation
503+
*
504+
* @return bool
505+
*/
506+
bool has_allocation() const;
507+
501508
/**
502509
* @brief Determine whether Tensor is initialized.
503510
*

paddle/phi/api/lib/tensor.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,10 @@ void Tensor::set_name(const std::string &name) { name_ = name; }
411411

412412
bool Tensor::defined() const { return impl_ != nullptr; }
413413

414+
bool Tensor::has_allocation() const {
415+
return defined() && impl_->has_allocation();
416+
}
417+
414418
bool Tensor::initialized() const { return defined() && impl_->initialized(); }
415419

416420
bool Tensor::is_initialized() const {

paddle/phi/api/lib/tensor_method.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Tensor::copy_to<phi::dtype::float16>(const Place &target_place) const;
8787
void Tensor::copy_(const Tensor &src,
8888
const phi::Place &target_place,
8989
bool blocking) {
90-
if (!src.initialized()) {
90+
if (!src.has_allocation()) {
9191
VLOG(8) << "Src is empty, skip copy";
9292
return;
9393
}

paddle/phi/core/dense_tensor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ class TEST_API DenseTensor : public TensorBase,
128128
/// return Whether the allocation is allocated.
129129
bool initialized() const override { return holder_ && holder_->ptr(); }
130130

131+
/// \brief Test whether the holder is created.
132+
/// \return Whether the holder is created.
133+
bool has_allocation() const override { return holder_ != nullptr; }
134+
131135
/// \brief Allocate memory with requested size from allocator.
132136
/// \return The mutable data pointer value of type T.
133137
void* AllocateFrom(Allocator* allocator,

paddle/phi/core/distributed/auto_parallel/dist_tensor.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ bool DistTensor::valid() const {
273273

274274
bool DistTensor::defined() const { return value_->holder_ != nullptr; }
275275

276+
bool DistTensor::has_allocation() const {
277+
return value_->holder_ != nullptr && (value_->holder_->ptr() || numel() != 0);
278+
}
279+
276280
bool DistTensor::initialized() const {
277281
return value_->holder_ != nullptr && value_->holder_->ptr();
278282
}

paddle/phi/core/distributed/auto_parallel/dist_tensor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ class DistTensor final
147147
/// \return The global dims of the dist tensor.
148148
const DDim& local_dims() const;
149149

150+
/// \brief Test whether the holder is created.
151+
/// \return Whether the holder is created.
152+
bool has_allocation() const override;
153+
150154
/// \brief Returns the global number of elements contained in tensor.
151155
/// \return The number of elements contained in tensor.
152156
int64_t numel() const override;

paddle/phi/core/extended_tensor.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ bool ExtendedTensor::valid() const {
4747
"ExtendedTensor does not support `valid` method."));
4848
}
4949

50+
bool ExtendedTensor::has_allocation() const {
51+
PADDLE_THROW(common::errors::Unavailable(
52+
"ExtendedTensor does not support `has_allocation` method."));
53+
}
54+
5055
bool ExtendedTensor::initialized() const {
5156
PADDLE_THROW(common::errors::Unavailable(
5257
"ExtendedTensor does not support `initialized` method."));

paddle/phi/core/extended_tensor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class TEST_API ExtendedTensor : public TensorBase {
4747

4848
bool valid() const override;
4949

50+
bool has_allocation() const override;
51+
5052
bool initialized() const override;
5153

5254
void* AllocateFrom(Allocator* allocator,

paddle/phi/core/selected_rows.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ class SelectedRows : public TensorBase,
160160
/// \return Whether the metadata is valid.
161161
bool valid() const noexcept override { return impl_->valid(); }
162162

163+
/// \brief Test whether the holder is created.
164+
/// \return Whether the holder is created.
165+
bool has_allocation() const override { return impl_->has_allocation(); }
166+
163167
/// \brief Test whether the storage is allocated.
164168
/// return Whether the storage is allocated.
165169
bool initialized() const override { return impl_->initialized(); }

paddle/phi/core/selected_rows_impl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ class SelectedRowsImpl {
179179
/// \return Whether the metadata is valid.
180180
bool valid() const noexcept { return value_->valid(); }
181181

182+
/// \brief Test whether the holder is created.
183+
/// \return Whether the holder is created.
184+
bool has_allocation() const { return value_->has_allocation(); }
185+
182186
/// \brief Test whether the storage is allocated.
183187
/// return Whether the storage is allocated.
184188
bool initialized() const { return value_->initialized(); }

paddle/phi/core/sparse_coo_tensor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ class SparseCooTensor : public TensorBase,
126126
/// \return Whether the non_zero_elements_ metadata is valid.
127127
bool valid() const noexcept override { return non_zero_elements_.valid(); }
128128

129+
/// \brief Test whether the holder is created.
130+
/// \return Whether the holder is created.
131+
bool has_allocation() const override { return values().has_allocation(); }
132+
129133
/// \brief Test whether the non_zero_elements_ storage is allocated.
130134
/// In special cases, when nnz=0, non_zero_elements_ will not need to be
131135
/// initialized, but it is necessary to return true here, otherwise the

paddle/phi/core/sparse_csr_tensor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ class SparseCsrTensor : public TensorBase,
130130
/// \return Whether the non_zero_elements_ metadata is valid.
131131
bool valid() const noexcept override { return non_zero_elements_.valid(); }
132132

133+
/// \brief Test whether the holder is created.
134+
/// \return Whether the holder is created.
135+
bool has_allocation() const override { return values().has_allocation(); }
136+
133137
/// \brief Test whether the non_zero_elements_ storage is allocated.
134138
/// In special cases, when nnz=0, non_zero_elements_ will not need to be
135139
/// initialized, but it is necessary to return true here, otherwise the

paddle/phi/core/string_tensor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ class StringTensor : public TensorBase,
9797
/// \return Whether the metadata is valid.
9898
bool valid() const noexcept override { return meta_.valid(); }
9999

100+
/// \brief Test whether the holder is created.
101+
/// \return Whether the holder is created.
102+
bool has_allocation() const override { return holder_ != nullptr; }
103+
100104
/// \brief Test whether the storage is allocated.
101105
/// return Whether the storage is allocated.
102106
bool initialized() const override { return holder_ && holder_->ptr(); }

paddle/phi/core/tensor_array.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ TensorArray::TensorArray(const std::vector<DenseTensor>& vec) {
2121
tensors_ = vec;
2222
}
2323

24+
/// \brief Test whether the holder is created.
25+
/// \return Whether the holder is created.
26+
bool TensorArray::has_allocation() const {
27+
if (tensors_.empty()) {
28+
return false;
29+
}
30+
31+
for (auto const& tensor : tensors_) {
32+
if (!tensor.has_allocation()) {
33+
return false;
34+
}
35+
}
36+
return true;
37+
}
38+
2439
/// \brief Test whether the tensor's storage in TensorArray is allocated.
2540
/// return Whether all tensors in TensorArray is allocated.
2641
bool TensorArray::initialized() const {

paddle/phi/core/tensor_array.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ class TensorArray : public TensorBase,
7878
/// \brief This overridden function is not used in TensorArray.
7979
TEST_API bool valid() const override;
8080

81+
/// \brief Test whether the holder is created.
82+
/// \return Whether the holder is created.
83+
TEST_API bool has_allocation() const override;
84+
8185
/// \brief Test whether the tensor's storage in TensorArray is allocated.
8286
/// return Whether all tensors in TensorArray is allocated.
8387
TEST_API bool initialized() const override;

paddle/phi/core/tensor_base.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class TensorBase {
5252
/// \return Whether the metadata is valid.
5353
virtual bool valid() const = 0;
5454

55+
/// \brief Test whether the holder is created.
56+
/// \return Whether the holder is created.
57+
virtual bool has_allocation() const = 0;
58+
5559
/// \brief Test whether the storage is allocated.
5660
/// \return Whether the storage is allocated.
5761
virtual bool initialized() const = 0;

test/legacy_test/test_eager_tensor.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,17 @@ def test_deep_copy(self):
542542
np.array(selected_rows.get_tensor()),
543543
)
544544

545+
def test_deep_copy_0size_tensor(self):
546+
x = paddle.to_tensor(np.array([]))
547+
x_copy = copy.deepcopy(x)
548+
self.assertEqual(x_copy.stop_gradient, x.stop_gradient)
549+
self.assertEqual(x_copy.persistable, x.persistable)
550+
self.assertEqual(x_copy.type, x.type)
551+
self.assertEqual(x_copy.dtype, x.dtype)
552+
self.assertEqual(x_copy.shape, x.shape)
553+
self.assertEqual(str(x_copy.place), str(x.place))
554+
np.testing.assert_array_equal(x.numpy(), x_copy.numpy())
555+
545556
# test some patched methods
546557
def test_set_value(self):
547558
var = paddle.to_tensor(self.array)

0 commit comments

Comments
 (0)