From 8c2379732257f6d6bdf8fbe9157afea51a364942 Mon Sep 17 00:00:00 2001 From: Aurelius84 Date: Tue, 1 Mar 2022 10:59:51 +0800 Subject: [PATCH] [Phi] Migrate logical_and/or/not/xor into Phi (#39942) * [Phi] Migrate logical_and/or/not/xor into Phi * fix unittest * fix function name --- .../operators/controlflow/CMakeLists.txt | 2 +- .../fluid/operators/controlflow/logical_op.cc | 10 +- .../fluid/operators/controlflow/logical_op.cu | 69 ----------- .../fluid/operators/controlflow/logical_op.h | 111 ------------------ .../operators/controlflow/logical_op_npu.cc | 2 +- paddle/phi/kernels/cpu/logical_kernel.cc | 72 ++++++++++++ paddle/phi/kernels/funcs/logical_functor.h | 41 +++++++ paddle/phi/kernels/gpu/logical_kernel.cu | 79 +++++++++++++ paddle/phi/kernels/logical_kernel.h | 38 ++++++ .../fluid/tests/unittests/test_diff_op.py | 2 +- 10 files changed, 234 insertions(+), 192 deletions(-) delete mode 100644 paddle/fluid/operators/controlflow/logical_op.cu delete mode 100644 paddle/fluid/operators/controlflow/logical_op.h create mode 100644 paddle/phi/kernels/cpu/logical_kernel.cc create mode 100644 paddle/phi/kernels/funcs/logical_functor.h create mode 100644 paddle/phi/kernels/gpu/logical_kernel.cu create mode 100644 paddle/phi/kernels/logical_kernel.h diff --git a/paddle/fluid/operators/controlflow/CMakeLists.txt b/paddle/fluid/operators/controlflow/CMakeLists.txt index 1a2df2a0c7..a974f2ec33 100644 --- a/paddle/fluid/operators/controlflow/CMakeLists.txt +++ b/paddle/fluid/operators/controlflow/CMakeLists.txt @@ -20,5 +20,5 @@ else() endif() file(APPEND ${pybind_file} "USE_OP(less_than);\nUSE_OP(equal_all);\nUSE_NO_KERNEL_OP(read_from_array);\n") -file(APPEND ${pybind_file} "USE_OP(logical_and);\nUSE_OP(logical_or);\nUSE_OP(logical_xor);\nUSE_OP(logical_not);\n") +file(APPEND ${pybind_file} "USE_OP_ITSELF(logical_and);\nUSE_OP_ITSELF(logical_or);\nUSE_OP_ITSELF(logical_xor);\nUSE_OP_ITSELF(logical_not);\n") file(APPEND ${pybind_file} "USE_OP(bitwise_and);\nUSE_OP(bitwise_or);\nUSE_OP(bitwise_xor);\nUSE_OP(bitwise_not);\n") diff --git a/paddle/fluid/operators/controlflow/logical_op.cc b/paddle/fluid/operators/controlflow/logical_op.cc index a4262d4054..4d11cb5ff7 100644 --- a/paddle/fluid/operators/controlflow/logical_op.cc +++ b/paddle/fluid/operators/controlflow/logical_op.cc @@ -9,11 +9,11 @@ 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 "paddle/fluid/operators/controlflow/logical_op.h" #include #include #include #include "paddle/fluid/framework/op_registry.h" +#include "paddle/fluid/operators/elementwise/elementwise_op_function.h" namespace paddle { namespace operators { @@ -145,15 +145,7 @@ class BinaryLogicalOp : public LogicalOp { ::paddle::framework::EmptyGradOpMaker); REGISTER_BINARY_LOGICAL_OP(logical_and, "$$Out = X \\&\\& Y$$"); -REGISTER_BINARY_LOGICAL_KERNEL(logical_and, CPU, - paddle::operators::LogicalAndFunctor); REGISTER_BINARY_LOGICAL_OP(logical_or, "$$Out = X || Y$$"); -REGISTER_BINARY_LOGICAL_KERNEL(logical_or, CPU, - paddle::operators::LogicalOrFunctor); REGISTER_UNARY_LOGICAL_OP(logical_not, "$$Out = !X$$"); -REGISTER_UNARY_LOGICAL_KERNEL(logical_not, CPU, - paddle::operators::LogicalNotFunctor); REGISTER_BINARY_LOGICAL_OP(logical_xor, "$$Out = (X || Y) \\&\\& !(X \\&\\& Y)$$"); -REGISTER_BINARY_LOGICAL_KERNEL(logical_xor, CPU, - paddle::operators::LogicalXorFunctor); diff --git a/paddle/fluid/operators/controlflow/logical_op.cu b/paddle/fluid/operators/controlflow/logical_op.cu deleted file mode 100644 index d88658607e..0000000000 --- a/paddle/fluid/operators/controlflow/logical_op.cu +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2016 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 "paddle/fluid/operators/controlflow/logical_op.h" -#include "paddle/fluid/operators/elementwise/elementwise_op_broadcast.cu.h" - -namespace paddle { -namespace operators { - -template -class BinaryLogicalOpKernel - : public framework::OpKernel { - public: - void Compute(const framework::ExecutionContext& ctx) const override { - using InT = typename Functor::ELEMENT_TYPE; - using OutT = bool; - - auto functor = Functor(); - std::vector ins; - std::vector outs; - const auto& cuda_ctx = - ctx.template device_context(); - int axis = PackTensorsIntoVector(ctx, &ins, &outs); - - if (ins.size() == 1) { - paddle::operators::LaunchElementwiseCudaKernel( - cuda_ctx, ins, &outs, axis, functor); - } else { - paddle::operators::LaunchElementwiseCudaKernel( - cuda_ctx, ins, &outs, axis, functor); - } - } -}; - -} // namespace operators -} // namespace paddle - -namespace ops = paddle::operators; -namespace plat = paddle::platform; - -#define REGISTER_LOGICAL_CUDA_KERNEL(op_name, func) \ - REGISTER_OP_CUDA_KERNEL( \ - op_name, \ - ops::BinaryLogicalOpKernel>, \ - ops::BinaryLogicalOpKernel>, \ - ops::BinaryLogicalOpKernel>, \ - ops::BinaryLogicalOpKernel>, \ - ops::BinaryLogicalOpKernel>, \ - ops::BinaryLogicalOpKernel>, \ - ops::BinaryLogicalOpKernel>); - -REGISTER_LOGICAL_CUDA_KERNEL(logical_or, LogicalOrFunctor) -REGISTER_LOGICAL_CUDA_KERNEL(logical_and, LogicalAndFunctor) -REGISTER_LOGICAL_CUDA_KERNEL(logical_xor, LogicalXorFunctor) -REGISTER_LOGICAL_CUDA_KERNEL(logical_not, LogicalNotFunctor) -#undef REGISTER_LOGICAL_CUDA_KERNEL diff --git a/paddle/fluid/operators/controlflow/logical_op.h b/paddle/fluid/operators/controlflow/logical_op.h deleted file mode 100644 index 15cd643a85..0000000000 --- a/paddle/fluid/operators/controlflow/logical_op.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (c) 2016 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. */ - -#pragma once -#include -#include -#include "paddle/fluid/framework/op_registry.h" -#include "paddle/fluid/operators/elementwise/elementwise_op_function.h" -#include "paddle/fluid/platform/transform.h" - -namespace paddle { -namespace operators { - -#define LOGICAL_BINARY_FUNCTOR(func_name, op) \ - template \ - struct func_name { \ - using ELEMENT_TYPE = T; \ - HOSTDEVICE bool operator()(const T a, const T b) const { \ - return static_cast(a) op static_cast(b); \ - } \ - }; - -LOGICAL_BINARY_FUNCTOR(LogicalOrFunctor, ||) -LOGICAL_BINARY_FUNCTOR(LogicalAndFunctor, &&) -LOGICAL_BINARY_FUNCTOR(LogicalXorFunctor, ^) -#undef LOGICAL_BINARY_FUNCTOR - -template -struct LogicalNotFunctor { - using ELEMENT_TYPE = T; - HOSTDEVICE bool operator()(const T a) const { return !a; } -}; - -template -class BinaryLogicalOpKernel - : public framework::OpKernel { - public: - void Compute(const framework::ExecutionContext& context) const override { - using T = typename Functor::ELEMENT_TYPE; - auto* x = context.Input("X"); - auto* y = context.Input("Y"); - auto* out = context.Output("Out"); - Functor binary_func; - ElementwiseComputeEx(context, x, y, -1, - binary_func, out); - } -}; - -template -class UnaryLogicalOpKernel - : public framework::OpKernel { - public: - void Compute(const framework::ExecutionContext& context) const override { - using T = typename Functor::ELEMENT_TYPE; - auto* x = context.Input("X"); - auto* out = context.Output("Out"); - Functor unary_func; - platform::Transform trans; - trans(context.template device_context(), x->data(), - x->data() + x->numel(), - out->mutable_data(context.GetPlace()), unary_func); - } -}; - -} // namespace operators -} // namespace paddle - -#define REGISTER_BINARY_LOGICAL_KERNEL(op_type, dev, functor) \ - REGISTER_OP_##dev##_KERNEL( \ - op_type, ::paddle::operators::BinaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::BinaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::BinaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::BinaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::BinaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::BinaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::BinaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>); - -#define REGISTER_UNARY_LOGICAL_KERNEL(op_type, dev, functor) \ - REGISTER_OP_##dev##_KERNEL( \ - op_type, ::paddle::operators::UnaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::UnaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::UnaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::UnaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::UnaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::UnaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>, \ - ::paddle::operators::UnaryLogicalOpKernel< \ - ::paddle::platform::dev##DeviceContext, functor>); diff --git a/paddle/fluid/operators/controlflow/logical_op_npu.cc b/paddle/fluid/operators/controlflow/logical_op_npu.cc index 02f9525403..c3d7df8d02 100644 --- a/paddle/fluid/operators/controlflow/logical_op_npu.cc +++ b/paddle/fluid/operators/controlflow/logical_op_npu.cc @@ -9,7 +9,7 @@ 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 "paddle/fluid/operators/controlflow/logical_op.h" +#include "paddle/fluid/framework/op_registry.h" #include "paddle/fluid/platform/device/npu/npu_op_runner.h" namespace paddle { diff --git a/paddle/phi/kernels/cpu/logical_kernel.cc b/paddle/phi/kernels/cpu/logical_kernel.cc new file mode 100644 index 0000000000..3d179e1e75 --- /dev/null +++ b/paddle/phi/kernels/cpu/logical_kernel.cc @@ -0,0 +1,72 @@ +// 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 "paddle/phi/kernels/logical_kernel.h" + +#include "paddle/phi/backends/cpu/cpu_context.h" +#include "paddle/phi/core/kernel_registry.h" +#include "paddle/phi/kernels/cpu/elementwise.h" +#include "paddle/phi/kernels/funcs/logical_functor.h" + +// See Note [ Why still include the fluid headers? ] +#include "paddle/fluid/platform/transform.h" + +namespace phi { + +#define DEFINE_LOGICAL_BINARY_KERNEL(type) \ + template \ + void Logical##type##Kernel(const Context& dev_ctx, \ + const DenseTensor& x, \ + const DenseTensor& y, \ + DenseTensor* out) { \ + funcs::Logical##type##Functor binary_func; \ + ElementwiseCompute, T, bool>( \ + dev_ctx, x, y, -1, binary_func, out); \ + } + +DEFINE_LOGICAL_BINARY_KERNEL(And) +DEFINE_LOGICAL_BINARY_KERNEL(Or) +DEFINE_LOGICAL_BINARY_KERNEL(Xor) +#undef DEFINE_LOGICAL_BINARY_KERNEL + +template +void LogicalNotKernel(const Context& dev_ctx, + const DenseTensor& x, + DenseTensor* out) { + auto* out_ptr = dev_ctx.template Alloc(out); + funcs::LogicalNotFunctor unary_func; + + paddle::platform::Transform trans; + trans(dev_ctx, x.data(), x.data() + x.numel(), out_ptr, unary_func); +} + +} // namespace phi + +#define REGISTER_LOGICAL_CPU_KERNEL(logical_and, func_type) \ + PD_REGISTER_KERNEL(logical_and, \ + CPU, \ + ALL_LAYOUT, \ + phi::Logical##func_type##Kernel, \ + float, \ + double, \ + bool, \ + int64_t, \ + int, \ + int8_t, \ + int16_t) {} + +REGISTER_LOGICAL_CPU_KERNEL(logical_and, And) +REGISTER_LOGICAL_CPU_KERNEL(logical_or, Or) +REGISTER_LOGICAL_CPU_KERNEL(logical_not, Not) +REGISTER_LOGICAL_CPU_KERNEL(logical_xor, Xor) diff --git a/paddle/phi/kernels/funcs/logical_functor.h b/paddle/phi/kernels/funcs/logical_functor.h new file mode 100644 index 0000000000..1ea7fc43e6 --- /dev/null +++ b/paddle/phi/kernels/funcs/logical_functor.h @@ -0,0 +1,41 @@ +// 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. + +#pragma once + +namespace phi { +namespace funcs { + +#define LOGICAL_BINARY_FUNCTOR(func_name, op) \ + template \ + struct func_name { \ + using ELEMENT_TYPE = T; \ + HOSTDEVICE bool operator()(const T a, const T b) const { \ + return static_cast(a) op static_cast(b); \ + } \ + }; + +LOGICAL_BINARY_FUNCTOR(LogicalOrFunctor, ||) +LOGICAL_BINARY_FUNCTOR(LogicalAndFunctor, &&) +LOGICAL_BINARY_FUNCTOR(LogicalXorFunctor, ^) +#undef LOGICAL_BINARY_FUNCTOR + +template +struct LogicalNotFunctor { + using ELEMENT_TYPE = T; + HOSTDEVICE bool operator()(const T a) const { return !a; } +}; + +} // namespace funcs +} // namespace phi diff --git a/paddle/phi/kernels/gpu/logical_kernel.cu b/paddle/phi/kernels/gpu/logical_kernel.cu new file mode 100644 index 0000000000..f32d4c77d4 --- /dev/null +++ b/paddle/phi/kernels/gpu/logical_kernel.cu @@ -0,0 +1,79 @@ +// 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 "paddle/phi/kernels/logical_kernel.h" + +#include "paddle/phi/backends/gpu/gpu_context.h" +#include "paddle/phi/core/kernel_registry.h" +#include "paddle/phi/kernels/funcs/elementwise_base.h" +#include "paddle/phi/kernels/funcs/logical_functor.h" +#include "paddle/phi/kernels/gpu/elementwise.h" + +namespace phi { + +#define DEFINE_LOGICAL_BINARY_KERNEL(type) \ + template \ + void Logical##type##Kernel(const Context& dev_ctx, \ + const DenseTensor& x, \ + const DenseTensor& y, \ + DenseTensor* out) { \ + using InT = typename funcs::Logical##type##Functor::ELEMENT_TYPE; \ + using OutT = bool; \ + dev_ctx.template Alloc(out); \ + funcs::Logical##type##Functor binary_func; \ + std::vector ins = {&x, &y}; \ + std::vector outs = {out}; \ + funcs::BroadcastKernel( \ + dev_ctx, ins, &outs, -1, binary_func); \ + } + +DEFINE_LOGICAL_BINARY_KERNEL(And) +DEFINE_LOGICAL_BINARY_KERNEL(Or) +DEFINE_LOGICAL_BINARY_KERNEL(Xor) +#undef DEFINE_LOGICAL_BINARY_KERNEL + +template +void LogicalNotKernel(const Context& dev_ctx, + const DenseTensor& x, + DenseTensor* out) { + using InT = typename funcs::LogicalNotFunctor::ELEMENT_TYPE; + using OutT = bool; + + dev_ctx.template Alloc(out); + funcs::LogicalNotFunctor unary_func; + std::vector ins = {&x}; + std::vector outs = {out}; + funcs::BroadcastKernel( + dev_ctx, ins, &outs, -1, unary_func); +} + +} // namespace phi + +#define REGISTER_LOGICAL_CUDA_KERNEL(logical_and, func_type) \ + PD_REGISTER_KERNEL(logical_and, \ + GPU, \ + ALL_LAYOUT, \ + phi::Logical##func_type##Kernel, \ + float, \ + double, \ + bool, \ + int64_t, \ + int, \ + int8_t, \ + int16_t) {} + +REGISTER_LOGICAL_CUDA_KERNEL(logical_and, And) +REGISTER_LOGICAL_CUDA_KERNEL(logical_or, Or) +REGISTER_LOGICAL_CUDA_KERNEL(logical_not, Not) +REGISTER_LOGICAL_CUDA_KERNEL(logical_xor, Xor) diff --git a/paddle/phi/kernels/logical_kernel.h b/paddle/phi/kernels/logical_kernel.h new file mode 100644 index 0000000000..3ccc03a5b5 --- /dev/null +++ b/paddle/phi/kernels/logical_kernel.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2021 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. */ + +#pragma once + +#include "paddle/phi/core/dense_tensor.h" + +namespace phi { + +#define DECLEAR_LOGICAL_BINARY_KERNEL(type) \ + template \ + void Logical##type##Kernel(const Context& dev_ctx, \ + const DenseTensor& x, \ + const DenseTensor& y, \ + DenseTensor* out); + +DECLEAR_LOGICAL_BINARY_KERNEL(And) +DECLEAR_LOGICAL_BINARY_KERNEL(Or) +DECLEAR_LOGICAL_BINARY_KERNEL(Xor) +#undef DECLEAR_LOGICAL_BINARY_KERNEL + +template +void LogicalNotKernel(const Context& dev_ctx, + const DenseTensor& x, + DenseTensor* out); + +} // namespace phi diff --git a/python/paddle/fluid/tests/unittests/test_diff_op.py b/python/paddle/fluid/tests/unittests/test_diff_op.py index 345dad5413..1ae780f488 100644 --- a/python/paddle/fluid/tests/unittests/test_diff_op.py +++ b/python/paddle/fluid/tests/unittests/test_diff_op.py @@ -55,7 +55,7 @@ class TestDiffOp(unittest.TestCase): def test_dygraph(self): for place in self.places: - paddle.disable_static(place) + paddle.disable_static() x = paddle.to_tensor(self.input, place=place) if self.prepend is not None: self.prepend = paddle.to_tensor(self.prepend, place=place) -- GitLab