diff --git a/paddle/fluid/prim/api/auto_code_generated/CMakeLists.txt b/paddle/fluid/prim/api/auto_code_generated/CMakeLists.txt index e2ea334175db0cfff4accc5924472722015d2724..55d80f9e7436ba871eaf680eade3835b9d6d1d77 100644 --- a/paddle/fluid/prim/api/auto_code_generated/CMakeLists.txt +++ b/paddle/fluid/prim/api/auto_code_generated/CMakeLists.txt @@ -78,30 +78,22 @@ execute_process( ${static_prim_api_cc_path}) message("copy tmp_xxx_prim_api to xxx_prim_api") -set(tmp_eager_tensor_operants_cc_path - "${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/eager/eager_tensor_operants.cc.tmp" -) -set(tmp_eager_tensor_operants_h_path - "${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/eager/eager_tensor_operants.h.tmp" -) -set(tmp_static_tensor_operants_cc_path - "${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/static/static_tensor_operants.cc.tmp" -) -set(tmp_static_tensor_operants_h_path - "${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/static/static_tensor_operants.h.tmp" -) set(eager_tensor_operants_cc_path - "${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/eager/eager_tensor_operants.cc" -) + ${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/eager/eager_tensor_operants.cc) set(eager_tensor_operants_h_path - "${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/eager/eager_tensor_operants.h" -) + ${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/eager/eager_tensor_operants.h) set(static_tensor_operants_cc_path - "${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/static/static_tensor_operants.cc" + ${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/static/static_tensor_operants.cc ) set(static_tensor_operants_h_path - "${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/static/static_tensor_operants.h" -) + ${PADDLE_SOURCE_DIR}/paddle/fluid/prim/utils/static/static_tensor_operants.h +) +set(tmp_eager_tensor_operants_cc_path ${eager_tensor_operants_cc_path}.tmp) +set(tmp_eager_tensor_operants_h_path ${eager_tensor_operants_h_path}.tmp) +set(tmp_static_tensor_operants_cc_path ${static_tensor_operants_cc_path}.tmp) +set(tmp_static_tensor_operants_h_path ${static_tensor_operants_h_path}.tmp) +set(tensor_api_yaml_path + ${PADDLE_SOURCE_DIR}/paddle/phi/api/yaml/tensor_api.yaml) message("Prim tensor operants code generator") execute_process( @@ -114,7 +106,7 @@ execute_process( ${tmp_eager_tensor_operants_cc_path} --static_tensor_operants_header_path ${tmp_static_tensor_operants_h_path} --static_tensor_operants_source_path ${tmp_static_tensor_operants_cc_path} --api_prim_yaml_path - ${api_prim_yaml_path} + ${tensor_api_yaml_path} RESULT_VARIABLE _result) if(${_result}) message(FATAL_ERROR "Prim tensor operants generate failed, exiting.") diff --git a/paddle/fluid/prim/api/auto_code_generated/tensor_operants_gen.py b/paddle/fluid/prim/api/auto_code_generated/tensor_operants_gen.py index 499066c27ef46b8e1aeeef1aee0f5a8fd6f1c338..b0dc1d646984f58238728830f5262ff6ccf5c994 100644 --- a/paddle/fluid/prim/api/auto_code_generated/tensor_operants_gen.py +++ b/paddle/fluid/prim/api/auto_code_generated/tensor_operants_gen.py @@ -25,6 +25,8 @@ eager_header_include = """// Generated by paddle/fluid/prim/api/auto_code_genera #include "paddle/phi/api/include/operants_base.h" #include "paddle/phi/api/include/tensor.h" +#include "paddle/phi/common/scalar.h" +#include "paddle/phi/common/int_array.h" #include "paddle/phi/core/macros.h" """ @@ -35,6 +37,8 @@ namespace paddle { namespace prim { using Tensor = paddle::experimental::Tensor; +using Scalar = paddle::experimental::Scalar; +using IntArray = paddle::experimental::IntArray; using TensorOperantsBase = paddle::operants::TensorOperantsBase; class EagerTensorOperants : public TensorOperantsBase { @@ -85,6 +89,8 @@ static_header_include = """// Generated by paddle/fluid/prim/api/auto_code_gener #include "paddle/phi/api/include/operants_base.h" #include "paddle/phi/api/include/tensor.h" +#include "paddle/phi/common/scalar.h" +#include "paddle/phi/common/int_array.h" #include "paddle/phi/core/macros.h" """ @@ -95,6 +101,8 @@ namespace paddle { namespace prim { using Tensor = paddle::experimental::Tensor; +using Scalar = paddle::experimental::Scalar; +using IntArray = paddle::experimental::IntArray; using TensorOperantsBase = paddle::operants::TensorOperantsBase; class StaticTensorOperants : public TensorOperantsBase { @@ -269,8 +277,6 @@ def generate_tensor_operants_api( with open(api_prim_path, 'rt') as f: api_prims = yaml.safe_load(f) - # white list temporarily - api_prims = ('add', 'subtract', 'multiply', 'divide') for api in apis: eager_api = PrimTensorAPI(api, api_prims) diff --git a/paddle/fluid/prim/api/composite_backward/composite_backward_api.h b/paddle/fluid/prim/api/composite_backward/composite_backward_api.h index e99f816bf6da28151aa5fc5005a259c8facb3d38..c036170197b5b1fb79697be6d2e163e1c61dbe1a 100644 --- a/paddle/fluid/prim/api/composite_backward/composite_backward_api.h +++ b/paddle/fluid/prim/api/composite_backward/composite_backward_api.h @@ -61,7 +61,7 @@ void gather_grad(const Tensor& x, template void tanh_grad(const Tensor& out, const Tensor& grad_out, Tensor* grad_x) { if (!grad_x) return; - auto tmp = pow(out, 2.0); + auto tmp = out.pow(2.0); tmp = scale(tmp, -1.0, 1.0, true); auto grad_x_tmp = grad_out * tmp; set_output(grad_x_tmp, grad_x); @@ -82,8 +82,8 @@ void subtract_grad(const Tensor& x, if (!reduce_dim.size()) { by_pass(scale_out_grad, dy); } else { - auto dy_reduce_res = sum( - scale_out_grad, phi::vectorize(reduce_dim), y.dtype(), false); + auto dy_reduce_res = + scale_out_grad.sum(phi::vectorize(reduce_dim), y.dtype(), false); auto dy_tmp = reshape(dy_reduce_res, phi::vectorize(y.dims())); set_output(dy_tmp, dy); } @@ -99,7 +99,7 @@ void subtract_grad(const Tensor& x, by_pass(out_grad, dx); } else { auto dx_reduce_res = - sum(out_grad, phi::vectorize(reduce_dim), x.dtype(), false); + out_grad.sum(phi::vectorize(reduce_dim), x.dtype(), false); auto dx_tmp = reshape(dx_reduce_res, phi::vectorize(x.dims())); set_output(dx_tmp, dx); } @@ -124,7 +124,7 @@ void add_grad(const Tensor& x, by_pass(out_grad, dy); } else { auto dy_reduce_res = - sum(out_grad, phi::vectorize(reduce_dim), y.dtype(), false); + out_grad.sum(phi::vectorize(reduce_dim), y.dtype(), false); auto dy_tmp = reshape(dy_reduce_res, phi::vectorize(y.dims())); set_output(dy_tmp, dy); } @@ -141,7 +141,7 @@ void add_grad(const Tensor& x, by_pass(out_grad, dx); } else { auto dx_reduce_res = - sum(out_grad, phi::vectorize(reduce_dim), x.dtype(), false); + out_grad.sum(phi::vectorize(reduce_dim), x.dtype(), false); auto dx_tmp = reshape(dx_reduce_res, phi::vectorize(x.dims())); set_output(dx_tmp, dx); } @@ -172,7 +172,7 @@ void sum_grad(const Tensor& x, } auto x_grad_tmp = Tensor(); if (x_dim_size == 1) { - x_grad_tmp = expand(out_grad, IntArray(x_dim)); + x_grad_tmp = out_grad.expand(IntArray(x_dim)); } else { if (!keepdim) { auto axis_ = std::vector(); @@ -184,9 +184,9 @@ void sum_grad(const Tensor& x, axis_ = axis.GetData(); } auto out_grad_ = unsqueeze(out_grad, axis_); - x_grad_tmp = expand(out_grad_, IntArray(x_dim)); + x_grad_tmp = out_grad_.expand(IntArray(x_dim)); } else { - x_grad_tmp = expand(out_grad, IntArray(x_dim)); + x_grad_tmp = out_grad.expand(IntArray(x_dim)); } } @@ -203,7 +203,7 @@ void divide_grad(const Tensor& x, Tensor* dy) { if (dy) { // dy = -(x/y^2) * dout - auto tmp0 = pow(y, 2.0); + auto tmp0 = y.pow(2.0); auto tmp1 = x / tmp0; auto tmp2 = scale(tmp1, -1.0, 0.0, true); auto dy_res = tmp2 * out_grad; @@ -214,7 +214,7 @@ void divide_grad(const Tensor& x, set_output(dy_res, dy); } else { auto dy_reduce_res = - sum(dy_res, phi::vectorize(reduce_dim), y.dtype(), false); + dy_res.sum(phi::vectorize(reduce_dim), y.dtype(), false); auto dy_tmp = reshape(dy_reduce_res, phi::vectorize(y.dims())); set_output(dy_tmp, dy); } @@ -233,7 +233,7 @@ void divide_grad(const Tensor& x, set_output(dx_res, dx); } else { auto dx_reduce_res = - sum(dx_res, phi::vectorize(reduce_dim), x.dtype(), false); + dx_res.sum(phi::vectorize(reduce_dim), x.dtype(), false); auto dx_tmp = reshape(dx_reduce_res, phi::vectorize(x.dims())); set_output(dx_tmp, dx); } @@ -267,10 +267,8 @@ void multiply_grad(const Tensor& x, if (!axes.size()) { set_output(x_grad_unreduce, x_grad); } else { - auto x_grad_reduced = sum(x_grad_unreduce, - phi::vectorize(axes), - x_grad_unreduce.dtype(), - false); + auto x_grad_reduced = x_grad_unreduce.sum( + phi::vectorize(axes), x_grad_unreduce.dtype(), false); if (x_grad_reduced.dims().size() != x.dims().size()) { x_grad_reduced = reshape(x_grad_reduced, x.shape()); } @@ -287,10 +285,8 @@ void multiply_grad(const Tensor& x, if (!axes.size()) { set_output(y_grad_unreduce, y_grad); } else { - auto y_grad_reduced = sum(y_grad_unreduce, - phi::vectorize(axes), - y_grad_unreduce.dtype(), - false); + auto y_grad_reduced = y_grad_unreduce.sum( + phi::vectorize(axes), y_grad_unreduce.dtype(), false); if (y_grad_reduced.dims().size() != y.dims().size()) { y_grad_reduced = reshape(y_grad_reduced, y.shape()); } @@ -314,7 +310,7 @@ void expand_grad(const Tensor& x, if (!axes.size()) { by_pass(out_grad, x_grad); } else { - auto reduced = sum(out_grad, phi::vectorize(axes), x.dtype(), false); + auto reduced = out_grad.sum(phi::vectorize(axes), x.dtype(), false); if (reduced.dims().size() != x.dims().size()) { reduced = reshape(reduced, x.shape()); } diff --git a/paddle/phi/api/include/tensor.h b/paddle/phi/api/include/tensor.h index fc37ec6172c4c3cdb7207d386e3a3867d81ac591..c10218b8f1541b479551231e0bed0ae39dccc9f6 100644 --- a/paddle/phi/api/include/tensor.h +++ b/paddle/phi/api/include/tensor.h @@ -47,6 +47,16 @@ namespace paddle { namespace experimental { +class Tensor; + +template +class ScalarBase; +using Scalar = paddle::experimental::ScalarBase; + +template +class IntArrayBase; +using IntArray = paddle::experimental::IntArrayBase; + class AbstractAutogradMeta { public: // No AbstractAutogradMeta should be created @@ -646,12 +656,35 @@ class PADDLE_API Tensor final { */ std::string name_{""}; + public: // Tensor C++ APIs // Example: Tensor add(const Tensor& other) const; Tensor add(const Tensor& y) const; Tensor divide(const Tensor& y) const; Tensor multiply(const Tensor& y) const; Tensor subtract(const Tensor& y) const; + Tensor exp() const; + Tensor floor() const; + Tensor gather_nd(const Tensor& index) const; + Tensor log() const; + Tensor pow(const Scalar& y) const; + Tensor roll(const IntArray& shifts, const std::vector& axis) const; + Tensor scatter(const Tensor& index, + const Tensor& updates, + bool overwrite) const; + Tensor scatter_nd_add(const Tensor& index, const Tensor& updates) const; + Tensor abs() const; + Tensor assign() const; + Tensor elementwise_pow(const Tensor& y) const; + Tensor expand(const IntArray& shape) const; + Tensor matmul(const Tensor& y, bool transpose_x, bool transpose_y) const; + Tensor max(const IntArray& axis, bool keepdim) const; + Tensor maximum(const Tensor& y) const; + Tensor minimum(const Tensor& y) const; + Tensor prod(const IntArray& dims, bool keep_dim, bool reduce_all) const; + Tensor scale(const Scalar& scale, float bias, bool bias_after_scale) const; + Tensor sum(const IntArray& axis, DataType dtype, bool keepdim) const; + Tensor tile(const IntArray& repeat_times) const; }; } // namespace experimental diff --git a/paddle/phi/api/lib/CMakeLists.txt b/paddle/phi/api/lib/CMakeLists.txt index 1fb9c147ffec4941275a197f6a903728f3a7599a..025b7dff007c8004e45bdc2fc91b82b608485b68 100644 --- a/paddle/phi/api/lib/CMakeLists.txt +++ b/paddle/phi/api/lib/CMakeLists.txt @@ -98,8 +98,10 @@ set(wrapped_infermeta_source_file ${CMAKE_SOURCE_DIR}/paddle/phi/infermeta/generated.cc) # tensor and tensor operants file +set(tensor_api_yaml_path + ${CMAKE_SOURCE_DIR}/paddle/phi/api/yaml/tensor_api.yaml) set(tensor_gen_file - ${CMAKE_SOURCE_DIR}/paddle/phi/api/yaml/generator/tensor_gen.py) + ${CMAKE_SOURCE_DIR}/paddle/phi/api/yaml/generator/tensor_operants_gen.py) set(operants_base_file ${CMAKE_SOURCE_DIR}/paddle/phi/api/include/operants_base.h) set(tensor_api_source_file ${CMAKE_SOURCE_DIR}/paddle/phi/api/lib/tensor_api.cc) @@ -249,6 +251,7 @@ execute_process( --phi_tensor_operants_source_path ${phi_tensor_operants_source_file_tmp} --operants_manager_header_path ${operants_manager_header_file_tmp} --operants_manager_source_path ${operants_manager_source_file_tmp} + --tensor_api_yaml_path ${tensor_api_yaml_path} RESULT_VARIABLE _result) if(${_result}) message(FATAL_ERROR "tensor codegen failed, exiting.") diff --git a/paddle/phi/api/yaml/generator/tensor_gen.py b/paddle/phi/api/yaml/generator/tensor_operants_gen.py similarity index 88% rename from paddle/phi/api/yaml/generator/tensor_gen.py rename to paddle/phi/api/yaml/generator/tensor_operants_gen.py index 19f1919edbb3327ab49c7fda43babd3ca1a75ed0..45ac6ee926324083d53d0f85a318b48caed28bf1 100644 --- a/paddle/phi/api/yaml/generator/tensor_gen.py +++ b/paddle/phi/api/yaml/generator/tensor_operants_gen.py @@ -30,11 +30,13 @@ inplace_optional_out_type_map = { indent = " " -operants_base_include = """// Generated by paddle/phi/api/yaml/generator/tensor_gen.py +operants_base_include = """// Generated by paddle/phi/api/yaml/generator/tensor_operants_gen.py #pragma once #include "paddle/phi/api/include/tensor.h" +#include "paddle/phi/common/scalar.h" +#include "paddle/phi/common/int_array.h" """ @@ -44,6 +46,8 @@ namespace paddle { namespace operants { using Tensor = paddle::experimental::Tensor; +using Scalar = paddle::experimental::Scalar; +using IntArray = paddle::experimental::IntArray; class TensorOperantsBase { public: @@ -58,7 +62,7 @@ operants_base_end = """}; """ -tensor_api_source_include = """// Generated by paddle/phi/api/yaml/generator/tensor_gen.py +tensor_api_source_include = """// Generated by paddle/phi/api/yaml/generator/tensor_operants_gen.py #include "paddle/phi/api/include/tensor.h" @@ -96,12 +100,14 @@ tensor_api_source_end = """ """ -operants_header_include = """// Generated by paddle/phi/api/yaml/generator/tensor_gen.py +operants_header_include = """// Generated by paddle/phi/api/yaml/generator/tensor_operants_gen.py #pragma once #include "paddle/phi/api/include/operants_base.h" #include "paddle/phi/api/include/tensor.h" +#include "paddle/phi/common/scalar.h" +#include "paddle/phi/common/int_array.h" #include "paddle/phi/core/macros.h" """ @@ -111,6 +117,9 @@ namespace paddle { namespace operants { +using Scalar = paddle::experimental::Scalar; +using IntArray = paddle::experimental::IntArray; + class PhiTensorOperants : public TensorOperantsBase { private: DISABLE_COPY_AND_ASSIGN(PhiTensorOperants); @@ -128,7 +137,7 @@ operants_header_end = """}; """ -operants_source_include = """// Generated by paddle/phi/api/yaml/generator/tensor_gen.py +operants_source_include = """// Generated by paddle/phi/api/yaml/generator/tensor_operants_gen.py #include "paddle/phi/api/include/tensor_operants.h" @@ -151,12 +160,14 @@ operants_source_end = """ """ -operants_manager_header_include = """// Generated by paddle/phi/api/yaml/generator/tensor_gen.py +operants_manager_header_include = """// Generated by paddle/phi/api/yaml/generator/tensor_operants_gen.py #pragma once #include "paddle/phi/api/include/operants_base.h" #include "paddle/phi/api/include/tensor.h" +#include "paddle/phi/common/scalar.h" +#include "paddle/phi/common/int_array.h" #include "paddle/phi/core/macros.h" """ @@ -165,6 +176,8 @@ operants_manager_header_start = """ namespace paddle { using Tensor = paddle::experimental::Tensor; +using Scalar = paddle::experimental::Scalar; +using IntArray = paddle::experimental::IntArray; using TensorOperantsBase = paddle::operants::TensorOperantsBase; /** @@ -222,7 +235,7 @@ operants_manager_header_end = """}; """ -operants_manager_source_include = """// Generated by paddle/phi/api/yaml/generator/tensor_gen.py +operants_manager_source_include = """// Generated by paddle/phi/api/yaml/generator/tensor_operants_gen.py #include "paddle/phi/api/include/operants_manager.h" @@ -271,11 +284,17 @@ class OperantsAPI(ForwardAPI): """ def get_define_args_without_first_tensor(self, inplace_flag=False): - # NOTE(HongyuJia): consider vector becomes first input argument. + func_name = self.get_api_func_name() define_args = self.get_input_tensor_args(inplace_flag) - assert ( - len(define_args) > 1 - ), "Can't use tensor api without Tensor inputs" + assert len(define_args) >= 1, ( + "Error! Api %s has no Tensor inputs" % func_name + ) + first_input_type = " ".join(define_args[0].split(" ")[:-1]) + # NOTE(HongyuJia): Do not consider "const paddle::optional&" + assert first_input_type == "const Tensor&", ( + "Error! The first argument of Tensor Api %s must be Tensor, but received %s" + % (func_name, first_input_type) + ) for name in self.attrs['names']: define_args.append(self.attrs['attr_info'][name][0] + ' ' + name) # remove first Tensor argument @@ -283,23 +302,26 @@ class OperantsAPI(ForwardAPI): def gene_tensor_api_implementation(self): func_name = self.get_api_func_name() - assert ( - len(self.inputs['names']) > 1 - ), "Can't use tensor api without Tensor inputs" + assert len(self.inputs['names']) >= 1, ( + "Error! Api %s has no Tensor inputs" % func_name + ) # remove first Tensor argument func_args = self.inputs['names'][1:] + self.attrs['names'] - func_args_code = ", ".join(func_args) + if len(func_args) > 0: + func_args_code = ", ".join([""] + func_args) + else: + func_args_code = "" # func decalaration if func_name[-1] != '_': return f""" {self.get_return_type()} Tensor::{func_name}({self.get_define_args_without_first_tensor()}) const {{ -{indent}return paddle::OperantsManager::Instance().{func_name}(static_cast(*this), {func_args_code}); +{indent}return paddle::OperantsManager::Instance().{func_name}(static_cast(*this){func_args_code}); }} """ else: return f""" {self.get_return_type(inplace_flag=True)} Tensor::{func_name}({self.get_define_args_without_first_tensor(inplace_flag=True)}) const {{ -{indent}return paddle::OperantsManager::Instance().{func_name}(static_cast(*this), {func_args_code}); +{indent}return paddle::OperantsManager::Instance().{func_name}(static_cast(*this){func_args_code}); }} """ @@ -394,6 +416,7 @@ def generate_tensor_operants_api( operants_source_path, operants_manager_header_path, operants_manager_source_path, + tensor_api_yaml_path, ): apis = [] @@ -423,8 +446,8 @@ def generate_tensor_operants_api( operants_manager_source_file.write(operants_manager_source_include) operants_manager_source_file.write(operants_manager_source_start) - # white list temporarily - api_prims = ('add', 'subtract', 'multiply', 'divide') + with open(tensor_api_yaml_path, 'rt') as f: + api_prims = yaml.safe_load(f) for api in apis: operants_api = OperantsAPI(api, api_prims) @@ -506,6 +529,12 @@ def main(): default='paddle/phi/api/lib/operants_manager.cc', ) + parser.add_argument( + '--tensor_api_yaml_path', + help='path to tensor_api yaml file', + default='paddle/phi/api/yaml/tensor_api.yaml', + ) + options = parser.parse_args() api_yaml_path = options.api_yaml_path @@ -515,6 +544,7 @@ def main(): operants_source_path = options.phi_tensor_operants_source_path operants_manager_header_path = options.operants_manager_header_path operants_manager_source_path = options.operants_manager_source_path + tensor_api_yaml_path = options.tensor_api_yaml_path generate_tensor_operants_api( api_yaml_path, @@ -524,6 +554,7 @@ def main(): operants_source_path, operants_manager_header_path, operants_manager_source_path, + tensor_api_yaml_path, ) diff --git a/paddle/phi/api/yaml/tensor_api.yaml b/paddle/phi/api/yaml/tensor_api.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a96a2a44132e5ac62d251a4e7d4a88930480eb2f --- /dev/null +++ b/paddle/phi/api/yaml/tensor_api.yaml @@ -0,0 +1,25 @@ +- unsqueeze +- pow +- exp +- scale +- multiply +- matmul +- expand +- divide +- sum +- add +- abs +- assign +- elementwise_pow +- floor +- gather_nd +- log +- max +- maximum +- minimum +- prod +- roll +- scatter +- scatter_nd_add +- tile +- subtract