// 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 void LogsumexpGradKernel(const Context& dev_ctx, const DenseTensor& x, const DenseTensor& y, const DenseTensor& dy, const std::vector& axis_in, bool keepdim, bool reduce_all, DenseTensor* dx) { if (dx && dx->numel() == 0) { dev_ctx.template Alloc(dx); return; } using XPUType = typename XPUTypeTrait::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(x.data()); auto y_data = reinterpret_cast(y.data()); auto dy_data = reinterpret_cast(dy.data()); auto dx_data = reinterpret_cast(dev_ctx.template Alloc(dx)); std::vector xdims = vectorize(x.dims()); std::vector ydims = xdims; if (reduce_all) { ydims = {1}; xdims = {x.numel()}; } else { std::vector 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(t + xdims.size())); } else { axis.push_back(static_cast(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(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) {}