From 74ce03974337666d2c04f084087661c801b1ec8a Mon Sep 17 00:00:00 2001 From: pangyoki Date: Mon, 19 Oct 2020 10:41:38 +0800 Subject: [PATCH] Add uniform_random XPU kernel (#27846) * support uniform_random op on Baidu Kunlun * change dtype of attr shape from int to int64_t * kunlun ci, test=kunlun * new version, test=kunlun * change boost_get to BOOST_GET_CONST * change boost_get to BOOST_GET_CONST, test=kunlun * use Generator to generate random number and optimize format * run Kunlun CI, test=kunlun * add TODO, test=kunlun --- .../fluid/operators/uniform_random_op_xpu.cc | 75 +++++++++++++++++++ .../xpu/test_uniform_random_op_xpu.py | 51 +++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 paddle/fluid/operators/uniform_random_op_xpu.cc create mode 100644 python/paddle/fluid/tests/unittests/xpu/test_uniform_random_op_xpu.py diff --git a/paddle/fluid/operators/uniform_random_op_xpu.cc b/paddle/fluid/operators/uniform_random_op_xpu.cc new file mode 100644 index 0000000000..507bd7e9ea --- /dev/null +++ b/paddle/fluid/operators/uniform_random_op_xpu.cc @@ -0,0 +1,75 @@ +/* Copyright (c) 2020 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_XPU + +#include "paddle/fluid/operators/uniform_random_op.h" +#include +#include "paddle/fluid/framework/generator.h" +#include "paddle/fluid/framework/op_registry.h" +#include "paddle/fluid/framework/operator.h" + +namespace paddle { +namespace operators { + +template +class XPUUniformRandomKernel : public framework::OpKernel { + public: + void Compute(const framework::ExecutionContext &ctx) const override { + framework::Tensor *tensor = nullptr; + auto out_var = ctx.OutputVar("Out"); + if (out_var->IsType()) { + tensor = out_var->GetMutable(); + } else if (out_var->IsType()) { + auto shape = ctx.Attr>("shape"); + auto *selected_rows = out_var->GetMutable(); + tensor = selected_rows->mutable_value(); + tensor->Resize(framework::make_ddim(shape)); + selected_rows->mutable_rows()->reserve(shape[0]); + } else { + PADDLE_THROW(platform::errors::InvalidArgument( + "Expected type of Output(out) in uniform_random_op must be " + "LoDTensor, " + "SelectedRows. But got unsupport type: %s.", + framework::ToTypeName(out_var->Type()))); + } + T *data = tensor->mutable_data(ctx.GetPlace()); + + int64_t size = tensor->numel(); + std::uniform_real_distribution dist( + static_cast(ctx.Attr("min")), + static_cast(ctx.Attr("max"))); + unsigned int seed = static_cast(ctx.Attr("seed")); + // TODO(pangyoki): implement GetXPURandomEngine to set different seeds on + // corresponding XPU device. + auto engine = framework::GetCPURandomEngine(seed); + + std::unique_ptr data_cpu(new T[size]); + for (int64_t i = 0; i < size; ++i) { + data_cpu[i] = dist(*engine); + } + + memory::Copy(BOOST_GET_CONST(platform::XPUPlace, ctx.GetPlace()), data, + platform::CPUPlace(), reinterpret_cast(data_cpu.get()), + size * sizeof(T)); + } +}; + +} // namespace operators +} // namespace paddle + +REGISTER_OP_XPU_KERNEL(uniform_random, + paddle::operators::XPUUniformRandomKernel); + +#endif // PADDLE_WITH_XPU diff --git a/python/paddle/fluid/tests/unittests/xpu/test_uniform_random_op_xpu.py b/python/paddle/fluid/tests/unittests/xpu/test_uniform_random_op_xpu.py new file mode 100644 index 0000000000..ab59fd2665 --- /dev/null +++ b/python/paddle/fluid/tests/unittests/xpu/test_uniform_random_op_xpu.py @@ -0,0 +1,51 @@ +# Copyright (c) 2020 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 sys +sys.path.append("..") +import subprocess +import unittest +import numpy as np +from op_test import OpTest +import paddle +import paddle.fluid.core as core +from paddle.fluid.op import Operator +import paddle.fluid as fluid +from paddle.fluid import Program, program_guard +from test_uniform_random_op import TestUniformRandomOp, TestUniformRandomOpSelectedRows + +paddle.enable_static() + + +class TestXPUUniformRandomOp(TestUniformRandomOp): + def test_check_output(self): + if paddle.is_compiled_with_xpu(): + place = paddle.XPUPlace(0) + outs = self.calc_output(place) + outs = [np.array(out) for out in outs] + outs.sort(key=len) + self.verify_output(outs) + + +class TestXPUUniformRandomOpSelectedRows(TestUniformRandomOpSelectedRows): + def test_check_output(self): + if paddle.is_compiled_with_xpu(): + place = paddle.XPUPlace(0) + self.check_with_place(place) + + +if __name__ == "__main__": + unittest.main() -- GitLab