Files
2026-07-13 12:40:42 +08:00

97 lines
3.4 KiB
C++

// Copyright (c) 2024 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/phi/kernels/logsumexp_grad_kernel.h"
#include "paddle/phi/backends/xpu/enforce_xpu.h"
#include "paddle/phi/core/kernel_registry.h"
namespace phi {
template <typename T, typename Context>
void LogsumexpGradKernel(const Context& dev_ctx,
const DenseTensor& x,
const DenseTensor& y,
const DenseTensor& dy,
const std::vector<int>& axis_in,
bool keepdim,
bool reduce_all,
DenseTensor* dx) {
if (dx && dx->numel() == 0) {
dev_ctx.template Alloc<T>(dx);
return;
}
using XPUType = typename XPUTypeTrait<T>::Type;
xpu::ctx_guard RAII_GUARD(dev_ctx.x_context());
reduce_all = recompute_reduce_all(x, axis_in, reduce_all);
auto x_data = reinterpret_cast<const XPUType*>(x.data<T>());
auto y_data = reinterpret_cast<const XPUType*>(y.data<T>());
auto dy_data = reinterpret_cast<const XPUType*>(dy.data<T>());
auto dx_data = reinterpret_cast<XPUType*>(dev_ctx.template Alloc<T>(dx));
std::vector<int64_t> xdims = vectorize<int64_t>(x.dims());
std::vector<int64_t> ydims = xdims;
if (reduce_all) {
ydims = {1};
xdims = {x.numel()};
} else {
std::vector<int64_t> axis;
axis.reserve(axis_in.size());
std::for_each(
axis_in.begin(), axis_in.end(), [&axis, &xdims](const int& t) {
if (t < 0) {
axis.push_back(static_cast<int64_t>(t + xdims.size()));
} else {
axis.push_back(static_cast<int64_t>(t));
}
});
for (size_t i = 0; i < axis.size(); ++i) {
PADDLE_ENFORCE_LT(
axis[i],
ydims.size(),
errors::InvalidArgument(
"The axis should be less than the rank of Input(X)."));
ydims[axis[i]] = 1;
}
}
int64_t xlen = 1;
for (size_t i = 0; i < xdims.size(); ++i) {
PADDLE_ENFORCE_LT(0,
xdims[i],
errors::InvalidArgument(
"The dims of Input(X) should be greater than 0."));
xlen *= xdims[i];
}
XPUType* tmp_data = RAII_GUARD.alloc<XPUType>(xlen);
int ret = xpu::broadcast_sub(
dev_ctx.x_context(), x_data, y_data, tmp_data, xdims, ydims);
PADDLE_ENFORCE_XDNN_SUCCESS(ret, "broadcast_sub");
ret = xpu::exp(dev_ctx.x_context(), tmp_data, tmp_data, xlen);
PADDLE_ENFORCE_XDNN_SUCCESS(ret, "exp");
ret = xpu::broadcast_mul(
dev_ctx.x_context(), dy_data, tmp_data, dx_data, ydims, xdims);
PADDLE_ENFORCE_XDNN_SUCCESS(ret, "broadcast_mul");
}
} // namespace phi
PD_REGISTER_KERNEL(logsumexp_grad,
XPU,
ALL_LAYOUT,
phi::LogsumexpGradKernel,
float,
phi::float16,
phi::bfloat16) {}