Skip to content

Commit a399217

Browse files
authored
Fix (#73173)
1 parent f7ebcaf commit a399217

File tree

6 files changed

+140
-2
lines changed

6 files changed

+140
-2
lines changed

paddle/phi/kernels/impl/kldiv_loss_grad_kernel_impl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ void KLDivLossGradKernel(const Context& dev_ctx,
4848
const std::string& reduction,
4949
bool log_target,
5050
DenseTensor* d_x) {
51+
if (d_x->numel() == 0) {
52+
dev_ctx.template Alloc<T>(d_x);
53+
return;
54+
}
55+
5156
auto& place = *dev_ctx.eigen_device();
5257
auto* target = &label;
5358
auto* input_grad = d_x;

paddle/phi/kernels/impl/kldiv_loss_kernel_impl.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
#include "paddle/common/hostdevice.h"
1919
#include "paddle/phi/backends/cpu/cpu_context.h"
2020
#include "paddle/phi/core/dense_tensor.h"
21+
#include "paddle/phi/kernels/full_kernel.h"
2122
#include "paddle/phi/kernels/funcs/eigen/common.h"
22-
2323
namespace phi {
2424
using Array1 = Eigen::DSizes<int64_t, 1>;
2525
template <typename T>
@@ -48,6 +48,11 @@ void KLDivLossKernel(const Context& dev_ctx,
4848
const std::string& reduction,
4949
bool log_target,
5050
DenseTensor* out) {
51+
if (x.numel() == 0) {
52+
phi::Full<T, Context>(
53+
dev_ctx, phi::IntArray(common::vectorize(out->dims())), NAN, out);
54+
return;
55+
}
5156
auto& place = *(dev_ctx.eigen_device());
5257
auto* input = &x;
5358
auto* target = &label;

paddle/phi/kernels/xpu/kldiv_loss_kernel.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ limitations under the License. */
1515
#include "paddle/phi/backends/xpu/enforce_xpu.h"
1616
#include "paddle/phi/core/enforce.h"
1717
#include "paddle/phi/core/kernel_registry.h"
18+
#include "paddle/phi/kernels/full_kernel.h"
1819
#include "paddle/phi/kernels/softmax_kernel.h"
19-
2020
namespace phi {
2121

2222
template <typename T, typename Context>
@@ -31,6 +31,11 @@ void KLDivLossKernel(const Context& dev_ctx,
3131
if (out->numel() == 0) {
3232
return;
3333
}
34+
if (x.numel() == 0) {
35+
phi::Full<T, Context>(
36+
dev_ctx, phi::IntArray(common::vectorize(out->dims())), NAN, out);
37+
return;
38+
}
3439

3540
int r = 0;
3641

test/legacy_test/test_hinge_embedding_loss.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,5 +201,44 @@ def test_value_error():
201201
self.assertRaises(ValueError, test_value_error)
202202

203203

204+
class TestFunctionalHingeEmbeddingLoss_ZeroSize(unittest.TestCase):
205+
def setUp(self):
206+
self.margin = 1.0
207+
self.shape = (0, 10, 5) # zero size
208+
self.input_np = np.random.random(size=self.shape).astype(np.float64)
209+
self.label_np = 2 * np.random.randint(0, 2, size=self.shape) - 1.0
210+
211+
def run_dynamic_check(self, place=paddle.CPUPlace()):
212+
paddle.disable_static(place=place)
213+
input = paddle.to_tensor(self.input_np)
214+
input.stop_gradient = False
215+
label = paddle.to_tensor(self.label_np, dtype="float64")
216+
217+
dy_result = paddle.nn.functional.hinge_embedding_loss(input, label)
218+
expected = calc_hinge_embedding_loss(self.input_np, self.label_np)
219+
np.testing.assert_allclose(dy_result.numpy(), expected, rtol=1e-05)
220+
self.assertEqual(dy_result.shape, [])
221+
222+
dy_result = paddle.nn.functional.hinge_embedding_loss(
223+
input, label, reduction='none'
224+
)
225+
expected = calc_hinge_embedding_loss(
226+
self.input_np, self.label_np, reduction='none'
227+
)
228+
np.testing.assert_allclose(dy_result.numpy(), expected, rtol=1e-05)
229+
230+
loss = paddle.sum(dy_result)
231+
loss.backward()
232+
self.assertEqual(input.grad.shape, input.shape)
233+
234+
def test_cpu(self):
235+
self.run_dynamic_check(place=paddle.CPUPlace())
236+
237+
def test_gpu(self):
238+
if not paddle.is_compiled_with_cuda():
239+
return
240+
self.run_dynamic_check(place=paddle.CUDAPlace(0))
241+
242+
204243
if __name__ == "__main__":
205244
unittest.main()

test/legacy_test/test_kldiv_loss_op.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,52 @@ def initTestCase(self):
115115
self.log_target = True
116116

117117

118+
class TestKLDivLossOp_ZeroSize1(TestKLDivLossOp):
119+
def setUp(self):
120+
self.initTestCase()
121+
self.op_type = 'kldiv_loss'
122+
self.python_api = kl_div
123+
self.public_python_api = paddle.nn.functional.kl_div
124+
x = np.random.uniform(-10, 10, self.x_shape).astype('float64')
125+
target = np.random.uniform(-10, 10, self.x_shape).astype('float64')
126+
127+
self.attrs = {
128+
"reduction": self.reduction,
129+
"log_target": self.log_target,
130+
}
131+
132+
self.inputs = {
133+
'X': x,
134+
'Target': target,
135+
}
136+
loss = kldiv_loss(x, target, self.reduction, self.log_target)
137+
self.outputs = {'Loss': loss.astype('float64')}
138+
139+
def initTestCase(self):
140+
# return NAN
141+
self.x_shape = (0, 2, 7, 7)
142+
self.reduction = 'mean'
143+
self.log_target = False
144+
145+
def test_check_output(self):
146+
self.check_output(check_pir=True, equal_nan=True)
147+
148+
def test_check_grad(self):
149+
self.check_grad(
150+
['X'],
151+
'Loss',
152+
no_grad_set={"Target"},
153+
check_pir=True,
154+
)
155+
156+
157+
class TestKLDivLossOp_ZeroSize2(TestKLDivLossOp_ZeroSize1):
158+
def initTestCase(self):
159+
self.x_shape = (0, 2, 7, 7)
160+
self.reduction = 'none'
161+
self.log_target = False
162+
163+
118164
class TestKLDivLossDygraph(unittest.TestCase):
119165
def run_kl_loss(self, reduction, shape=(5, 20), log_target=False):
120166
x = np.random.uniform(-10, 10, shape).astype('float64')

test/legacy_test/test_l1_loss.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,44 @@ def test_value_error():
201201
self.assertRaises(ValueError, test_value_error)
202202

203203

204+
class TestClassL1Loss_ZeroSize(unittest.TestCase):
205+
def setUp(self):
206+
self.input_np = np.random.random(size=(0, 10, 5)).astype(np.float32)
207+
self.label_np = np.random.random(size=(0, 10, 5)).astype(np.float32)
208+
209+
def run_imperative(self):
210+
input = paddle.to_tensor(self.input_np)
211+
label = paddle.to_tensor(self.label_np)
212+
input.stop_gradient = False
213+
l1_loss = paddle.nn.loss.L1Loss()
214+
dy_result = l1_loss(input, label)
215+
expected = np.mean(np.abs(self.input_np - self.label_np))
216+
np.testing.assert_allclose(dy_result.numpy(), expected, rtol=1e-05)
217+
self.assertEqual(dy_result.shape, [])
218+
219+
l1_loss = paddle.nn.loss.L1Loss(reduction='sum')
220+
dy_result = l1_loss(input, label)
221+
expected = np.sum(np.abs(self.input_np - self.label_np))
222+
np.testing.assert_allclose(dy_result.numpy(), expected, rtol=1e-05)
223+
self.assertEqual(dy_result.shape, [])
224+
225+
loss = paddle.sum(dy_result)
226+
loss.backward()
227+
np.testing.assert_allclose(input.grad.shape, input.shape)
228+
229+
def test_cpu(self):
230+
paddle.disable_static(place=paddle.base.CPUPlace())
231+
self.run_imperative()
232+
paddle.enable_static()
233+
234+
def test_gpu(self):
235+
if not base.core.is_compiled_with_cuda():
236+
return
237+
paddle.disable_static(place=paddle.base.CUDAPlace(0))
238+
self.run_imperative()
239+
paddle.enable_static()
240+
241+
204242
if __name__ == "__main__":
205243
paddle.enable_static()
206244
unittest.main()

0 commit comments

Comments
 (0)