Skip to content

Commit eb9267a

Browse files
authored
[0-size Tensor No.18、42、51、83] Add 0-size Tensor support for hessian、cumulative_trapezoid、einsum、fused_feedforward API. (#73962)
* add cumulative_trapezoid test case * fix fusedFFN and einsum * fix test_einsum_0d_tensor error * fix judge condition
1 parent 9dac891 commit eb9267a

File tree

8 files changed

+91
-3
lines changed

8 files changed

+91
-3
lines changed

paddle/phi/infermeta/unary.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ void EinsumInferMeta(const std::vector<const MetaTensor*>& inputs,
12511251
const std::string& equation,
12521252
MetaTensor* out) {
12531253
// collect the following information to prepare einsum.
1254-
LabelMap labelshape(0);
1254+
LabelMap labelshape(-1);
12551255
LabelMap labeltype(LabelType::Reduction);
12561256
std::vector<LabelMap> label2perms(inputs.size(), LabelMap(-1));
12571257
std::vector<char> all_labels;

paddle/phi/kernels/fusion/gpu/fused_feedforward_grad_kernel.cu

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ void FusedFeedForwardGradKernel(
327327
dev_ctx.template Alloc<T>(d_linear2_weight,
328328
d_linear2_weight->numel() * sizeof(T));
329329

330+
if (d_x->numel() == 0) return;
331+
330332
auto x_dim = x.dims();
331333
auto mat_dim_x = phi::funcs::CreateMatrixDescriptor(
332334
phi::RowMatrixFromVector(x_dim), 0, false);

paddle/phi/kernels/fusion/gpu/fused_feedforward_kernel.cu

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ void FusedFeedForwardKernel(const Context& dev_ctx,
250250
dev_ctx.template Alloc<T>(dropout1_out, dropout1_out->numel() * sizeof(T));
251251
dev_ctx.template Alloc<T>(dropout2_out, dropout2_out->numel() * sizeof(T));
252252

253+
if (out->numel() == 0) {
254+
return;
255+
}
256+
253257
auto x_dim = x_ptr->dims();
254258
auto mat_dim_x = phi::funcs::CreateMatrixDescriptor(
255259
phi::RowMatrixFromVector(x_dim), 0, false);

paddle/phi/kernels/impl/einsum_grad_kernel_impl.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
#include "paddle/phi/core/dense_tensor.h"
1919
#include "paddle/phi/kernels/complex_kernel.h"
20+
#include "paddle/phi/kernels/full_kernel.h"
2021
#include "paddle/phi/kernels/impl/einsum_kernel_impl.h"
2122
#include "paddle/phi/kernels/tile_grad_kernel.h"
2223
#include "paddle/phi/kernels/tile_kernel.h"
2324
#include "paddle/utils/string/string_helper.h"
24-
2525
namespace phi {
2626

2727
template <typename T, typename Context>
@@ -117,6 +117,17 @@ void EinsumGradKernel(const Context& dev_ctx,
117117
const std::string& equation,
118118
std::vector<DenseTensor*> x_grad) {
119119
VLOG(5) << "Start EinsumGradKernel:";
120+
bool has_zero_size_tensor = out_grad.numel() == 0;
121+
for (auto& i : x_grad) {
122+
if (i != nullptr) {
123+
if (i->numel() == 0) {
124+
has_zero_size_tensor = true;
125+
phi::Full<T, Context>(
126+
dev_ctx, phi::IntArray(common::vectorize(i->dims())), 0, i);
127+
}
128+
}
129+
}
130+
if (has_zero_size_tensor) return;
120131
LabelMap labelshape(0);
121132
LabelMap labeltype(LabelType::Reduction);
122133
std::vector<LabelMap> label2perms(x.size(), LabelMap(-1));

paddle/phi/kernels/impl/einsum_kernel_impl.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,19 @@ inline static void InferLabelShape(
209209
for (size_t i = 0; i < op_labels.size(); ++i) {
210210
auto& op_str = op_labels[i];
211211
auto& op_dim = inputs[i];
212+
VLOG(5) << "i = " << i << " op_str " << op_str << " op_dim " << op_dim;
212213
int dim_ptr = 0;
213214
for (auto& c : op_str) {
214215
if (!labelshape->exist(c) || abs((*labelshape)[c]) == 1) {
215-
(*labelshape)[c] = op_dim[dim_ptr];
216+
VLOG(5)
217+
<< "if (!labelshape->exist(c) || abs((*labelshape)[c]) == 1) c = "
218+
<< c << " (*labelshape)[c] " << (*labelshape)[c]
219+
<< " op_dim[dim_ptr] " << op_dim[dim_ptr];
220+
(*labelshape)[c] = static_cast<int>(op_dim[dim_ptr]);
216221
} else if (abs(op_dim[dim_ptr]) != 1) {
222+
VLOG(5) << "if (abs(op_dim[dim_ptr]) != 1) c = " << c
223+
<< " (*labelshape)[c] " << (*labelshape)[c]
224+
<< " op_dim[dim_ptr] " << op_dim[dim_ptr];
217225
PADDLE_ENFORCE_EQ(
218226
(*labelshape)[c],
219227
op_dim[dim_ptr],

test/legacy_test/test_cumulative_trapezoid.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ def set_api(self):
9797
self.ref_api = cumulative_trapezoid
9898

9999

100+
class TestCumulativeTrapezoidZeroSizeTensorCase1(TestCumulativeTrapezoidAPI):
101+
def set_args(self):
102+
self.y = np.random.random((3, 3, 0)).astype('float32')
103+
self.x = np.random.random(3).astype('float32')
104+
self.dx = None
105+
self.axis = 0
106+
107+
108+
class TestCumulativeTrapezoidZeroSizeTensorCase2(TestCumulativeTrapezoidAPI):
109+
def set_args(self):
110+
self.y = np.random.random((1, 3, 3)).astype('float32')
111+
self.x = np.random.random((0, 3, 3)).astype('float32')
112+
self.dx = None
113+
self.axis = -1
114+
115+
100116
if __name__ == '__main__':
101117
paddle.enable_static()
102118
unittest.main()

test/legacy_test/test_einsum.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ def setUpClass(cls):
147147
"I": np.random.rand(2, 2),
148148
"J": np.random.rand(1, 3, 5),
149149
"K": np.random.rand(1, 2, 3, 4),
150+
"L": np.random.rand(2, 0, 13),
151+
"M": np.random.rand(13),
150152
}
151153

152154
def _get_place(self, force_to_use_cpu=False):
@@ -320,6 +322,42 @@ def setUp(self):
320322
self.sample = {"paradigm": "blq,bhlk->bhlqk", "data": ["J", "K"]}
321323

322324

325+
class TestEinsumZeroSizeTensor(TestEinsum):
326+
def setUp(self):
327+
self.sample = {"paradigm": "...i, ...i", "data": ["L", "M"]}
328+
329+
def test_backward(self):
330+
operands = [
331+
TestEinsum.TEST_SAMPLES[operand] for operand in self.sample["data"]
332+
]
333+
expected_result = np.einsum(self.sample["paradigm"], *operands)
334+
equation = self.sample["paradigm"]
335+
336+
with paddle.base.dygraph.guard(self._get_place(force_to_use_cpu=False)):
337+
pd_operands = [
338+
paddle.to_tensor(operand, stop_gradient=False)
339+
for operand in operands
340+
]
341+
result = paddle.einsum(equation, *pd_operands)
342+
self.check_output_equal(result.numpy(), expected_result)
343+
loss = result.sum()
344+
loss.backward()
345+
for x in pd_operands:
346+
np.testing.assert_allclose(x.grad.shape, x.shape)
347+
348+
with paddle.base.dygraph.guard(self._get_place(force_to_use_cpu=True)):
349+
pd_operands = [
350+
paddle.to_tensor(operand, stop_gradient=False)
351+
for operand in operands
352+
]
353+
result = paddle.einsum(equation, *pd_operands)
354+
self.check_output_equal(result.numpy(), expected_result)
355+
loss = result.sum()
356+
loss.backward()
357+
for x in pd_operands:
358+
np.testing.assert_allclose(x.grad.shape, x.shape)
359+
360+
323361
class TestNumpyTests(unittest.TestCase):
324362
def setUp(self):
325363
pass

test/legacy_test/test_fused_feedforward_op.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,5 +496,14 @@ def test_dropout_mode():
496496
self.assertRaises(ValueError, test_dropout_mode)
497497

498498

499+
class APITestStaticFusedFFNZeroSizeTensor(unittest.TestCase):
500+
def setUp(self):
501+
self.dtype = "float32"
502+
self.layer_norm_dtype = "float32"
503+
self.batch_size = 1
504+
self.d_model = 8
505+
self.dim_feedforward = 0
506+
507+
499508
if __name__ == "__main__":
500509
unittest.main()

0 commit comments

Comments
 (0)