diff --git a/paddle/fluid/prim/api/auto_code_generated/eager_gen.py b/paddle/fluid/prim/api/auto_code_generated/eager_gen.py index 176d693eee9b28df66d7d45ebd4f598c851fcb8d..6231157b19861a7d463d65024daa33436e27d153 100644 --- a/paddle/fluid/prim/api/auto_code_generated/eager_gen.py +++ b/paddle/fluid/prim/api/auto_code_generated/eager_gen.py @@ -15,7 +15,320 @@ import argparse import yaml -from prim_base import EagerPrimAPI + +inplace_out_type_map = { + "Tensor": "Tensor&", + "std::vector": "std::vector&", +} + +inplace_optional_out_type_map = { + "Tensor": "paddle::optional&", + "std::vector": "paddle::optional>&", +} + + +class BaseAPI: + def __init__(self, api_item_yaml, prims=tuple()): + # self.api = api_item_yaml['op'] + self.api = api_item_yaml['name'] + + self.is_prim_api = False + if api_item_yaml['name'] in prims: + self.is_prim_api = True + + ####################################### + # inputs: + # names : [], list of input names + # input_info : {input_name : type} + # attrs: + # names : [], list of attribute names + # attr_info : { attr_name : (type, default_values)} + # outputs: + # names : [], list of output names + # types : [], list of output types + # out_size_expr : [], expression for getting size of vector + ######################################## + if self.is_prim_api: + ( + self.inputs, + self.attrs, + self.outputs, + self.optional_vars, + ) = self.parse_args(self.api, api_item_yaml) + + self.inplace_map = api_item_yaml['inplace'] + + def get_api_func_name(self): + return self.api + + # def is_inplace(self): + # if self.inplace_map + # return True + # return False + + def get_input_tensor_args(self, inplace_flag=False): + input_args = [] + inplace_type_map = { + "const Tensor&": "Tensor&", + "const paddle::optional&": "paddle::optional&", + "const std::vector&": "std::vector&", + "const paddle::optional>&": "paddle::optional>&", + } + for name in self.inputs['names']: + name = name.split('@')[0] + if inplace_flag and name in self.inplace_map.values(): + input_args.append( + inplace_type_map[self.inputs['input_info'][name]] + + ' ' + + name + ) + else: + input_args.append(self.inputs['input_info'][name] + ' ' + name) + return input_args + + def get_declare_args(self, inplace_flag=False): + declare_args = self.get_input_tensor_args(inplace_flag) + for name in self.attrs['names']: + default_value = '' + if self.attrs['attr_info'][name][1] is not None: + default_value = ' = ' + self.attrs['attr_info'][name][1] + declare_args.append( + self.attrs['attr_info'][name][0] + ' ' + name + default_value + ) + + return ", ".join(declare_args) + + def get_declare_args_nodefault(self, inplace_flag=False): + declare_args = self.get_input_tensor_args(inplace_flag) + for name in self.attrs['names']: + declare_args.append(self.attrs['attr_info'][name][0] + ' ' + name) + + return ", ".join(declare_args) + + def get_return_type(self, inplace_flag=False): + out_type_list = [] + for i, out_type in enumerate(self.outputs['types']): + out_name = self.outputs['names'][i].split('@')[0] + if inplace_flag and out_name in self.inplace_map: + if self.inplace_map[out_name] in self.optional_vars: + out_type_list.append( + inplace_optional_out_type_map[out_type] + ) + else: + out_type_list.append(inplace_out_type_map[out_type]) + else: + out_type_list.append(out_type) + if len(out_type_list) == 1: + return out_type_list[0] + else: + return "std::tuple<" + ", ".join(out_type_list) + ">" + + def parse_args(self, api_name, api_item_yaml): + optional_vars = [] + for input_dict in api_item_yaml['inputs']: + if input_dict['optional']: + optional_vars.append(input_dict['name']) + + inputs, attrs = self.parse_input_and_attr( + api_item_yaml['inputs'], api_item_yaml['attrs'] + ) + + output_type_list, output_names, out_size_expr = self.parse_output( + api_item_yaml['outputs'] + ) + return ( + inputs, + attrs, + { + 'names': output_names, + 'types': output_type_list, + 'out_size_expr': out_size_expr, + }, + optional_vars, + ) + + def parse_input_and_attr(self, inputs_list, attrs_list): + input_types_map = { + 'Tensor': 'const Tensor&', + 'Tensor[]': 'const std::vector&', + } + attr_types_map = { + 'IntArray': 'const IntArray&', + 'Scalar': 'const Scalar&', + 'Scalar(int)': 'const Scalar&', + 'Scalar(int64_t)': 'const Scalar&', + 'Scalar(float)': 'const Scalar&', + 'Scalar(dobule)': 'const Scalar&', + 'Scalar[]': 'const std::vector&', + 'int': 'int', + 'int32_t': 'int32_t', + 'int64_t': 'int64_t', + 'long': 'long', + 'size_t': 'size_t', + 'float': 'float', + 'float[]': 'const std::vector&', + 'double': 'double', + 'bool': 'bool', + 'bool[]': 'const std::vector&', + 'str': 'const std::string&', + 'str[]': 'const std::vector&', + 'Place': 'const Place&', + 'DataLayout': 'DataLayout', + 'DataType': 'DataType', + 'int64_t[]': 'const std::vector&', + 'int[]': 'const std::vector&', + } + optional_types_trans = { + 'Tensor': 'const paddle::optional&', + 'Tensor[]': 'const paddle::optional>&', + 'int': 'paddle::optional', + 'int32_t': 'paddle::optional', + 'int64_t': 'paddle::optional', + 'float': 'paddle::optional', + 'double': 'paddle::optional', + 'bool': 'paddle::optional', + 'Place': 'paddle::optional', + 'DataLayout': 'paddle::optional', + 'DataType': 'paddle::optional', + } + + inputs = {'names': [], 'input_info': {}} + for input_dict in inputs_list: + inputs['names'].append(input_dict['name']) + if input_dict['optional']: + inputs['input_info'][input_dict['name']] = optional_types_trans[ + input_dict['typename'] + ] + else: + inputs['input_info'][input_dict['name']] = input_types_map[ + input_dict['typename'] + ] + + attrs = {'names': [], 'attr_info': {}} + for attr_dict in attrs_list: + attrs['names'].append(attr_dict['name']) + if 'default_value' in attr_dict.keys(): + default_value = attr_dict['default_value'] + else: + default_value = None + + if 'optional' in attr_dict.keys(): + attrs['attr_info'][attr_dict['name']] = ( + optional_types_trans[attr_dict['typename']], + default_value, + ) + else: + attrs['attr_info'][attr_dict['name']] = ( + attr_types_map[attr_dict['typename']], + default_value, + ) + return inputs, attrs + + def parse_output(self, outputs_list): + + out_type_list = [] + out_name_list = [] + out_size_expr_list = [] + for output_dict in outputs_list: + if output_dict['intermediate']: + continue + out_type_list.append(output_dict['typename']) + out_name_list.append(output_dict['name']) + if 'size' in output_dict.keys(): + out_size_expr_list.append(output_dict['size']) + else: + out_size_expr_list.append(None) + return out_type_list, out_name_list, out_size_expr_list + + +class EagerPrimAPI(BaseAPI): + def __init__(self, api_item_yaml, prims=tuple()): + super().__init__(api_item_yaml, prims) + + def get_api__func_name(self): + api_func_name = self.api + # if self.is_inplace: + # if api_func_name[-1] != '_': + # api_func_name += '_' + # print("after api name", api_func_name) + return api_func_name + + def gene_prim_api_declaration(self): + api_declaration = "" + api_func_name = self.get_api__func_name() + if api_func_name[-1] != '_': + api_declaration = f""" +template +{self.get_return_type()} {api_func_name}({self.get_declare_args()}); +""" + else: + api_declaration = ( + api_declaration + + f""" +template +{self.get_return_type(inplace_flag=True)} {api_func_name}({self.get_declare_args(inplace_flag=True)}); +""" + ) + + return api_declaration + + def get_ad_func_input_args(self, inplace_flag=False): + input_args = [] + for name in self.inputs['names']: + name = name.split('@')[0] + if inplace_flag and name in self.inplace_map.values(): + input_args.append(name) + else: + input_args.append(name) + return input_args + + def get_ad_func_args(self, inplace_flag=False): + ad_func_args = self.get_ad_func_input_args(inplace_flag) + for name in self.attrs['names']: + default_value = '' + if self.attrs['attr_info'][name][1] is not None: + default_value = ' = ' + self.attrs['attr_info'][name][1] + ad_func_args.append(name) + + ad_func_args_str = ", ".join(ad_func_args) + return ad_func_args_str + + def gene_ad_func_call(self): + api_func_name = self.get_api__func_name() + + dygraph_ad_func_name = '::' + api_func_name + '_ad_func' + dygraph_ad_func_parameters = self.get_ad_func_args() + + ad_func_call_str = f""" +VLOG(4) << "Eager Prim API {api_func_name}_ad_func call"; +return {dygraph_ad_func_name}({dygraph_ad_func_parameters}); +""" + # print("ad_func_call_str: ", ad_func_call_str) + return ad_func_call_str + + def gene_eager_prim_api_code(self): + api_code = "" + indent = " " + api_func_name = self.get_api__func_name() + template = '' + # func decalaration + if api_func_name[-1] != '_': + api_code = f""" +template <> +{self.get_return_type()} {api_func_name}{template}({self.get_declare_args_nodefault()}) +""" + else: + api_code = f""" +template <> +{self.get_return_type(inplace_flag=True)} {api_func_name}{template}({self.get_declare_args_nodefault(inplace_flag=True)}) +""" + # func code + + api_code = api_code + '{' + api_code += f"""{self.gene_ad_func_call()}""" + api_code += '}' + '\n' + + return api_code def header_include(): @@ -120,7 +433,7 @@ def main(): parser.add_argument( '--api_prim_yaml_path', help='Primitive API list yaml file.', - default='paddle/fluid/prim/api/auto_code_generated/api.yaml', + default='paddle/fluid/prim/api/api.yaml', ) options = parser.parse_args() diff --git a/paddle/fluid/prim/api/auto_code_generated/prim_base.py b/paddle/fluid/prim/api/auto_code_generated/prim_base.py deleted file mode 100644 index ce14878037480763eb192f5afc05247eb9c0c3d4..0000000000000000000000000000000000000000 --- a/paddle/fluid/prim/api/auto_code_generated/prim_base.py +++ /dev/null @@ -1,342 +0,0 @@ -# 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. - - -# prim api list -white_ops_list = [ - "pow", - "scale", - "multiply", - "unsqueeze", - "expand", - "full", - "reshape", - "divide", - "sum", - "exp", -] - -inplace_out_type_map = { - "Tensor": "Tensor&", - "std::vector": "std::vector&", -} - -inplace_optional_out_type_map = { - "Tensor": "paddle::optional&", - "std::vector": "paddle::optional>&", -} - - -class BaseAPI: - def __init__(self, api_item_yaml, prims=tuple()): - # self.api = api_item_yaml['op'] - self.api = api_item_yaml['name'] - - self.is_prim_api = False - if api_item_yaml['name'] in prims: - self.is_prim_api = True - - ####################################### - # inputs: - # names : [], list of input names - # input_info : {input_name : type} - # attrs: - # names : [], list of attribute names - # attr_info : { attr_name : (type, default_values)} - # outputs: - # names : [], list of output names - # types : [], list of output types - # out_size_expr : [], expression for getting size of vector - ######################################## - if self.is_prim_api: - ( - self.inputs, - self.attrs, - self.outputs, - self.optional_vars, - ) = self.parse_args(self.api, api_item_yaml) - - self.inplace_map = api_item_yaml['inplace'] - - def get_api_func_name(self): - return self.api - - # def is_inplace(self): - # if self.inplace_map - # return True - # return False - - def get_input_tensor_args(self, inplace_flag=False): - input_args = [] - inplace_type_map = { - "const Tensor&": "Tensor&", - "const paddle::optional&": "paddle::optional&", - "const std::vector&": "std::vector&", - "const paddle::optional>&": "paddle::optional>&", - } - for name in self.inputs['names']: - name = name.split('@')[0] - if inplace_flag and name in self.inplace_map.values(): - input_args.append( - inplace_type_map[self.inputs['input_info'][name]] - + ' ' - + name - ) - else: - input_args.append(self.inputs['input_info'][name] + ' ' + name) - return input_args - - def get_declare_args(self, inplace_flag=False): - declare_args = self.get_input_tensor_args(inplace_flag) - for name in self.attrs['names']: - default_value = '' - if self.attrs['attr_info'][name][1] is not None: - default_value = ' = ' + self.attrs['attr_info'][name][1] - declare_args.append( - self.attrs['attr_info'][name][0] + ' ' + name + default_value - ) - - return ", ".join(declare_args) - - def get_declare_args_nodefault(self, inplace_flag=False): - declare_args = self.get_input_tensor_args(inplace_flag) - for name in self.attrs['names']: - declare_args.append(self.attrs['attr_info'][name][0] + ' ' + name) - - return ", ".join(declare_args) - - def get_return_type(self, inplace_flag=False): - out_type_list = [] - for i, out_type in enumerate(self.outputs['types']): - out_name = self.outputs['names'][i].split('@')[0] - if inplace_flag and out_name in self.inplace_map: - if self.inplace_map[out_name] in self.optional_vars: - out_type_list.append( - inplace_optional_out_type_map[out_type] - ) - else: - out_type_list.append(inplace_out_type_map[out_type]) - else: - out_type_list.append(out_type) - if len(out_type_list) == 1: - return out_type_list[0] - else: - return "std::tuple<" + ", ".join(out_type_list) + ">" - - def parse_args(self, api_name, api_item_yaml): - optional_vars = [] - for input_dict in api_item_yaml['inputs']: - if input_dict['optional']: - optional_vars.append(input_dict['name']) - - inputs, attrs = self.parse_input_and_attr( - api_item_yaml['inputs'], api_item_yaml['attrs'] - ) - - output_type_list, output_names, out_size_expr = self.parse_output( - api_item_yaml['outputs'] - ) - return ( - inputs, - attrs, - { - 'names': output_names, - 'types': output_type_list, - 'out_size_expr': out_size_expr, - }, - optional_vars, - ) - - def parse_input_and_attr(self, inputs_list, attrs_list): - input_types_map = { - 'Tensor': 'const Tensor&', - 'Tensor[]': 'const std::vector&', - } - attr_types_map = { - 'IntArray': 'const IntArray&', - 'Scalar': 'const Scalar&', - 'Scalar(int)': 'const Scalar&', - 'Scalar(int64_t)': 'const Scalar&', - 'Scalar(float)': 'const Scalar&', - 'Scalar(dobule)': 'const Scalar&', - 'Scalar[]': 'const std::vector&', - 'int': 'int', - 'int32_t': 'int32_t', - 'int64_t': 'int64_t', - 'long': 'long', - 'size_t': 'size_t', - 'float': 'float', - 'float[]': 'const std::vector&', - 'double': 'double', - 'bool': 'bool', - 'bool[]': 'const std::vector&', - 'str': 'const std::string&', - 'str[]': 'const std::vector&', - 'Place': 'const Place&', - 'DataLayout': 'DataLayout', - 'DataType': 'DataType', - 'int64_t[]': 'const std::vector&', - 'int[]': 'const std::vector&', - } - optional_types_trans = { - 'Tensor': 'const paddle::optional&', - 'Tensor[]': 'const paddle::optional>&', - 'int': 'paddle::optional', - 'int32_t': 'paddle::optional', - 'int64_t': 'paddle::optional', - 'float': 'paddle::optional', - 'double': 'paddle::optional', - 'bool': 'paddle::optional', - 'Place': 'paddle::optional', - 'DataLayout': 'paddle::optional', - 'DataType': 'paddle::optional', - } - - inputs = {'names': [], 'input_info': {}} - for input_dict in inputs_list: - inputs['names'].append(input_dict['name']) - if input_dict['optional']: - inputs['input_info'][input_dict['name']] = optional_types_trans[ - input_dict['typename'] - ] - else: - inputs['input_info'][input_dict['name']] = input_types_map[ - input_dict['typename'] - ] - - attrs = {'names': [], 'attr_info': {}} - for attr_dict in attrs_list: - attrs['names'].append(attr_dict['name']) - if 'default_value' in attr_dict.keys(): - default_value = attr_dict['default_value'] - else: - default_value = None - - if 'optional' in attr_dict.keys(): - attrs['attr_info'][attr_dict['name']] = ( - optional_types_trans[attr_dict['typename']], - default_value, - ) - else: - attrs['attr_info'][attr_dict['name']] = ( - attr_types_map[attr_dict['typename']], - default_value, - ) - return inputs, attrs - - def parse_output(self, outputs_list): - - out_type_list = [] - out_name_list = [] - out_size_expr_list = [] - for output_dict in outputs_list: - if output_dict['intermediate']: - continue - out_type_list.append(output_dict['typename']) - out_name_list.append(output_dict['name']) - if 'size' in output_dict.keys(): - out_size_expr_list.append(output_dict['size']) - else: - out_size_expr_list.append(None) - return out_type_list, out_name_list, out_size_expr_list - - -class EagerPrimAPI(BaseAPI): - def __init__(self, api_item_yaml, prims=tuple()): - super().__init__(api_item_yaml, prims) - - def get_api__func_name(self): - api_func_name = self.api - # if self.is_inplace: - # if api_func_name[-1] != '_': - # api_func_name += '_' - # print("after api name", api_func_name) - return api_func_name - - def gene_prim_api_declaration(self): - api_declaration = "" - api_func_name = self.get_api__func_name() - if api_func_name[-1] != '_': - api_declaration = f""" -template -{self.get_return_type()} {api_func_name}({self.get_declare_args()}); -""" - else: - api_declaration = ( - api_declaration - + f""" -template -{self.get_return_type(inplace_flag=True)} {api_func_name}({self.get_declare_args(inplace_flag=True)}); -""" - ) - - return api_declaration - - def get_ad_func_input_args(self, inplace_flag=False): - input_args = [] - for name in self.inputs['names']: - name = name.split('@')[0] - if inplace_flag and name in self.inplace_map.values(): - input_args.append(name) - else: - input_args.append(name) - return input_args - - def get_ad_func_args(self, inplace_flag=False): - ad_func_args = self.get_ad_func_input_args(inplace_flag) - for name in self.attrs['names']: - default_value = '' - if self.attrs['attr_info'][name][1] is not None: - default_value = ' = ' + self.attrs['attr_info'][name][1] - ad_func_args.append(name) - - ad_func_args_str = ", ".join(ad_func_args) - return ad_func_args_str - - def gene_ad_func_call(self): - api_func_name = self.get_api__func_name() - - dygraph_ad_func_name = '::' + api_func_name + '_ad_func' - dygraph_ad_func_parameters = self.get_ad_func_args() - - ad_func_call_str = f""" -VLOG(4) << "Eager Prim API {api_func_name}_ad_func call"; -return {dygraph_ad_func_name}({dygraph_ad_func_parameters}); -""" - # print("ad_func_call_str: ", ad_func_call_str) - return ad_func_call_str - - def gene_eager_prim_api_code(self): - api_code = "" - indent = " " - api_func_name = self.get_api__func_name() - template = '' - # func decalaration - if api_func_name[-1] != '_': - api_code = f""" -template <> -{self.get_return_type()} {api_func_name}{template}({self.get_declare_args_nodefault()}) -""" - else: - api_code = f""" -template <> -{self.get_return_type(inplace_flag=True)} {api_func_name}{template}({self.get_declare_args_nodefault(inplace_flag=True)}) -""" - # func code - - api_code = api_code + '{' - api_code += f"""{self.gene_ad_func_call()}""" - api_code += '}' + '\n' - - return api_code