From cb195fa0c349b0592974dbb206f0f708552db943 Mon Sep 17 00:00:00 2001 From: cambriconhsq <106155938+cambriconhsq@users.noreply.github.com> Date: Tue, 31 May 2022 16:28:38 +0800 Subject: [PATCH] [MLU] add mlu kernel for abs op (#43099) --- paddle/fluid/operators/abs_op_mlu.cc | 75 +++++++++++++++ .../tests/unittests/mlu/test_abs_op_mlu.py | 95 +++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 paddle/fluid/operators/abs_op_mlu.cc create mode 100644 python/paddle/fluid/tests/unittests/mlu/test_abs_op_mlu.py diff --git a/paddle/fluid/operators/abs_op_mlu.cc b/paddle/fluid/operators/abs_op_mlu.cc new file mode 100644 index 00000000000..3a3a484ea77 --- /dev/null +++ b/paddle/fluid/operators/abs_op_mlu.cc @@ -0,0 +1,75 @@ +/* Copyright (c) 2022 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 Licnse. */ + +#include "paddle/fluid/framework/op_registry.h" +#include "paddle/fluid/operators/mlu/mlu_baseop.h" + +namespace paddle { +namespace operators { + +using Tensor = framework::Tensor; + +template +class AbsMLUKernel : public framework::OpKernel { + public: + void Compute(const framework::ExecutionContext& ctx) const override { + auto* input = ctx.Input("X"); + auto* output = ctx.Output("Out"); + + output->mutable_data(ctx.GetPlace()); + + MLUCnnlTensorDesc input_desc(*input); + MLUCnnlTensorDesc output_desc(*output); + + MLUCnnl::Abs(ctx, input_desc.get(), GetBasePtr(input), output_desc.get(), + GetBasePtr(output)); + } +}; + +template +class AbsGradMLUKernel : public framework::OpKernel { + public: + void Compute(const framework::ExecutionContext& ctx) const override { + auto* x = ctx.Input("X"); + auto* dout = ctx.Input(framework::GradVarName("Out")); + auto* dx = ctx.Output(framework::GradVarName("X")); + + dx->mutable_data(ctx.GetPlace()); + + MLUCnnlTensorDesc input_desc(*x); + MLUCnnlOpTensorDesc mul_op_desc(CNNL_OP_TENSOR_MUL, ToCnnlDataType(), + CNNL_NOT_PROPAGATE_NAN); + + Tensor sign_x; + sign_x.mutable_data(x->dims(), ctx.GetPlace()); + + MLUCnnl::Sign(ctx, input_desc.get(), GetBasePtr(x), input_desc.get(), + GetBasePtr(&sign_x)); + MLUCnnl::OpTensor(ctx, mul_op_desc.get(), input_desc.get(), + GetBasePtr(&sign_x), input_desc.get(), GetBasePtr(dout), + input_desc.get(), GetBasePtr(dx), ToCnnlDataType()); + } +}; + +} // namespace operators +} // namespace paddle + +namespace ops = paddle::operators; +namespace plat = paddle::platform; + +REGISTER_OP_MLU_KERNEL(abs, ops::AbsMLUKernel, + ops::AbsMLUKernel); + +REGISTER_OP_MLU_KERNEL(abs_grad, ops::AbsGradMLUKernel, + ops::AbsGradMLUKernel); diff --git a/python/paddle/fluid/tests/unittests/mlu/test_abs_op_mlu.py b/python/paddle/fluid/tests/unittests/mlu/test_abs_op_mlu.py new file mode 100644 index 00000000000..0c33bd6b1ad --- /dev/null +++ b/python/paddle/fluid/tests/unittests/mlu/test_abs_op_mlu.py @@ -0,0 +1,95 @@ +# Copyright (c) 2022 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. + +from __future__ import print_function + +import unittest +import numpy as np +import sys +sys.path.append('..') +from op_test import OpTest +import paddle.fluid.core as core +import paddle.fluid as fluid +from paddle.fluid import compiler, Program, program_guard +import paddle +import paddle.nn.functional as F + +paddle.enable_static() +np.random.seed(10) + + +class TestAbs(OpTest): + def setUp(self): + self.op_type = "abs" + self.set_mlu() + self.dtype = 'float32' + self.shape = [4, 25] + + np.random.seed(1024) + x = np.random.uniform(-1, 1, self.shape).astype(self.dtype) + # Because we set delta = 0.005 in calculating numeric gradient, + # if x is too small, such as 0.002, x_neg will be -0.003 + # x_pos will be 0.007, so the numeric gradient is inaccurate. + # we should avoid this + x[np.abs(x) < 0.005] = 0.02 + out = np.abs(x) + + self.inputs = {'X': OpTest.np_dtype_to_fluid_dtype(x)} + self.outputs = {'Out': out} + + def set_mlu(self): + self.__class__.use_mlu = True + self.place = paddle.device.MLUPlace(0) + + def test_check_output(self): + self.check_output_with_place(self.place) + + def test_check_grad(self): + self.check_grad_with_place( + self.place, ['X'], ['Out'], check_eager=False) + + +class TestAbsHalf(OpTest): + def setUp(self): + self.op_type = "abs" + self.set_mlu() + self.dtype = 'float16' + self.shape = [7, 9, 13, 19] + + np.random.seed(1024) + x = np.random.uniform(-1, 1, self.shape).astype(self.dtype) + # Because we set delta = 0.005 in calculating numeric gradient, + # if x is too small, such as 0.002, x_neg will be -0.003 + # x_pos will be 0.007, so the numeric gradient is inaccurate. + # we should avoid this + x[np.abs(x) < 0.005] = 0.02 + out = np.abs(x) + + self.inputs = {'X': OpTest.np_dtype_to_fluid_dtype(x)} + self.outputs = {'Out': out} + + def set_mlu(self): + self.__class__.use_mlu = True + self.place = paddle.device.MLUPlace(0) + + def test_check_output(self): + self.check_output_with_place(self.place) + + def test_check_grad(self): + self.check_grad_with_place( + self.place, ['X'], ['Out'], check_eager=False) + + +if __name__ == "__main__": + unittest.main() -- GitLab