From 72fb86a284bd28ebbc83cd3d224a6df2f9a14b7c Mon Sep 17 00:00:00 2001 From: dongzhihong Date: Mon, 7 Aug 2017 15:50:11 +0800 Subject: [PATCH] "remove type alias done." --- paddle/framework/backward.cc | 1 + paddle/framework/backward_test.cc | 14 +- paddle/framework/pybind.cc | 35 ++-- paddle/operators/add_op_test.cc | 3 +- paddle/operators/fill_zeros_like_op.cc | 8 +- paddle/operators/fill_zeros_like_op.cu | 4 +- paddle/operators/fill_zeros_like_op.h | 3 +- paddle/operators/net_op_test.cc | 19 +-- paddle/pybind/pybind.cc | 220 +++++++++++++++++++++++++ 9 files changed, 266 insertions(+), 41 deletions(-) create mode 100644 paddle/pybind/pybind.cc diff --git a/paddle/framework/backward.cc b/paddle/framework/backward.cc index 13706f8b56..47983110fa 100644 --- a/paddle/framework/backward.cc +++ b/paddle/framework/backward.cc @@ -13,6 +13,7 @@ limitations under the License. */ #include "paddle/framework/backward.h" + #include #include "paddle/framework/op_registry.h" #include "paddle/operators/net_op.h" diff --git a/paddle/framework/backward_test.cc b/paddle/framework/backward_test.cc index 6c6e12ca25..6d5835bd22 100644 --- a/paddle/framework/backward_test.cc +++ b/paddle/framework/backward_test.cc @@ -17,16 +17,21 @@ #include #include "paddle/framework/op_registry.h" #include "paddle/operators/net_op.h" -#include "paddle/operators/type_alias.h" namespace paddle { namespace framework { +using OperatorBase = framework::OperatorBase; +using OpProtoAndCheckerMaker = framework::OpProtoAndCheckerMaker; +using OpProto = framework::OpProto; +using OpAttrChecker = framework::OpAttrChecker; +using Scope = framework::Scope; +using DeviceContext = platform::DeviceContext; + class EmptyOp : public OperatorBase { public: void InferShape(const Scope &scope) const override {} - void Run(const Scope &scope, - const platform::DeviceContext &dev_ctx) const override {} + void Run(const Scope &scope, const DeviceContext &dev_ctx) const override {} }; class RowWiseAddOpMaker : public OpProtoAndCheckerMaker { @@ -71,7 +76,7 @@ class NoGradOpMaker : public OpProtoAndCheckerMaker { } }; -class FcOp : public ops::NetOp { +class FcOp : public operators::NetOp { public: void Init() override { AddOp(OpRegistry::CreateOp("mul", {Input("X"), Input("W")}, @@ -143,6 +148,7 @@ class AddOpMaker : public OpProtoAndCheckerMaker { } // namespace paddle namespace f = paddle::framework; +namespace ops = paddle::operators; using EnforceNotMet = paddle::platform::EnforceNotMet; REGISTER_OP(rowwise_add, f::EmptyOp, f::RowWiseAddOpMaker); REGISTER_GRADIENT_OP(rowwise_add, rowwise_add_grad, f::EmptyOp); diff --git a/paddle/framework/pybind.cc b/paddle/framework/pybind.cc index cbb86c4195..e63e500c1d 100644 --- a/paddle/framework/pybind.cc +++ b/paddle/framework/pybind.cc @@ -18,11 +18,8 @@ limitations under the License. */ #include "paddle/framework/backward.h" #include "paddle/framework/op_registry.h" -#include "paddle/framework/operator.h" -#include "paddle/framework/scope.h" #include "paddle/framework/tensor_py.h" #include "paddle/operators/net_op.h" -#include "paddle/operators/type_alias.h" #include "paddle/platform/enforce.h" #include "paddle/platform/place.h" #include "pybind11/numpy.h" @@ -43,6 +40,9 @@ USE_OP(rowwise_add); USE_OP_WITHOUT_KERNEL(recurrent_op); namespace paddle { namespace framework { + +using Tensor = framework::Tensor; + template void ExposeOperator(ClassType &m) { m.def("infer_shape", &ClassType::type::InferShape) @@ -128,8 +128,8 @@ All parameter, weight, gradient are variables in Paddle. [](Variable &self) -> Tensor * { return self.GetMutable(); }, py::return_value_policy::reference) .def("get_net", - [](Variable &self) -> ops::NetOp * { - return self.GetMutable(); + [](Variable &self) -> operators::NetOp * { + return self.GetMutable(); }, py::return_value_policy::reference); @@ -208,23 +208,24 @@ All parameter, weight, gradient are variables in Paddle. ExposeOperator(operator_base); - py::class_> net(m, "Net"); + py::class_> net(m, "Net"); net.def_static("create", - []() -> std::shared_ptr { - auto retv = std::make_shared(); + []() -> std::shared_ptr { + auto retv = std::make_shared(); retv->type_ = "plain_net"; return retv; }) - .def("add_op", &ops::NetOp::AddOp) - .def( - "add_op", - [](ops::NetOp &self, const std::shared_ptr &net) -> void { - self.AddOp(std::static_pointer_cast(net)); - }) - .def("complete_add_op", &ops::NetOp::CompleteAddOp) - .def("complete_add_op", - [](std::shared_ptr &self) { self->CompleteAddOp(); }); + .def("add_op", &operators::NetOp::AddOp) + .def("add_op", + [](operators::NetOp &self, + const std::shared_ptr &net) -> void { + self.AddOp(std::static_pointer_cast(net)); + }) + .def("complete_add_op", &operators::NetOp::CompleteAddOp) + .def("complete_add_op", [](std::shared_ptr &self) { + self->CompleteAddOp(); + }); ExposeOperator(net); diff --git a/paddle/operators/add_op_test.cc b/paddle/operators/add_op_test.cc index 3d52f54983..4f33f46bb2 100644 --- a/paddle/operators/add_op_test.cc +++ b/paddle/operators/add_op_test.cc @@ -14,7 +14,8 @@ limitations under the License. */ #include #define private public -#include +#include "paddle/framework/op_registry.h" + USE_OP(add_two); // USE_OP(add_two_grad); diff --git a/paddle/operators/fill_zeros_like_op.cc b/paddle/operators/fill_zeros_like_op.cc index 3d37d64c5a..f6f1b1442e 100644 --- a/paddle/operators/fill_zeros_like_op.cc +++ b/paddle/operators/fill_zeros_like_op.cc @@ -13,8 +13,6 @@ See the License for the specific language governing permissions and limitations under the License. */ #include "paddle/operators/fill_zeros_like_op.h" -#include "paddle/framework/op_registry.h" -#include "paddle/framework/tensor.h" namespace paddle { namespace operators { @@ -52,8 +50,8 @@ The output will have the same size with input. } // namespace operators } // namespace paddle -REGISTER_OP(fill_zeros_like, paddle::operators::FillZerosLikeOp, - paddle::operators::FillZerosLikeOpMaker); +namespace ops = paddle::operators; +REGISTER_OP(fill_zeros_like, ops::FillZerosLikeOp, ops::FillZerosLikeOpMaker); REGISTER_OP_CPU_KERNEL( fill_zeros_like, - paddle::operators::FillZerosLikeKernel); + ops::FillZerosLikeKernel); diff --git a/paddle/operators/fill_zeros_like_op.cu b/paddle/operators/fill_zeros_like_op.cu index ed1068219c..0542dc7b4d 100644 --- a/paddle/operators/fill_zeros_like_op.cu +++ b/paddle/operators/fill_zeros_like_op.cu @@ -12,9 +12,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -#include "paddle/framework/op_registry.h" #include "paddle/operators/fill_zeros_like_op.h" +namespace ops = paddle::operators; REGISTER_OP_GPU_KERNEL( fill_zeros_like, - paddle::operators::FillZerosLikeKernel); + ops::FillZerosLikeKernel); diff --git a/paddle/operators/fill_zeros_like_op.h b/paddle/operators/fill_zeros_like_op.h index 4bff1fbfc1..4a572e5b1a 100644 --- a/paddle/operators/fill_zeros_like_op.h +++ b/paddle/operators/fill_zeros_like_op.h @@ -13,9 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. */ #pragma once -#include "glog/logging.h" #include "paddle/framework/eigen.h" -#include "paddle/framework/operator.h" +#include "paddle/framework/op_registry.h" namespace paddle { namespace operators { diff --git a/paddle/operators/net_op_test.cc b/paddle/operators/net_op_test.cc index f823f36234..76bf79f9b5 100644 --- a/paddle/operators/net_op_test.cc +++ b/paddle/operators/net_op_test.cc @@ -4,26 +4,25 @@ namespace paddle { namespace operators { +using Scope = framework::Scope; +using DeviceContext = platform::DeviceContext; static int infer_shape_cnt = 0; static int run_cnt = 0; -class TestOp : public OperatorBase { +class TestOp : public framework::OperatorBase { public: - void InferShape(const framework::Scope& scope) const override { - ++infer_shape_cnt; - } - void Run(const framework::Scope& scope, - const paddle::platform::DeviceContext& dev_ctx) const override { + void InferShape(const Scope& scope) const override { ++infer_shape_cnt; } + void Run(const Scope& scope, + const platform::DeviceContext& dev_ctx) const override { ++run_cnt; } }; -class EmptyOp : public OperatorBase { +class EmptyOp : public framework::OperatorBase { public: void InferShape(const Scope& scope) const override {} - void Run(const Scope& scope, - const platform::DeviceContext& dev_ctx) const override {} + void Run(const Scope& scope, const DeviceContext& dev_ctx) const override {} }; template @@ -69,7 +68,7 @@ TEST(OpKernel, all) { net->Run(scope, dev_ctx); ASSERT_EQ(2, infer_shape_cnt); ASSERT_EQ(2, run_cnt); - ASSERT_THROW(net->AddOp(op2), paddle::platform::EnforceNotMet); + ASSERT_THROW(net->AddOp(op2), platform::EnforceNotMet); } TEST(NetOp, insert_op) { diff --git a/paddle/pybind/pybind.cc b/paddle/pybind/pybind.cc new file mode 100644 index 0000000000..d3cde07bd0 --- /dev/null +++ b/paddle/pybind/pybind.cc @@ -0,0 +1,220 @@ +/* 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. */ + +#include +#include +#include + +#include "paddle/framework/net.h" +#include "paddle/framework/op_registry.h" +#include "paddle/framework/operator.h" +#include "paddle/framework/scope.h" +#include "paddle/platform/enforce.h" +#include "paddle/platform/place.h" +#include "paddle/pybind/tensor_bind.h" +#include "pybind11/numpy.h" +#include "pybind11/pybind11.h" +#include "pybind11/stl.h" + +namespace py = pybind11; +namespace pd = paddle::framework; + +USE_OP(add_two); +USE_OP(onehot_cross_entropy); +USE_OP_WITHOUT_KERNEL(fc); +USE_OP(sgd); +USE_OP(mul); +USE_OP(mean); +USE_OP(sigmoid); +USE_OP(softmax); +USE_OP(rowwise_add); +USE_OP_WITHOUT_KERNEL(recurrent_op); + +template +void ExposeOperator(ClassType& m) { + m.def("infer_shape", &ClassType::type::InferShape) + .def("run", &ClassType::type::Run) + .def("outputs", + [](const typename ClassType::type& op) -> std::vector { + return op.outputs_; + }) + .def("__str__", &ClassType::type::DebugString); +} + +static size_t UniqueIntegerGenerator() { + static std::atomic generator; + return generator.fetch_add(1); +} + +bool IsCompileGPU() { +#ifdef PADDLE_ONLY_CPU + return false; +#else + return true; +#endif +} + +PYBIND11_PLUGIN(core) { + py::module m("core", "C++ core of PaddlePaddle"); + + py::class_(m, "Tensor", py::buffer_protocol()) + .def_buffer([](pd::Tensor& self) -> py::buffer_info { + return paddle::pybind::CastToPyBuffer(self); + }) + .def("get_dims", + [](const pd::Tensor& self) { return pd::vectorize(self.dims()); }) + .def("set_dims", + [](pd::Tensor& self, const std::vector& dim) { + self.Resize(pd::make_ddim(dim)); + }) + .def("alloc_float", + [](pd::Tensor& self, paddle::platform::GPUPlace& place) { + self.mutable_data(place); + }) + .def("alloc_float", + [](pd::Tensor& self, paddle::platform::CPUPlace& place) { + self.mutable_data(place); + }) + .def("alloc_int", + [](pd::Tensor& self, paddle::platform::CPUPlace& place) { + self.mutable_data(place); + }) + .def("alloc_int", + [](pd::Tensor& self, paddle::platform::GPUPlace& place) { + self.mutable_data(place); + }) + .def("set", paddle::pybind::PyCPUTensorSetFromArray) + .def("set", paddle::pybind::PyCPUTensorSetFromArray) +#ifndef PADDLE_ONLY_CPU + .def("set", paddle::pybind::PyCUDATensorSetFromArray) + .def("set", paddle::pybind::PyCUDATensorSetFromArray) +#endif + .def("shape", + [](pd::Tensor& self) { return pd::vectorize(self.dims()); }); + + py::class_(m, "Variable", R"DOC(Variable Class. + +All parameter, weight, gradient are variables in Paddle. +)DOC") + .def("is_int", [](const pd::Variable& var) { return var.IsType(); }) + .def("set_int", + [](pd::Variable& var, int val) -> void { + *var.GetMutable() = val; + }) + .def("get_int", + [](const pd::Variable& var) -> int { return var.Get(); }) + .def("get_tensor", + [](pd::Variable& self) -> pd::Tensor* { + return self.GetMutable(); + }, + py::return_value_policy::reference) + .def("get_net", + [](pd::Variable& self) -> pd::NetOp* { + return self.GetMutable(); + }, + py::return_value_policy::reference); + + py::class_(m, "Scope", "") + .def("new_var", + [](pd::Scope& self, const std::string& name) -> pd::Variable* { + return self.NewVar(name); + }, + py::return_value_policy::reference) + .def("find_var", &pd::Scope::FindVar, py::return_value_policy::reference) + .def(py::init<>()) + .def("new_scope", + [](pd::Scope& self) -> pd::Scope* { return &self.NewScope(); }, + py::return_value_policy::reference) + .def("drop_kids", &pd::Scope::DropKids); + + //! @note: Be careful! PyBind will return std::string as an unicode, not + //! Python str. If you want a str object, you should cast them in Python. + m.def("get_all_op_protos", []() -> std::vector { + auto& protos = pd::OpRegistry::protos(); + std::vector ret_values; + for (auto it = protos.begin(); it != protos.end(); ++it) { + PADDLE_ENFORCE(it->second.IsInitialized(), + "OpProto must all be initialized"); + std::string str; + PADDLE_ENFORCE(it->second.SerializeToString(&str), + "Serialize OpProto Error. This could be a bug of Paddle."); + ret_values.push_back(py::bytes(str)); + } + return ret_values; + }); + m.def_submodule( + "var_names", + "The module will return special predefined variable name in Paddle") + .def("empty", pd::OperatorBase::EMPTY_VAR_NAME) + .def("temp", pd::OperatorBase::TMP_VAR_NAME); + // clang-format off + py::class_(m, "DeviceContext") + .def_static("create", + [](paddle::platform::CPUPlace& place) + -> paddle::platform::DeviceContext* { + return new paddle::platform::CPUDeviceContext(); + }) + .def_static("create", + [](paddle::platform::GPUPlace& place) + -> paddle::platform::DeviceContext* { +#ifdef PADDLE_ONLY_CPU + PADDLE_THROW("GPUPlace is not supported in CPU device."); +#else + return new paddle::platform::CUDADeviceContext(place); +#endif + }); + // clang-format on + + py::class_(m, "GPUPlace").def(py::init()); + + py::class_(m, "CPUPlace").def(py::init<>()); + + py::class_> operator_base( + m, "Operator"); + + operator_base.def_static("create", [](py::bytes protobin) { + pd::OpDesc desc; + PADDLE_ENFORCE(desc.ParsePartialFromString(protobin), + "Cannot parse user input to OpDesc"); + PADDLE_ENFORCE(desc.IsInitialized(), + "User OpDesc is not initialized, reason %s", + desc.InitializationErrorString()); + return pd::OpRegistry::CreateOp(desc); + }); + ExposeOperator(operator_base); + + py::class_> net(m, "Net"); + + net.def_static("create", + []() -> std::shared_ptr { + auto retv = std::make_shared(); + retv->type_ = "plain_net"; + return retv; + }) + .def("add_op", &pd::NetOp::AddOp) + .def("add_op", + [](pd::NetOp& self, const std::shared_ptr& net) -> void { + self.AddOp(std::static_pointer_cast(net)); + }) + .def("complete_add_op", &pd::NetOp::CompleteAddOp) + .def("complete_add_op", + [](std::shared_ptr& self) { self->CompleteAddOp(); }); + ExposeOperator(net); + + m.def("unique_integer", UniqueIntegerGenerator); + + m.def("is_compile_gpu", IsCompileGPU); + + return m.ptr(); +} -- GitLab