// Copyright (c) 2021 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/fluid/framework/op_registry.h" #include "paddle/fluid/platform/device/npu/npu_op_runner.h" namespace paddle { namespace operators { template class WhereNPUKernel : public framework::OpKernel { public: void Compute(const framework::ExecutionContext& ctx) const override { auto* condition = ctx.Input("Condition"); auto* X = ctx.Input("X"); auto* Y = ctx.Input("Y"); auto* out = ctx.Output("Out"); out->mutable_data(ctx.GetPlace()); const auto& runner = NpuOpRunner("Select", {*condition, *X, *Y}, {*out}, {}); auto stream = ctx.template device_context() .stream(); runner.Run(stream); } }; template class WhereGradNPUKernel : public framework::OpKernel { public: void Compute(const framework::ExecutionContext& ctx) const override { auto* condition = ctx.Input("Condition"); auto* dout_t = ctx.Input(framework::GradVarName("Out")); auto* dx_t = ctx.Output(framework::GradVarName("X")); auto* dy_t = ctx.Output(framework::GradVarName("Y")); if (dx_t != nullptr) { dx_t->mutable_data(ctx.GetPlace()); } if (dy_t != nullptr) { dy_t->mutable_data(ctx.GetPlace()); } auto stream = ctx.template device_context() .stream(); framework::Tensor tensor_zeros(dout_t->dtype()); tensor_zeros.mutable_data(dout_t->dims(), ctx.GetPlace()); const auto& runner = NpuOpRunner("ZerosLike", {*dout_t}, {tensor_zeros}, {}); runner.Run(stream); if (dx_t != nullptr) { const auto& runner = NpuOpRunner( "Select", {*condition, *dout_t, tensor_zeros}, {*dx_t}, {}); runner.Run(stream); } if (dy_t != nullptr) { const auto& runner = NpuOpRunner( "Select", {*condition, tensor_zeros, *dout_t}, {*dy_t}, {}); runner.Run(stream); } } }; } // namespace operators } // namespace paddle namespace ops = paddle::operators; REGISTER_OP_NPU_KERNEL( where, ops::WhereNPUKernel, ops::WhereNPUKernel, ops::WhereNPUKernel, ops::WhereNPUKernel); REGISTER_OP_NPU_KERNEL( where_grad, ops::WhereGradNPUKernel, ops::WhereGradNPUKernel, ops::WhereGradNPUKernel, ops::WhereGradNPUKernel);