From ceb6b3f1fb3865711c03d64be5497197f1257258 Mon Sep 17 00:00:00 2001 From: zhaoying9105 Date: Tue, 14 Jun 2022 19:55:03 +0800 Subject: [PATCH] [MLU]: add elementwise_max mlu kernel (#43365) * [MLU]: add elementwise_max mlu kernel * [MLU]: add int32 support for elementwise maxk MLU kernel --- .../elementwise/elementwise_max_op_mlu.cc | 37 +++ .../operators/elementwise/elementwise_mlu.h | 11 + .../mlu/test_elementwise_max_op_mlu.py | 241 ++++++++++++++++++ 3 files changed, 289 insertions(+) create mode 100644 paddle/fluid/operators/elementwise/elementwise_max_op_mlu.cc create mode 100644 python/paddle/fluid/tests/unittests/mlu/test_elementwise_max_op_mlu.py diff --git a/paddle/fluid/operators/elementwise/elementwise_max_op_mlu.cc b/paddle/fluid/operators/elementwise/elementwise_max_op_mlu.cc new file mode 100644 index 00000000000..3ff93c49a36 --- /dev/null +++ b/paddle/fluid/operators/elementwise/elementwise_max_op_mlu.cc @@ -0,0 +1,37 @@ +/* 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. */ + +#ifdef PADDLE_WITH_MLU + +#include "paddle/fluid/operators/elementwise/elementwise_mlu.h" +#include "paddle/fluid/operators/elementwise/elementwise_op.h" +namespace paddle { +namespace operators { + +template +class ElementwiseMaxMLUKernel : public framework::OpKernel { + public: + void Compute(const framework::ExecutionContext& ctx) const override { + MLUBinaryOp(ctx); + } +}; + +} // namespace operators +} // namespace paddle + +namespace ops = paddle::operators; +REGISTER_OP_MLU_KERNEL(elementwise_max, ops::ElementwiseMaxMLUKernel, + ops::ElementwiseMaxMLUKernel, + ops::ElementwiseMaxMLUKernel); +#endif diff --git a/paddle/fluid/operators/elementwise/elementwise_mlu.h b/paddle/fluid/operators/elementwise/elementwise_mlu.h index 8c230c5f47b..a6a153c34d4 100644 --- a/paddle/fluid/operators/elementwise/elementwise_mlu.h +++ b/paddle/fluid/operators/elementwise/elementwise_mlu.h @@ -108,6 +108,7 @@ void MLUOpTensorKernel(const framework::ExecutionContext& ctx, enum BINARY_FUNCTOR { DIV, DIVNONAN, + MAXIMUM, }; template @@ -126,6 +127,16 @@ inline void MLUBinary
(const framework::ExecutionContext& ctx, MLUCnnl::Div(ctx, prefer, x_desc, x, y_desc, y, out_desc, out); } +template <> +inline void MLUBinary( + const framework::ExecutionContext& ctx, + cnnlComputationPreference_t prefer, // useless, only for compatible + const cnnlTensorDescriptor_t x_desc, const void* x, + const cnnlTensorDescriptor_t y_desc, const void* y, + const cnnlTensorDescriptor_t out_desc, void* out) { + MLUCnnl::Maximum(ctx, x_desc, x, y_desc, y, out_desc, out); +} + template void MLUBinaryOp(const framework::ExecutionContext& ctx) { auto* x = ctx.Input("X"); diff --git a/python/paddle/fluid/tests/unittests/mlu/test_elementwise_max_op_mlu.py b/python/paddle/fluid/tests/unittests/mlu/test_elementwise_max_op_mlu.py new file mode 100644 index 00000000000..b4c74a99d85 --- /dev/null +++ b/python/paddle/fluid/tests/unittests/mlu/test_elementwise_max_op_mlu.py @@ -0,0 +1,241 @@ +# 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 +from paddle.fluid.core import ops + +paddle.enable_static() +SEED = 2022 + + +class TestElementwiseMax(OpTest): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + + self.init_dtype() + np.random.seed(SEED) + x = np.random.uniform(1, 2, [11, 17]).astype(self.dtype) + y = np.random.uniform(1, 2, [11, 17]).astype(self.dtype) + out = np.maximum(x, y) + + self.inputs = { + 'X': OpTest.np_dtype_to_fluid_dtype(x), + 'Y': OpTest.np_dtype_to_fluid_dtype(y) + } + self.attrs = {} + self.outputs = {'Out': out} + + def set_mlu(self): + self.__class__.use_mlu = True + self.place = paddle.device.MLUPlace(0) + + def init_dtype(self): + self.dtype = np.float32 + + def test_check_output(self): + self.check_output_with_place(self.place) + + +class TestElementwiseMaxFp16(OpTest): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + + self.init_dtype() + np.random.seed(SEED) + x = np.random.uniform(1, 2, [3, 4]).astype(self.dtype) + y = np.random.uniform(1, 2, [3, 4]).astype(self.dtype) + out = np.maximum(x, y) + + self.inputs = { + 'X': OpTest.np_dtype_to_fluid_dtype(x), + 'Y': OpTest.np_dtype_to_fluid_dtype(y) + } + self.attrs = {} + self.outputs = {'Out': out} + + def set_mlu(self): + self.__class__.use_mlu = True + self.__class__.no_need_check_grad = True + self.place = paddle.device.MLUPlace(0) + + def init_dtype(self): + self.dtype = np.float16 + + def test_check_output(self): + self.check_output_with_place(self.place) + + +class TestElementwiseMaxInt32(OpTest): + + def init_dtype(self): + self.dtype = np.int32 + + +class TestTestElementwiseMax_Vector(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [100]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [100]).astype("float32") + } + self.outputs = {'Out': np.maximum(self.inputs['X'], self.inputs['Y'])} + + +class TestTestElementwiseMax_broadcast_0(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [100, 3, 4]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [100]).astype("float32") + } + + self.attrs = {'axis': 0} + self.outputs = { + 'Out': np.maximum(self.inputs['X'], + self.inputs['Y'].reshape(100, 1, 1)) + } + + +class TestTestElementwiseMax_broadcast_1(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [2, 100, 4]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [100]).astype("float32") + } + + self.attrs = {'axis': 1} + self.outputs = { + 'Out': np.maximum(self.inputs['X'], + self.inputs['Y'].reshape(1, 100, 1)) + } + + +class TestTestElementwiseMax_broadcast_2(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [2, 3, 100]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [100]).astype("float32") + } + + self.outputs = { + 'Out': np.maximum(self.inputs['X'], + self.inputs['Y'].reshape(1, 1, 100)) + } + + +class TestTestElementwiseMax_broadcast_3(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [2, 10, 12, 5]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [10, 12]).astype("float32") + } + + self.attrs = {'axis': 1} + self.outputs = { + 'Out': + np.maximum(self.inputs['X'], self.inputs['Y'].reshape(1, 10, 12, 1)) + } + + +class TestTestElementwiseMax_broadcast_4(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [2, 3, 50]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [2, 1, 50]).astype("float32") + } + self.outputs = {'Out': np.maximum(self.inputs['X'], self.inputs['Y'])} + + +class TestTestElementwiseMax_broadcast_5(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [2, 3, 4, 20]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [2, 3, 1, 20]).astype("float32") + } + self.outputs = {'Out': np.maximum(self.inputs['X'], self.inputs['Y'])} + + +class TestTestElementwiseMax_commonuse_1(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [2, 3, 100]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [1, 1, 100]).astype("float32"), + } + self.outputs = {'Out': np.maximum(self.inputs['X'], self.inputs['Y'])} + + +class TestTestElementwiseMax_commonuse_2(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [30, 3, 1, 5]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [30, 1, 4, 1]).astype("float32"), + } + self.outputs = {'Out': np.maximum(self.inputs['X'], self.inputs['Y'])} + + +class TestTestElementwiseMax_xsize_lessthan_ysize(TestElementwiseMax): + + def setUp(self): + self.set_mlu() + self.op_type = "elementwise_max" + self.inputs = { + 'X': np.random.uniform(0.1, 1, [10, 12]).astype("float32"), + 'Y': np.random.uniform(0.1, 1, [2, 3, 10, 12]).astype("float32"), + } + + self.attrs = {'axis': 2} + + self.outputs = {'Out': np.maximum(self.inputs['X'], self.inputs['Y'])} + + +if __name__ == '__main__': + unittest.main() -- GitLab