From 55d6b87c582e6a51ec91d397c0f874a06daa16c4 Mon Sep 17 00:00:00 2001 From: joeqiao12 <45232181+joeqiao12@users.noreply.github.com> Date: Wed, 26 Jan 2022 10:33:03 +0800 Subject: [PATCH] sum op (#39165) --- paddle/fluid/operators/sum_op_mlu.cc | 74 +++++++++++ .../tests/unittests/mlu/test_sum_op_mlu.py | 116 ++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 paddle/fluid/operators/sum_op_mlu.cc create mode 100755 python/paddle/fluid/tests/unittests/mlu/test_sum_op_mlu.py diff --git a/paddle/fluid/operators/sum_op_mlu.cc b/paddle/fluid/operators/sum_op_mlu.cc new file mode 100644 index 00000000000..e2cd649722b --- /dev/null +++ b/paddle/fluid/operators/sum_op_mlu.cc @@ -0,0 +1,74 @@ +/* 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. */ + +#include "paddle/fluid/operators/sum_op.h" +#include "paddle/fluid/operators/mlu/mlu_baseop.h" + +namespace paddle { +namespace operators { + +using Tensor = framework::Tensor; + +template +class SumMLUKernel : public framework::OpKernel { + public: + void Compute(const framework::ExecutionContext &ctx) const override { + auto out_var = ctx.OutputVar("Out"); + if (out_var->IsType()) { + // init + auto *out = out_var->GetMutable(); + auto ins = ctx.MultiInput("X"); + out->mutable_data(ctx.GetPlace()); + auto place = ctx.GetPlace(); + int ins_size = static_cast(ins.size()); + if (ins_size == 1) { + TensorCopy(*ins[0], place, out); + return; + } + + // MLU shoul do sth + std::vector inputs; + std::vector input_descs; + std::vector desc_vector; + for (int i = 0; i < ins_size; i++) { + input_descs.emplace_back(MLUCnnlTensorDesc( + *ins[i], CNNL_LAYOUT_ARRAY, ToCnnlDataType(ins[i]->type()))); + desc_vector.push_back(input_descs.back().get()); + inputs.push_back(GetBasePtr(ins[i])); + } + // init out tensors + MLUCnnlTensorDesc output_desc(*out, CNNL_LAYOUT_ARRAY, + ToCnnlDataType(out->type())); + uint32_t ins_size_t = static_cast(ins_size); + MLUCnnl::AddN(ctx, ins_size_t, desc_vector.data(), inputs.data(), + output_desc.get(), GetBasePtr(out)); + + } else { + PADDLE_THROW(platform::errors::InvalidArgument( + "Expected type of Output(out) must be Tensor or But got " + "unsupport type: %s.", + framework::ToTypeName(out_var->Type()))); + } + } +}; + +} // namespace operators +} // namespace paddle + +namespace ops = paddle::operators; + +REGISTER_OP_MLU_KERNEL( + sum, ops::SumMLUKernel, + ops::SumMLUKernel); diff --git a/python/paddle/fluid/tests/unittests/mlu/test_sum_op_mlu.py b/python/paddle/fluid/tests/unittests/mlu/test_sum_op_mlu.py new file mode 100755 index 00000000000..e9db14de46a --- /dev/null +++ b/python/paddle/fluid/tests/unittests/mlu/test_sum_op_mlu.py @@ -0,0 +1,116 @@ +# 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 numpy as np +import unittest +import sys +sys.path.append("..") +from op_test import OpTest +import paddle +import paddle.fluid as fluid +import paddle.fluid.core as core + +paddle.enable_static() +SEED = 2021 + + +class TestSum1(OpTest): + def setUp(self): + self.set_mlu() + self.init_dtype() + self.op_type = "sum" + self.place = paddle.MLUPlace(0) + + x0 = np.random.random((3, 40)).astype(self.dtype) + x1 = np.random.random((3, 40)).astype(self.dtype) + x2 = np.random.random((3, 40)).astype(self.dtype) + self.inputs = {'X': [("x0", x0), ("x1", x1), ("x2", x2)]} + y = x0 + x1 + x2 + self.outputs = {'Out': y} + + self.attrs = {'use_mkldnn': False} + + def init_dtype(self): + self.dtype = np.float32 + + def set_mlu(self): + self.__class__.use_mlu = True + + def test_check_output(self): + self.check_output_with_place(self.place) + + +class TestSum2(OpTest): + def setUp(self): + self.set_mlu() + self.init_dtype() + self.op_type = "sum" + self.place = paddle.MLUPlace(0) + + x0 = np.random.random((3, 3)).astype(self.dtype) + x1 = np.random.random((3, 3)).astype(self.dtype) + x2 = np.random.random((3, 3)).astype(self.dtype) + x3 = np.random.random((3, 3)).astype(self.dtype) + self.inputs = {'X': [("x0", x0), ("x1", x1), ("x2", x2), ("x3", x3)]} + # There will be a problem if just using `y=x0+x1+x2+x3` to calculate the + # summation result as the reference standard result. The reason is that + # numpy's fp16 data has precision loss when doing `add` operation. + # For example, the results of `x0+x1+x2+x3` is different from that of + # `x3+x2+x1+x0` if the dtype is fp16. + # Therefore, converting the input to fp32 for calculation. + y = (x0.astype(np.float32) + x1.astype(np.float32) + + x2.astype(np.float32) + x3.astype(np.float32)).astype(self.dtype) + self.outputs = {'Out': y} + + self.attrs = {'use_mkldnn': False} + + def init_dtype(self): + self.dtype = np.float16 + + def set_mlu(self): + self.__class__.use_mlu = True + + def test_check_output(self): + self.check_output_with_place(self.place) + + +class TestSum3(OpTest): + def setUp(self): + self.set_mlu() + self.init_dtype() + self.op_type = "sum" + self.place = paddle.MLUPlace(0) + + x0 = np.random.random((3, 3)).astype(self.dtype) + + self.inputs = {'X': [("x0", x0)]} + y = x0 + self.outputs = {'Out': y} + + self.attrs = {'use_mkldnn': False} + + def init_dtype(self): + self.dtype = np.float16 + + def set_mlu(self): + self.__class__.use_mlu = True + + def test_check_output(self): + self.check_output_with_place(self.place) + + +if __name__ == '__main__': + unittest.main() -- GitLab