diff --git a/paddle/operators/uniform_random_op.cc b/paddle/operators/uniform_random_op.cc index dec188f2a814f34c1643658e801cb93bad359a7b..877bcb9d4f8d9c525d691fd96242dd3dd58a81b2 100644 --- a/paddle/operators/uniform_random_op.cc +++ b/paddle/operators/uniform_random_op.cc @@ -12,25 +12,55 @@ See the License for the specific language governing permissions and limitations under the License. */ -#include "paddle/operators/uniform_random_op.h" +#include +#include +#include "paddle/framework/op_registry.h" +#include "paddle/framework/operator.h" namespace paddle { namespace operators { -class RandomOp : public OperatorWithKernel { + +// It seems that Eigen::Tensor::random in GPU will SEGFAULT. +// Use std::random and thrust::random(thrust is a std library in CUDA) to +// implement uniform random. +template +class CPUUniformRandomKernel : public framework::OpKernel { + public: + void Compute(const framework::ExecutionContext& context) const override { + auto* tensor = context.Output(0); + T* data = tensor->mutable_data(context.GetPlace()); + unsigned int seed = + static_cast(context.op_.GetAttr("seed")); + std::minstd_rand engine; + if (seed == 0) { + seed = std::random_device()(); + } + engine.seed(seed); + std::uniform_real_distribution dist( + static_cast(context.op_.GetAttr("min")), + static_cast(context.op_.GetAttr("max"))); + for (ssize_t i = 0; i < framework::product(tensor->dims()); ++i) { + data[i] = dist(engine); + } + } +}; + +class UniformRandomOp : public framework::OperatorWithKernel { protected: - void InferShape(const InferShapeContext &ctx) const override { + void InferShape(const framework::InferShapeContext& ctx) const override { PADDLE_ENFORCE(GetAttr("min") < GetAttr("max"), "uniform_random's min must less then max"); - auto tensor = ctx.Output(0); + auto tensor = ctx.Output(0); auto dims = GetAttr>("dims"); tensor->Resize(framework::make_ddim(dims)); } }; -class RandomOpMaker : public OpProtoAndCheckerMaker { +class UniformRandomOpMaker : public framework::OpProtoAndCheckerMaker { public: - RandomOpMaker(OpProto *proto, OpAttrChecker *op_checker) - : OpProtoAndCheckerMaker(proto, op_checker) { + UniformRandomOpMaker(framework::OpProto* proto, + framework::OpAttrChecker* op_checker) + : framework::OpProtoAndCheckerMaker(proto, op_checker) { AddOutput("Out", "The output tensor of uniform random op"); AddComment(R"DOC(Uniform random operator. @@ -48,5 +78,7 @@ Used to initialize tensor with uniform random generator. } // namespace operators } // namespace paddle -REGISTER_OP(uniform_random, ops::RandomOp, ops::RandomOpMaker); -REGISTER_OP_CPU_KERNEL(uniform_random, ops::CPUUniformRandomKernel); +REGISTER_OP(uniform_random, paddle::operators::UniformRandomOp, + paddle::operators::UniformRandomOpMaker); +REGISTER_OP_CPU_KERNEL(uniform_random, + paddle::operators::CPUUniformRandomKernel); diff --git a/paddle/operators/uniform_random_op.cu b/paddle/operators/uniform_random_op.cu index 89a274ae26cff32a788da6e422c66ee9762b9d47..f1a63e52ec0d3d46a505a89d7d7916bf93a58221 100644 --- a/paddle/operators/uniform_random_op.cu +++ b/paddle/operators/uniform_random_op.cu @@ -16,7 +16,8 @@ #include #include #include -#include "paddle/operators/type_alias.h" +#include "paddle/framework/op_registry.h" +#include "paddle/framework/operator.h" namespace paddle { namespace operators { @@ -38,11 +39,14 @@ struct UniformGenerator { } }; +// It seems that Eigen::Tensor::random in GPU will SEGFAULT. +// Use std::random and thrust::random(thrust is a std library in CUDA) to +// implement uniform random. template -class GPUUniformRandomKernel : public OpKernel { +class GPUUniformRandomKernel : public framework::OpKernel { public: - void Compute(const ExecutionContext& context) const override { - auto* tensor = context.Output(0); + void Compute(const framework::ExecutionContext& context) const override { + auto* tensor = context.Output(0); T* data = tensor->mutable_data(context.GetPlace()); unsigned int seed = static_cast(context.op_.GetAttr("seed")); @@ -62,4 +66,5 @@ class GPUUniformRandomKernel : public OpKernel { } // namespace operators } // namespace paddle -REGISTER_OP_GPU_KERNEL(uniform_random, ops::GPUUniformRandomKernel); +REGISTER_OP_GPU_KERNEL(uniform_random, + paddle::operators::GPUUniformRandomKernel); diff --git a/paddle/operators/uniform_random_op.h b/paddle/operators/uniform_random_op.h deleted file mode 100644 index e86771b444a3c582aeae24ec8c6e7a93a7de9076..0000000000000000000000000000000000000000 --- a/paddle/operators/uniform_random_op.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve. - - 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. */ - -#pragma once -#include -#include -#include "paddle/operators/type_alias.h" -namespace paddle { -namespace operators { - -template -class CPUUniformRandomKernel : public OpKernel { - public: - void Compute(const ExecutionContext& context) const override { - auto* tensor = context.Output(0); - T* data = tensor->mutable_data(context.GetPlace()); - unsigned int seed = - static_cast(context.op_.GetAttr("seed")); - std::minstd_rand engine; - if (seed == 0) { - seed = std::random_device()(); - } - engine.seed(seed); - std::uniform_real_distribution dist(static_cast(context.op_.GetAttr("min")), - static_cast(context.op_.GetAttr("max"))); - for (ssize_t i = 0; i < framework::product(tensor->dims()); ++i) { - data[i] = dist(engine); - } - } -}; - -} // namespace operators -} // namespace paddle