From e01411b74adc0fdc9acf954ecfe2eb9fd6de10df Mon Sep 17 00:00:00 2001 From: YuanRisheng Date: Sat, 2 Apr 2022 06:28:55 +0000 Subject: [PATCH 1/7] move yaml --- paddle/phi/api/lib/CMakeLists.txt | 2 +- paddle/phi/api/lib/api_custom_impl.cc | 149 ++++++++++++++++++ paddle/phi/api/lib/api_custom_impl.h | 4 +- paddle/phi/infermeta/backward.cc | 14 ++ paddle/phi/infermeta/backward.h | 4 + paddle/phi/infermeta/multiary.cc | 26 +++ paddle/phi/infermeta/multiary.h | 2 + python/paddle/fluid/layers/nn.py | 4 +- .../fluid/tests/unittests/test_mean_op.py | 13 +- .../fluid/tests/unittests/test_meshgrid_op.py | 13 ++ python/paddle/tensor/creation.py | 4 +- python/paddle/utils/code_gen/api.yaml | 13 ++ python/paddle/utils/code_gen/backward.yaml | 16 ++ 13 files changed, 254 insertions(+), 10 deletions(-) diff --git a/paddle/phi/api/lib/CMakeLists.txt b/paddle/phi/api/lib/CMakeLists.txt index af2533019156c..d4d8a0fa8a304 100644 --- a/paddle/phi/api/lib/CMakeLists.txt +++ b/paddle/phi/api/lib/CMakeLists.txt @@ -165,7 +165,7 @@ cc_library(context_pool SRCS context_pool.cc DEPS phi_context phi_enforce place) cc_library(kernel_dispatch SRCS kernel_dispatch.cc DEPS phi_tensor_raw phi_context kernel_factory context_pool) cc_library(api_gen_utils SRCS api_gen_utils.cc DEPS phi_tensor_raw selected_rows sparse_csr_tensor sparse_coo_tensor) cc_library(phi_data_transform SRCS data_transform.cc DEPS phi_tensor_raw transfer_layout_kernel cast_kernel data_device_transform) -cc_library(api_custom_impl SRCS api_custom_impl.cc DEPS phi_tensor_raw phi kernel_dispatch api_gen_utils phi_data_transform) +cc_library(api_custom_impl SRCS api_custom_impl.cc DEPS phi_tensor_raw phi kernel_dispatch api_gen_utils phi_data_transform backward_infermeta) cc_library(sparse_api_custom_impl SRCS sparse_api_custom_impl.cc DEPS phi_tensor_raw phi kernel_dispatch api_gen_utils phi_data_transform) cc_library(phi_function_api SRCS ${api_source_file} DEPS phi_tensor_raw phi kernel_dispatch api_gen_utils phi_data_transform api_custom_impl) diff --git a/paddle/phi/api/lib/api_custom_impl.cc b/paddle/phi/api/lib/api_custom_impl.cc index 152873fe41072..8f3b472ea048c 100644 --- a/paddle/phi/api/lib/api_custom_impl.cc +++ b/paddle/phi/api/lib/api_custom_impl.cc @@ -21,6 +21,7 @@ limitations under the License. */ #include "paddle/phi/core/compat/convert_utils.h" #include "paddle/phi/core/kernel_registry.h" #include "paddle/phi/core/meta_tensor.h" +#include "paddle/phi/infermeta/backward.h" #include "paddle/phi/infermeta/binary.h" #include "paddle/phi/infermeta/multiary.h" #include "paddle/phi/infermeta/nullary.h" @@ -120,5 +121,153 @@ std::vector split_impl(const Tensor& x, return out; } +std::vector meshgrid_impl(const std::vector& inputs) { + Backend kernel_backend = Backend::UNDEFINED; + DataLayout kernel_layout = DataLayout::UNDEFINED; + DataType kernel_data_type = DataType::UNDEFINED; + + if (kernel_backend == Backend::UNDEFINED || + kernel_layout == DataLayout::UNDEFINED || + kernel_data_type == DataType::UNDEFINED) { + auto kernel_key_set = ParseKernelKeyByInputArgs(inputs); + auto kernel_key = kernel_key_set.GetHighestPriorityKernelKey(); + if (kernel_backend == Backend::UNDEFINED) { + kernel_backend = kernel_key.backend(); + } + if (kernel_layout == DataLayout::UNDEFINED) { + kernel_layout = kernel_key.layout(); + } + if (kernel_data_type == DataType::UNDEFINED) { + kernel_data_type = kernel_key.dtype(); + } + } + + const auto& kernel = phi::KernelFactory::Instance().SelectKernelOrThrowError( + "meshgrid", {kernel_backend, kernel_layout, kernel_data_type}); + VLOG(6) << "meshgrid API kernel key: [" << kernel_backend << ", " + << kernel_layout << ", " << kernel_data_type << "]"; + VLOG(6) << "meshgrid API kernel: " << kernel; + + auto* dev_ctx = GetDeviceContextByBackend(kernel_backend); + + auto input_inputs_vec = PrepareData(inputs, kernel.InputAt(0), {}); + std::vector input_inputs(input_inputs_vec->size()); + for (size_t i = 0; i < input_inputs.size(); ++i) { + input_inputs[i] = &input_inputs_vec->at(i); + } + + auto x_meta_vec = MakeMetaTensor(input_inputs); + std::vector inputs_metas(x_meta_vec.size()); + for (size_t i = 0; i < x_meta_vec.size(); ++i) { + inputs_metas[i] = &x_meta_vec[i]; + } + + // Calculate the number of out tensors + size_t out_number = inputs.size(); + + std::vector out; + auto dense_outs = SetKernelOutput(out_number, kernel_backend, &out); + + std::vector meta_outs; + meta_outs.reserve(out_number); + std::vector meta_out_ptrs; + meta_out_ptrs.reserve(out_number); + for (size_t i = 0; i < out_number; ++i) { + meta_outs.push_back(dense_outs[i]); + meta_out_ptrs.push_back(&meta_outs.back()); + } + phi::MeshgridInferMeta(inputs_metas, meta_out_ptrs); + + using kernel_signature = void (*)(const platform::DeviceContext&, + const std::vector&, + std::vector&); + auto* kernel_fn = kernel.GetVariadicKernelFn(); + (*kernel_fn)(*dev_ctx, input_inputs, dense_outs); + + return out; +} + +std::vector meshgrid_grad_impl( + const std::vector& inputs, + const std::vector& outputs_grad) { + Backend kernel_backend = Backend::UNDEFINED; + DataLayout kernel_layout = DataLayout::UNDEFINED; + DataType kernel_data_type = DataType::UNDEFINED; + + if (kernel_backend == Backend::UNDEFINED || + kernel_layout == DataLayout::UNDEFINED || + kernel_data_type == DataType::UNDEFINED) { + auto kernel_key_set = ParseKernelKeyByInputArgs(inputs, outputs_grad); + auto kernel_key = kernel_key_set.GetHighestPriorityKernelKey(); + if (kernel_backend == Backend::UNDEFINED) { + kernel_backend = kernel_key.backend(); + } + if (kernel_layout == DataLayout::UNDEFINED) { + kernel_layout = kernel_key.layout(); + } + if (kernel_data_type == DataType::UNDEFINED) { + kernel_data_type = kernel_key.dtype(); + } + } + + const auto& kernel = phi::KernelFactory::Instance().SelectKernelOrThrowError( + "meshgrid_grad", {kernel_backend, kernel_layout, kernel_data_type}); + VLOG(6) << "meshgrid_grad API kernel key: [" << kernel_backend << ", " + << kernel_layout << ", " << kernel_data_type << "]"; + VLOG(6) << "meshgrid_grad API kernel: " << kernel; + + auto* dev_ctx = GetDeviceContextByBackend(kernel_backend); + + auto input_inputs_vec = PrepareData(inputs, kernel.InputAt(0), {}); + std::vector input_inputs(input_inputs_vec->size()); + for (size_t i = 0; i < input_inputs.size(); ++i) { + input_inputs[i] = &input_inputs_vec->at(i); + } + auto input_outputs_grad_vec = + PrepareData(outputs_grad, kernel.InputAt(1), {}); + std::vector input_outputs_grad( + input_outputs_grad_vec->size()); + for (size_t i = 0; i < input_outputs_grad.size(); ++i) { + input_outputs_grad[i] = &input_outputs_grad_vec->at(i); + } + + size_t out_number = inputs.size(); + std::vector api_output; + auto kernel_out = SetKernelOutput(out_number, kernel_backend, &api_output); + + auto inputs_meta_vec = MakeMetaTensor(input_inputs); + std::vector inputs_metas(inputs_meta_vec.size()); + for (size_t i = 0; i < inputs_meta_vec.size(); ++i) { + inputs_metas[i] = &inputs_meta_vec[i]; + } + + auto outputs_grad_meta_vec = MakeMetaTensor(input_outputs_grad); + std::vector outputs_grad_metas( + outputs_grad_meta_vec.size()); + for (size_t i = 0; i < outputs_grad_meta_vec.size(); ++i) { + outputs_grad_metas[i] = &outputs_grad_meta_vec[i]; + } + + std::vector meta_outs; + meta_outs.reserve(out_number); + std::vector meta_out_ptrs; + meta_out_ptrs.reserve(out_number); + for (size_t i = 0; i < out_number; ++i) { + meta_outs.push_back(kernel_out[i]); + meta_out_ptrs.push_back(&meta_outs.back()); + } + + phi::MeshgridGradInferMeta(inputs_metas, outputs_grad_metas, meta_out_ptrs); + + using kernel_signature = void (*)(const platform::DeviceContext&, + const std::vector&, + const std::vector&, + std::vector&); + auto* kernel_fn = kernel.GetVariadicKernelFn(); + (*kernel_fn)(*dev_ctx, input_inputs, input_outputs_grad, kernel_out); + + return api_output; +} + } // namespace experimental } // namespace paddle diff --git a/paddle/phi/api/lib/api_custom_impl.h b/paddle/phi/api/lib/api_custom_impl.h index b2f5a074d9288..e56806553de22 100644 --- a/paddle/phi/api/lib/api_custom_impl.h +++ b/paddle/phi/api/lib/api_custom_impl.h @@ -27,6 +27,8 @@ Tensor copy_to_impl(const Tensor& x, Place place, bool blocking); std::vector split_impl(const Tensor& x, const IntArray& num_or_sections, const Scalar& axis); - +std::vector meshgrid_impl(const std::vector& inputs); +std::vector meshgrid_grad_impl(const std::vector& inputs, + const std::vector& outputs_grad); } // namespace experimental } // namespace paddle diff --git a/paddle/phi/infermeta/backward.cc b/paddle/phi/infermeta/backward.cc index e7682d78a14a1..0942d9e98a3c5 100644 --- a/paddle/phi/infermeta/backward.cc +++ b/paddle/phi/infermeta/backward.cc @@ -180,6 +180,20 @@ void MaxPoolWithIndexGradInferMeta(const MetaTensor& x, dx->share_meta(x); } +void MeshgridGradInferMeta(const std::vector& inputs, + const std::vector& outputs_grad, + std::vector inputs_grad) { + PADDLE_ENFORCE_GT(outputs_grad.size(), + 1, + errors::InvalidArgument( + "Number of Inputs(Out@Grad) should be larger than 1." + "But received Inputs(Out@Grad)' size = %d .", + outputs_grad.size())); + for (size_t i = 0; i < inputs.size(); i++) { + inputs_grad[i]->share_meta(*inputs[i]); + } +} + void NllLossGradInferMeta(const MetaTensor& x, const MetaTensor& label, paddle::optional weight, diff --git a/paddle/phi/infermeta/backward.h b/paddle/phi/infermeta/backward.h index 4cdc048b24964..7488aaf30030f 100644 --- a/paddle/phi/infermeta/backward.h +++ b/paddle/phi/infermeta/backward.h @@ -104,6 +104,10 @@ void MaxPoolWithIndexGradInferMeta(const MetaTensor& x, bool adaptive, MetaTensor* dx); +void MeshgridGradInferMeta(const std::vector& inputs, + const std::vector& outputs_grad, + std::vector inputs_grad); + void NllLossGradInferMeta(const MetaTensor& input, const MetaTensor& label, paddle::optional weight, diff --git a/paddle/phi/infermeta/multiary.cc b/paddle/phi/infermeta/multiary.cc index 1f6cf1a6882d8..068dfcd1089ae 100644 --- a/paddle/phi/infermeta/multiary.cc +++ b/paddle/phi/infermeta/multiary.cc @@ -1389,6 +1389,32 @@ void InterpolateInferMeta( config); } } +void MeshgridInferMeta(const std::vector& x, + std::vector out) { + PADDLE_ENFORCE_GE( + x.size(), 1UL, errors::InvalidArgument("Input(X) should not be empty.")); + PADDLE_ENFORCE_GE( + out.size(), + 1UL, + errors::InvalidArgument("Output(Out) should not be empty.")); + std::vector inputs_dims; + for (auto x_meta_tensor : x) { + inputs_dims.push_back(x_meta_tensor->dims()); + } + const size_t inputs_num = inputs_dims.size(); + const size_t outputs_num = out.size(); + + auto out_shape = std::vector(inputs_num); + + for (size_t i = 0; i < inputs_num; i++) { + out_shape[i] = inputs_dims[i][0]; + } + auto out_dims = phi::make_ddim(std::vector(out_shape)); + std::vector outs_dims(outputs_num, out_dims); + for (size_t i = 0; i < out.size(); i++) { + out[i]->set_dims(outs_dims[i]); + } +} void MultiDotInferMeta(const std::vector& x, MetaTensor* out) { auto inputs_dims = GetMetaTensorsDim(x); diff --git a/paddle/phi/infermeta/multiary.h b/paddle/phi/infermeta/multiary.h index b748d898c1e4e..a241663a212cc 100644 --- a/paddle/phi/infermeta/multiary.h +++ b/paddle/phi/infermeta/multiary.h @@ -214,6 +214,8 @@ void InterpolateInferMeta( int align_mode, MetaTensor* output, MetaConfig config = MetaConfig()); +void MeshgridInferMeta(const std::vector& x, + std::vector out); void MultiDotInferMeta(const std::vector& x, MetaTensor* out); diff --git a/python/paddle/fluid/layers/nn.py b/python/paddle/fluid/layers/nn.py index 9567490551c28..f03a1897e18a0 100755 --- a/python/paddle/fluid/layers/nn.py +++ b/python/paddle/fluid/layers/nn.py @@ -12788,8 +12788,10 @@ def mean(x, name=None): mean = fluid.layers.mean(input) """ - if _non_static_mode(): + if _in_legacy_dygraph(): return _C_ops.mean(x) + if in_dygraph_mode(): + return _C_ops.final_state_mean_all(x) helper = LayerHelper("mean", **locals()) check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mean') diff --git a/python/paddle/fluid/tests/unittests/test_mean_op.py b/python/paddle/fluid/tests/unittests/test_mean_op.py index 7a49770e57985..3839c09a2a8ee 100644 --- a/python/paddle/fluid/tests/unittests/test_mean_op.py +++ b/python/paddle/fluid/tests/unittests/test_mean_op.py @@ -21,13 +21,14 @@ import paddle.fluid.core as core import paddle.fluid as fluid from paddle.fluid import Program, program_guard - +from paddle.fluid.framework import _test_eager_guard np.random.seed(10) class TestMeanOp(OpTest): def setUp(self): self.op_type = "mean" + self.python_api = fluid.layers.mean self.dtype = np.float64 self.init_dtype_type() self.inputs = {'X': np.random.random((10, 10)).astype(self.dtype)} @@ -37,10 +38,10 @@ def init_dtype_type(self): pass def test_check_output(self): - self.check_output() + self.check_output(check_eager=True) def test_checkout_grad(self): - self.check_grad(['X'], 'Out') + self.check_grad(['X'], 'Out', check_eager=True) class TestMeanOpError(unittest.TestCase): @@ -68,7 +69,7 @@ def init_dtype_type(self): def test_check_output(self): place = core.CUDAPlace(0) if core.is_float16_supported(place): - self.check_output_with_place(place) + self.check_output_with_place(place, check_eager=True) def test_checkout_grad(self): place = core.CUDAPlace(0) @@ -91,11 +92,11 @@ def init_dtype_type(self): def test_check_output(self): paddle.enable_static() - self.check_output_with_place(core.CPUPlace()) + self.check_output_with_place(core.CPUPlace(), check_eager=True) def test_checkout_grad(self): place = core.CPUPlace() - self.check_grad_with_place(place, ['X'], 'Out') + self.check_grad_with_place(place, ['X'], 'Out', check_eager=True) def ref_reduce_mean(x, axis=None, keepdim=False, reduce_all=False): diff --git a/python/paddle/fluid/tests/unittests/test_meshgrid_op.py b/python/paddle/fluid/tests/unittests/test_meshgrid_op.py index 2cb83eba3767c..b14e6a59f0bf8 100644 --- a/python/paddle/fluid/tests/unittests/test_meshgrid_op.py +++ b/python/paddle/fluid/tests/unittests/test_meshgrid_op.py @@ -20,6 +20,7 @@ import paddle.fluid as fluid import paddle from paddle.fluid import compiler, Program, program_guard, core +from paddle.fluid.framework import _test_eager_guard class TestMeshgridOp(OpTest): @@ -149,6 +150,10 @@ def test_api_with_dygraph(self): assert np.array_equal(res_3.shape, [100, 200]) assert np.array_equal(res_4.shape, [100, 200]) + def test_api_eager_dygraph(self): + with _test_eager_guard(): + self.test_api_with_dygraph() + class TestMeshgridOp7(unittest.TestCase): def test_api_with_dygraph_list_input(self): @@ -163,6 +168,10 @@ def test_api_with_dygraph_list_input(self): assert np.array_equal(res_3.shape, [100, 200]) assert np.array_equal(res_4.shape, [100, 200]) + def test_api_eager_dygraph(self): + with _test_eager_guard(): + self.test_api_with_dygraph_list_input() + class TestMeshgridOp8(unittest.TestCase): def test_api_with_dygraph_tuple_input(self): @@ -177,6 +186,10 @@ def test_api_with_dygraph_tuple_input(self): assert np.array_equal(res_3.shape, [100, 200]) assert np.array_equal(res_4.shape, [100, 200]) + def test_api_eager_dygraph(self): + with _test_eager_guard(): + self.test_api_with_dygraph_tuple_input() + if __name__ == '__main__': paddle.enable_static() diff --git a/python/paddle/tensor/creation.py b/python/paddle/tensor/creation.py index 6e7e5678be0b0..a4e0da4845e9d 100644 --- a/python/paddle/tensor/creation.py +++ b/python/paddle/tensor/creation.py @@ -767,10 +767,12 @@ def meshgrid(*args, **kwargs): if len(args) == 1 and isinstance(args[0], (list, tuple)): args = args[0] - if paddle.in_dynamic_mode(): + if _in_legacy_dygraph(): num = len(args) out = _C_ops.meshgrid(list(args), num) return out + if in_dygraph_mode(): + return _C_ops.final_state_meshgrid(list(args)) name = kwargs.get("name", None) helper = LayerHelper('meshgrid', **locals()) diff --git a/python/paddle/utils/code_gen/api.yaml b/python/paddle/utils/code_gen/api.yaml index da79a928dba7a..b40fc8b228a4d 100644 --- a/python/paddle/utils/code_gen/api.yaml +++ b/python/paddle/utils/code_gen/api.yaml @@ -761,6 +761,19 @@ kernel : func : mean +- api : mean_all + args : (Tensor x) + output : Tensor + infer_meta : + func : MeanAllInferMeta + kernel : + func : mean_all + +- api : meshgrid + args : (Tensor[] inputs) + output : Tensor[] + invoke : meshgrid_impl(inputs) + - api : minimum args : (Tensor x, Tensor y) output : Tensor(out) diff --git a/python/paddle/utils/code_gen/backward.yaml b/python/paddle/utils/code_gen/backward.yaml index dc7261eef1650..d395c656993e9 100644 --- a/python/paddle/utils/code_gen/backward.yaml +++ b/python/paddle/utils/code_gen/backward.yaml @@ -418,6 +418,22 @@ kernel : func : maximum_grad +- backward_api : mean_all_grad + forward : mean_all(Tensor x) -> Tensor(out) + args : (Tensor x, Tensor out_grad) + output : Tensor(x_grad) + infer_meta : + func : UnchangedInferMeta + param: [x] + kernel : + func : mean_all_grad + +- backward_api : meshgrid_grad + forward : meshgrid (Tensor[] inputs) -> Tensor[](outputs) + args : (Tensor[] inputs, Tensor[] outputs_grad) + output : Tensor[] + invoke : meshgrid_grad_impl(inputs, outputs_grad) + - backward_api : minimum_grad forward : minimum(Tensor x, Tensor y) -> Tensor(out) args : (Tensor x, Tensor y, Tensor out_grad, int axis=-1) From df191048985599c13bfb06bdb447dda5ee8ae070 Mon Sep 17 00:00:00 2001 From: YuanRisheng Date: Sun, 3 Apr 2022 06:53:43 +0000 Subject: [PATCH 2/7] add momentum yaml --- paddle/phi/api/lib/api_custom_impl.cc | 141 ++++++++++++++++++ paddle/phi/api/lib/api_custom_impl.h | 15 ++ paddle/phi/infermeta/multiary.cc | 47 ++++++ paddle/phi/infermeta/multiary.h | 15 ++ .../fluid/tests/unittests/test_momentum_op.py | 10 ++ python/paddle/optimizer/momentum.py | 12 +- python/paddle/utils/code_gen/api.yaml | 11 +- 7 files changed, 247 insertions(+), 4 deletions(-) diff --git a/paddle/phi/api/lib/api_custom_impl.cc b/paddle/phi/api/lib/api_custom_impl.cc index 8f3b472ea048c..bf2ca0ef40149 100644 --- a/paddle/phi/api/lib/api_custom_impl.cc +++ b/paddle/phi/api/lib/api_custom_impl.cc @@ -269,5 +269,146 @@ std::vector meshgrid_grad_impl( return api_output; } +std::tuple momentum_impl( + const Tensor& param, + const Tensor& grad, + const Tensor& velocity, + const Tensor& learning_rate, + paddle::optional master_param, + float mu, + bool use_nesterov, + const std::string& regularization_method, + float regularization_coeff, + bool multi_precision, + float rescale_grad) { + Backend kernel_backend = Backend::UNDEFINED; + DataLayout kernel_layout = DataLayout::UNDEFINED; + DataType kernel_data_type = DataType::UNDEFINED; + + if (kernel_backend == Backend::UNDEFINED || + kernel_layout == DataLayout::UNDEFINED || + kernel_data_type == DataType::UNDEFINED) { + auto kernel_key_set = ParseKernelKeyByInputArgs(param); + auto kernel_key = kernel_key_set.GetHighestPriorityKernelKey(); + if (kernel_backend == Backend::UNDEFINED) { + kernel_backend = kernel_key.backend(); + } + if (kernel_layout == DataLayout::UNDEFINED) { + kernel_layout = kernel_key.layout(); + } + if (kernel_data_type == DataType::UNDEFINED) { + kernel_data_type = kernel_key.dtype(); + } + } + std::string kernel_name = "momentum"; + if (grad.is_selected_rows()) { + kernel_name = "momentum_dense_param_sparse_grad"; + } + const auto& kernel = phi::KernelFactory::Instance().SelectKernelOrThrowError( + kernel_name, {kernel_backend, kernel_layout, kernel_data_type}); + VLOG(6) << kernel_name << " API kernel key: [" << kernel_backend << ", " + << kernel_layout << ", " << kernel_data_type << "]"; + VLOG(6) << kernel_name << " API kernel: " << kernel; + + auto* dev_ctx = GetDeviceContextByBackend(kernel_backend); + + auto input_param = PrepareData(param, kernel.InputAt(0), {}); + auto input_grad = PrepareData(grad, kernel.InputAt(1), {}); + auto input_velocity = PrepareData(velocity, kernel.InputAt(2), {}); + auto input_learning_rate = PrepareData(learning_rate, kernel.InputAt(3), {}); + paddle::optional input_master_param(paddle::none); + auto input_master_param_ptr = + PrepareData(master_param, kernel.InputAt(4), {}); + + std::tuple api_output; + auto kernel_out_0 = input_param.get(); + auto kernel_out_1 = input_velocity.get(); + phi::DenseTensor* kernel_out_2 = nullptr; + if (input_master_param_ptr) { + input_master_param = + paddle::make_optional(*input_master_param_ptr); + kernel_out_2 = + paddle::make_optional(*input_master_param_ptr) + .get_ptr(); + } + + paddle::optional input_meta_ref_master_param( + paddle::none); + auto input_meta_master_param = MakeMetaTensor(input_master_param); + if (input_meta_master_param) { + input_meta_ref_master_param = + paddle::make_optional(*input_meta_master_param); + } + phi::MetaTensor meta_out_0(kernel_out_0); + phi::MetaTensor meta_out_1(kernel_out_1); + if (kernel_out_2) { + phi::MetaTensor meta_out_2(kernel_out_2); + phi::MomentumInferMeta(MakeMetaTensor(*input_param), + MakeMetaTensor(*input_grad), + MakeMetaTensor(*input_velocity), + MakeMetaTensor(*input_learning_rate), + input_meta_ref_master_param, + mu, + use_nesterov, + regularization_method, + regularization_coeff, + multi_precision, + rescale_grad, + &meta_out_0, + &meta_out_1, + &meta_out_2); + } else { + phi::MomentumInferMeta(MakeMetaTensor(*input_param), + MakeMetaTensor(*input_grad), + MakeMetaTensor(*input_velocity), + MakeMetaTensor(*input_learning_rate), + input_meta_ref_master_param, + mu, + use_nesterov, + regularization_method, + regularization_coeff, + multi_precision, + rescale_grad, + &meta_out_0, + &meta_out_1, + nullptr); + } + + using kernel_signature = void (*)(const platform::DeviceContext&, + const phi::DenseTensor&, + const phi::DenseTensor&, + const phi::DenseTensor&, + const phi::DenseTensor&, + paddle::optional, + float, + bool, + const std::string&, + float, + bool, + float, + phi::DenseTensor*, + phi::DenseTensor*, + phi::DenseTensor*); + auto* kernel_fn = kernel.GetVariadicKernelFn(); + + (*kernel_fn)(*dev_ctx, + *input_param, + *input_grad, + *input_velocity, + *input_learning_rate, + input_master_param, + mu, + use_nesterov, + regularization_method, + regularization_coeff, + multi_precision, + rescale_grad, + kernel_out_0, + kernel_out_1, + kernel_out_2); + + return api_output; +} + } // namespace experimental } // namespace paddle diff --git a/paddle/phi/api/lib/api_custom_impl.h b/paddle/phi/api/lib/api_custom_impl.h index e56806553de22..5189ee3e58038 100644 --- a/paddle/phi/api/lib/api_custom_impl.h +++ b/paddle/phi/api/lib/api_custom_impl.h @@ -18,6 +18,7 @@ limitations under the License. */ #include "paddle/phi/common/int_array.h" #include "paddle/phi/common/place.h" #include "paddle/phi/common/scalar.h" +#include "paddle/utils/optional.h" namespace paddle { namespace experimental { @@ -30,5 +31,19 @@ std::vector split_impl(const Tensor& x, std::vector meshgrid_impl(const std::vector& inputs); std::vector meshgrid_grad_impl(const std::vector& inputs, const std::vector& outputs_grad); + +std::tuple momentum_impl( + const Tensor& param, + const Tensor& grad, + const Tensor& velocity, + const Tensor& learning_rate, + paddle::optional master_param, + float mu, + bool use_nesterov, + const std::string& regularization_method, + float regularization_coeff, + bool multi_precision, + float rescale_grad); + } // namespace experimental } // namespace paddle diff --git a/paddle/phi/infermeta/multiary.cc b/paddle/phi/infermeta/multiary.cc index b848c40211097..5fd8343ede79d 100644 --- a/paddle/phi/infermeta/multiary.cc +++ b/paddle/phi/infermeta/multiary.cc @@ -1416,6 +1416,53 @@ void MeshgridInferMeta(const std::vector& x, } } +void MomentumInferMeta(const MetaTensor& param, + const MetaTensor& grad, + const MetaTensor& velocity, + const MetaTensor& learning_rate, + paddle::optional master_param, + float mu, + bool use_nesterov, + const std::string& regularization_method, + float regularization_coeff, + bool multi_precision, + float rescale_grad, + MetaTensor* param_out, + MetaTensor* velocity_out, + MetaTensor* master_param_out) { + PADDLE_ENFORCE_NE( + param_out, + nullptr, + errors::NotFound("Output(ParamOut) of Momentum should not be null.")); + PADDLE_ENFORCE_NE( + velocity_out, + nullptr, + errors::NotFound("Output(VelocityOut) of Momentum should not be null.")); + + auto lr_dims = learning_rate.dims(); + PADDLE_ENFORCE_NE( + phi::product(lr_dims), + 0, + errors::InvalidArgument("Maybe the Input variable LearningRate has not " + "been initialized. You may need to confirm " + "if you put exe.run(startup_program) " + "after optimizer.minimize function.")); + PADDLE_ENFORCE_EQ( + phi::product(lr_dims), + 1, + errors::InvalidArgument("Learning_rate should be a scalar. But Received " + "LearningRate's dim [%s]", + phi::product(lr_dims))); + + auto param_dim = param.dims(); + param_out->set_dims(param_dim); + velocity_out->set_dims(param_dim); + + if (master_param_out) { + master_param_out->set_dims(param_dim); + } +} + void MultiDotInferMeta(const std::vector& x, MetaTensor* out) { auto inputs_dims = GetMetaTensorsDim(x); diff --git a/paddle/phi/infermeta/multiary.h b/paddle/phi/infermeta/multiary.h index d159bcea73236..ef28a092ebeef 100644 --- a/paddle/phi/infermeta/multiary.h +++ b/paddle/phi/infermeta/multiary.h @@ -217,6 +217,21 @@ void InterpolateInferMeta( void MeshgridInferMeta(const std::vector& x, std::vector out); +void MomentumInferMeta(const MetaTensor& param, + const MetaTensor& grad, + const MetaTensor& velocity, + const MetaTensor& learning_rate, + paddle::optional master_param, + float mu, + bool use_nesterov, + const std::string& regularization_method, + float regularization_coeff, + bool multi_precision, + float rescale_grad, + MetaTensor* param_out, + MetaTensor* velocity_out, + MetaTensor* master_param_out); + void MultiDotInferMeta(const std::vector& x, MetaTensor* out); void MultiplexInferMeta(const std::vector& ins, diff --git a/python/paddle/fluid/tests/unittests/test_momentum_op.py b/python/paddle/fluid/tests/unittests/test_momentum_op.py index 7f3690cff60f5..a4f38e37731e8 100644 --- a/python/paddle/fluid/tests/unittests/test_momentum_op.py +++ b/python/paddle/fluid/tests/unittests/test_momentum_op.py @@ -22,6 +22,7 @@ import paddle import paddle.fluid as fluid import numpy +from paddle.fluid.framework import _test_eager_guard def calculate_momentum_by_numpy(param, @@ -528,6 +529,11 @@ def test_raise_error(self): ValueError, paddle.optimizer.Momentum, learning_rate=None) self.assertRaises(ValueError, paddle.optimizer.Momentum, momentum=None) + def test_api_eager_dygraph(self): + with _test_eager_guard(): + self.test_momentum_dygraph() + self.test_raise_error() + class TestMomentumOpWithDecay(OpTest): def setUp(self): @@ -921,6 +927,10 @@ def test_main(self): self._check_with_param_arrt(place, use_amp) self._check_with_param_group(place, use_amp) + def test_api_eager_dygraph(self): + with _test_eager_guard(): + self.test_main() + class TestMultiTensorMomentumStatic(unittest.TestCase): def _momentum_optimize_static(self, diff --git a/python/paddle/optimizer/momentum.py b/python/paddle/optimizer/momentum.py index f68bbad4ab249..ce112c19250ca 100644 --- a/python/paddle/optimizer/momentum.py +++ b/python/paddle/optimizer/momentum.py @@ -25,6 +25,7 @@ from paddle.fluid.regularizer import L2DecayRegularizer from paddle import _C_ops import paddle +from paddle.fluid.framework import in_dygraph_mode, _in_legacy_dygraph __all__ = [] @@ -313,7 +314,7 @@ def _append_optimize_op(self, block, param_and_grad): master_weight = (self._master_weights[param_and_grad[0].name] if find_master else None) - if framework._non_static_mode(): + if _in_legacy_dygraph(): if isinstance(param_and_grad, dict): self._update_regularization(param_and_grad['weight_decay']) _, _, _ = _C_ops.momentum( @@ -323,8 +324,15 @@ def _append_optimize_op(self, block, param_and_grad): 'regularization_method', regularization_method, 'regularization_coeff', regularization_coeff, 'multi_precision', find_master) - return None + if in_dygraph_mode(): + if isinstance(param_and_grad, dict): + self._update_regularization(param_and_grad['weight_decay']) + return _C_ops.final_state_momentum( + param_and_grad[0], param_and_grad[1], velocity_acc, lr, + master_weight, self._momentum, self._use_nesterov, + regularization_method, regularization_coeff, find_master, + self._rescale_grad) attrs = { "mu": self._momentum, diff --git a/python/paddle/utils/code_gen/api.yaml b/python/paddle/utils/code_gen/api.yaml index b6521ef295d58..789d127db0774 100644 --- a/python/paddle/utils/code_gen/api.yaml +++ b/python/paddle/utils/code_gen/api.yaml @@ -1057,13 +1057,14 @@ func : MeanAllInferMeta kernel : func : mean_all + backward : mean_all_grad - api : meshgrid args : (Tensor[] inputs) output : Tensor[] + #backward : meshgrid_grad invoke : meshgrid_impl(inputs) - backward : meshgrid_grad - + - api : min args : (Tensor x, int64_t[] dims={}, bool keep_dim=false) output : Tensor(out) @@ -1110,6 +1111,12 @@ func : modulo backward : modulo_grad +- api : momentum + args : (Tensor param, Tensor grad, Tensor velocity, Tensor learning_rate, Tensor master_param, float mu, bool use_nesterov = false, str regularization_method = "", float regularization_coeff = 0.0, bool multi_precision = false, float rescale_grad = 1.0f) + output : Tensor(param_out), Tensor(velocity_out), Tensor(master_param_out) + invoke : momentum_impl(param, grad, velocity, learning_rate, master_param, mu, use_nesterov, regularization_method, regularization_coeff, multi_precision, rescale_grad) + optional : master_param + # multinomial - api : multinomial args : (Tensor x, int num_samples, bool replacement) From df0303469567c013445b874a5fe4f6cdcca0477d Mon Sep 17 00:00:00 2001 From: YuanRisheng Date: Sun, 3 Apr 2022 08:13:43 +0000 Subject: [PATCH 3/7] delete code --- paddle/phi/infermeta/multiary.cc | 44 +++++++------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/paddle/phi/infermeta/multiary.cc b/paddle/phi/infermeta/multiary.cc index 8be95132b4b5e..b00df7c380c46 100644 --- a/paddle/phi/infermeta/multiary.cc +++ b/paddle/phi/infermeta/multiary.cc @@ -1415,30 +1415,20 @@ void InterpolateInferMeta( config); } } -void MeshgridInferMeta(const std::vector& x, - std::vector out) { - PADDLE_ENFORCE_GE( - x.size(), 1UL, errors::InvalidArgument("Input(X) should not be empty.")); - PADDLE_ENFORCE_GE( - out.size(), - 1UL, - errors::InvalidArgument("Output(Out) should not be empty.")); - std::vector inputs_dims; - for (auto x_meta_tensor : x) { - inputs_dims.push_back(x_meta_tensor->dims()); - } - const size_t inputs_num = inputs_dims.size(); - const size_t outputs_num = out.size(); + +void MeshgridInferMeta(const std::vector& inputs, + std::vector outputs) { + const size_t inputs_num = inputs.size(); auto out_shape = std::vector(inputs_num); - for (size_t i = 0; i < inputs_num; i++) { - out_shape[i] = inputs_dims[i][0]; + for (size_t i = 0; i < inputs.size(); i++) { + out_shape[i] = inputs[i]->dims()[0]; } auto out_dims = phi::make_ddim(std::vector(out_shape)); - std::vector outs_dims(outputs_num, out_dims); - for (size_t i = 0; i < out.size(); i++) { - out[i]->set_dims(outs_dims[i]); + for (size_t i = 0; i < outputs.size(); ++i) { + outputs[i]->set_dims(out_dims); + outputs[i]->set_dtype(inputs[0]->dtype()); } } @@ -1489,22 +1479,6 @@ void MomentumInferMeta(const MetaTensor& param, } } -void MeshgridInferMeta(const std::vector& inputs, - std::vector outputs) { - const size_t inputs_num = inputs.size(); - - auto out_shape = std::vector(inputs_num); - - for (size_t i = 0; i < inputs.size(); i++) { - out_shape[i] = inputs[i]->dims()[0]; - } - auto out_dims = phi::make_ddim(std::vector(out_shape)); - for (size_t i = 0; i < outputs.size(); ++i) { - outputs[i]->set_dims(out_dims); - outputs[i]->set_dtype(inputs[0]->dtype()); - } -} - void MultiDotInferMeta(const std::vector& x, MetaTensor* out) { auto inputs_dims = GetMetaTensorsDim(x); From 038300580100e3058d291f04d6b30f2d4255cb4a Mon Sep 17 00:00:00 2001 From: YuanRisheng Date: Sun, 3 Apr 2022 08:23:52 +0000 Subject: [PATCH 4/7] delete some code --- paddle/phi/infermeta/multiary.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/paddle/phi/infermeta/multiary.h b/paddle/phi/infermeta/multiary.h index 89dba2952b15e..d16b9ba5c75c6 100644 --- a/paddle/phi/infermeta/multiary.h +++ b/paddle/phi/infermeta/multiary.h @@ -222,8 +222,9 @@ void InterpolateInferMeta( int align_mode, MetaTensor* output, MetaConfig config = MetaConfig()); -void MeshgridInferMeta(const std::vector& x, - std::vector out); + +void MeshgridInferMeta(const std::vector& inputs, + std::vector outputs); void MomentumInferMeta(const MetaTensor& param, const MetaTensor& grad, @@ -240,9 +241,6 @@ void MomentumInferMeta(const MetaTensor& param, MetaTensor* velocity_out, MetaTensor* master_param_out); -void MeshgridInferMeta(const std::vector& inputs, - std::vector outputs); - void MultiDotInferMeta(const std::vector& x, MetaTensor* out); void MultiplexInferMeta(const std::vector& ins, From 863e64ab5be537d5bcb779934c797626648d1179 Mon Sep 17 00:00:00 2001 From: YuanRisheng Date: Sun, 3 Apr 2022 11:19:50 +0000 Subject: [PATCH 5/7] add meshgrid backward --- python/paddle/utils/code_gen/api.yaml | 2 +- python/paddle/utils/code_gen/backward.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/paddle/utils/code_gen/api.yaml b/python/paddle/utils/code_gen/api.yaml index 789d127db0774..8596ad7a6e1c3 100644 --- a/python/paddle/utils/code_gen/api.yaml +++ b/python/paddle/utils/code_gen/api.yaml @@ -1062,8 +1062,8 @@ - api : meshgrid args : (Tensor[] inputs) output : Tensor[] - #backward : meshgrid_grad invoke : meshgrid_impl(inputs) + backward : meshgrid_grad - api : min args : (Tensor x, int64_t[] dims={}, bool keep_dim=false) diff --git a/python/paddle/utils/code_gen/backward.yaml b/python/paddle/utils/code_gen/backward.yaml index 8e4ef28036c66..bebe5bc9cd31d 100644 --- a/python/paddle/utils/code_gen/backward.yaml +++ b/python/paddle/utils/code_gen/backward.yaml @@ -696,7 +696,7 @@ - backward_api : meshgrid_grad forward : meshgrid (Tensor[] inputs) -> Tensor[](outputs) args : (Tensor[] inputs, Tensor[] outputs_grad) - output : Tensor[] + output : Tensor[](inputs_grad) invoke : meshgrid_grad_impl(inputs, outputs_grad) - backward_api : min_grad From bb75bef4cfa7bbdab4addc4ae800804385538a84 Mon Sep 17 00:00:00 2001 From: YuanRisheng Date: Mon, 4 Apr 2022 14:03:28 +0000 Subject: [PATCH 6/7] delete code --- paddle/phi/infermeta/backward.cc | 14 -------------- paddle/phi/infermeta/backward.h | 4 ---- 2 files changed, 18 deletions(-) diff --git a/paddle/phi/infermeta/backward.cc b/paddle/phi/infermeta/backward.cc index 7d1e965d928f2..7282c0695086a 100644 --- a/paddle/phi/infermeta/backward.cc +++ b/paddle/phi/infermeta/backward.cc @@ -245,20 +245,6 @@ void MaxPoolWithIndexGradInferMeta(const MetaTensor& x, dx->share_meta(x); } -void MeshgridGradInferMeta(const std::vector& inputs, - const std::vector& outputs_grad, - std::vector inputs_grad) { - PADDLE_ENFORCE_GT(outputs_grad.size(), - 1, - errors::InvalidArgument( - "Number of Inputs(Out@Grad) should be larger than 1." - "But received Inputs(Out@Grad)' size = %d .", - outputs_grad.size())); - for (size_t i = 0; i < inputs.size(); i++) { - inputs_grad[i]->share_meta(*inputs[i]); - } -} - void NllLossGradInferMeta(const MetaTensor& x, const MetaTensor& label, paddle::optional weight, diff --git a/paddle/phi/infermeta/backward.h b/paddle/phi/infermeta/backward.h index 0de1debd4ab32..92266811de057 100644 --- a/paddle/phi/infermeta/backward.h +++ b/paddle/phi/infermeta/backward.h @@ -115,10 +115,6 @@ void MaxPoolWithIndexGradInferMeta(const MetaTensor& x, bool adaptive, MetaTensor* dx); -void MeshgridGradInferMeta(const std::vector& inputs, - const std::vector& outputs_grad, - std::vector inputs_grad); - void NllLossGradInferMeta(const MetaTensor& input, const MetaTensor& label, paddle::optional weight, From 9b836128a448ec611cc68c7389e24a98a1624660 Mon Sep 17 00:00:00 2001 From: YuanRisheng Date: Mon, 4 Apr 2022 15:10:18 +0000 Subject: [PATCH 7/7] fix compile bugs --- paddle/phi/api/lib/api_custom_impl.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/paddle/phi/api/lib/api_custom_impl.cc b/paddle/phi/api/lib/api_custom_impl.cc index 63db2ca949e20..3fac683798924 100644 --- a/paddle/phi/api/lib/api_custom_impl.cc +++ b/paddle/phi/api/lib/api_custom_impl.cc @@ -231,10 +231,13 @@ std::tuple momentum_impl( paddle::optional input_meta_ref_master_param( paddle::none); - auto input_meta_master_param = MakeMetaTensor(input_master_param); - if (input_meta_master_param) { - input_meta_ref_master_param = - paddle::make_optional(*input_meta_master_param); + phi::DenseTensor dt; + phi::MetaTensor input_meta_tmp_master_param(dt); + if (input_master_param_ptr) { + input_meta_tmp_master_param.set_dtype(input_master_param_ptr->dtype()); + input_meta_tmp_master_param.set_dims(input_master_param_ptr->dims()); + input_meta_tmp_master_param.set_layout(input_master_param_ptr->layout()); + input_meta_ref_master_param = input_meta_tmp_master_param; } phi::MetaTensor meta_out_0(kernel_out_0); phi::MetaTensor meta_out_1(kernel_out_1); @@ -306,6 +309,7 @@ std::tuple momentum_impl( return api_output; } + std::tuple batch_norm_impl( const Tensor& x, const Tensor& scale,