From 5a5649c28541a1bd2c754e9a67d5d3636f587929 Mon Sep 17 00:00:00 2001 From: Chenxiao Niu Date: Fri, 17 Jun 2022 18:24:18 +0800 Subject: [PATCH] [MLU] add truncated_gaussian_random kernel. (#43575) --- .../truncated_gaussian_random_op_mlu.cc | 62 +++++++++++++ .../test_truncated_gaussian_random_op_mlu.py | 91 +++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 paddle/fluid/operators/truncated_gaussian_random_op_mlu.cc create mode 100644 python/paddle/fluid/tests/unittests/mlu/test_truncated_gaussian_random_op_mlu.py diff --git a/paddle/fluid/operators/truncated_gaussian_random_op_mlu.cc b/paddle/fluid/operators/truncated_gaussian_random_op_mlu.cc new file mode 100644 index 00000000000..6d5d9f8a3b1 --- /dev/null +++ b/paddle/fluid/operators/truncated_gaussian_random_op_mlu.cc @@ -0,0 +1,62 @@ +/* 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 +#include + +#include "paddle/fluid/framework/generator.h" +#include "paddle/fluid/framework/op_registry.h" +#include "paddle/fluid/operators/truncated_gaussian_random_op.h" + +namespace paddle { +namespace operators { + +template +class TruncatedGaussianRandomMLUKernel : public framework::OpKernel { + public: + void Compute(const framework::ExecutionContext& context) const override { + float mean = context.Attr("mean"); + float std = context.Attr("std"); + auto* tensor = context.Output("Out"); + tensor->mutable_data(context.GetPlace()); + + framework::Tensor cpu_tensor(tensor->dtype()); + cpu_tensor.Resize(tensor->dims()); + T* data_cpu = cpu_tensor.mutable_data(platform::CPUPlace()); + + std::uniform_real_distribution dist(std::numeric_limits::min(), + 1.0); + TruncatedNormal truncated_normal(mean, std); + int64_t size = tensor->numel(); + + unsigned int seed = static_cast(context.Attr("seed")); + auto engine = framework::GetCPURandomEngine(seed); + + for (int64_t i = 0; i < size; ++i) { + data_cpu[i] = truncated_normal(dist(*engine)); + } + + auto& dev_ctx = + context.template device_context(); + framework::TensorCopy(cpu_tensor, context.GetPlace(), dev_ctx, tensor); + dev_ctx.Wait(); + } +}; + +} // namespace operators +} // namespace paddle + +namespace ops = paddle::operators; +REGISTER_OP_MLU_KERNEL(truncated_gaussian_random, + ops::TruncatedGaussianRandomMLUKernel); diff --git a/python/paddle/fluid/tests/unittests/mlu/test_truncated_gaussian_random_op_mlu.py b/python/paddle/fluid/tests/unittests/mlu/test_truncated_gaussian_random_op_mlu.py new file mode 100644 index 00000000000..e1752029ef9 --- /dev/null +++ b/python/paddle/fluid/tests/unittests/mlu/test_truncated_gaussian_random_op_mlu.py @@ -0,0 +1,91 @@ +# 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 + +import paddle +import paddle.fluid as fluid +import paddle.fluid.core as core +import sys + +sys.path.append("..") +from op_test import OpTest +from paddle.fluid.op import Operator +from paddle.fluid.executor import Executor +from paddle.fluid.framework import _test_eager_guard + +paddle.enable_static() + + +class TestTrunctedGaussianRandomOp(unittest.TestCase): + + def setUp(self): + self.op_type = "truncated_gaussian_random" + self.inputs = {} + self.attrs = { + "shape": [10000], + "mean": .0, + "std": 1., + "seed": 10, + } + self.outputs = ["Out"] + + def test_cpu(self): + self.gaussian_random_test(place=fluid.CPUPlace()) + self.gaussian_random_test_eager(place=fluid.CPUPlace()) + + def test_mlu(self): + if core.is_compiled_with_mlu(): + self.gaussian_random_test(place=fluid.MLUPlace(0)) + # self.gaussian_random_test_eager(place=fluid.MLUPlace(0)) + + def gaussian_random_test(self, place): + + program = fluid.Program() + block = program.global_block() + vout = block.create_var(name="Out") + op = block.append_op(type=self.op_type, + outputs={"Out": vout}, + attrs=self.attrs) + + op.desc.infer_var_type(block.desc) + op.desc.infer_shape(block.desc) + + fetch_list = [] + for var_name in self.outputs: + fetch_list.append(block.var(var_name)) + + exe = Executor(place) + outs = exe.run(program, fetch_list=fetch_list) + tensor = outs[0] + self.assertAlmostEqual(numpy.mean(tensor), .0, delta=0.1) + self.assertAlmostEqual(numpy.var(tensor), 0.773, delta=0.1) + + # TruncatedNormal.__call__ has no return value, so here call _C_ops api + # directly + def gaussian_random_test_eager(self, place): + with fluid.dygraph.guard(place): + with _test_eager_guard(): + out = paddle._C_ops.final_state_truncated_gaussian_random( + self.attrs["shape"], self.attrs["mean"], self.attrs["std"], + self.attrs["seed"], core.VarDesc.VarType.FP32, place) + self.assertAlmostEqual(numpy.mean(out.numpy()), .0, delta=0.1) + self.assertAlmostEqual(numpy.var(out.numpy()), 0.773, delta=0.1) + + +if __name__ == "__main__": + unittest.main() -- GitLab