未验证 提交 c36c7199 编写于 作者: H HongyuJia 提交者: GitHub

[Autogen Tensor API] Autogen `tensor_api.cc` (#50642)

* polish tensor operants implementation

* change year, 2021->2023

* autogen tensor.h and tensor_api.cc

* polish CMakeLists logic

* cancel tensor.h auto-gen

* clean useless parameter

* delete tensor_api.cc
上级 43622a20
......@@ -21,6 +21,7 @@ paddle/phi/api/lib/operants_manager.cc
paddle/phi/api/lib/sparse_api.cc
paddle/phi/api/lib/strings_api.cc
paddle/phi/api/lib/sparse_bw_api.cc
paddle/phi/api/lib/tensor_api.cc
paddle/phi/api/lib/tensor_operants.cc
paddle/phi/extension.h
paddle/phi/include/*
......
......@@ -645,6 +645,13 @@ class PADDLE_API Tensor final {
* in the development of new dygraph. It may be removed in the future.
*/
std::string name_{""};
// 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;
};
} // namespace experimental
......
......@@ -102,6 +102,7 @@ set(tensor_gen_file
${CMAKE_SOURCE_DIR}/paddle/phi/api/yaml/generator/tensor_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)
set(phi_tensor_operants_header_file
${CMAKE_SOURCE_DIR}/paddle/phi/api/include/tensor_operants.h)
set(phi_tensor_operants_source_file
......@@ -111,6 +112,7 @@ set(operants_manager_header_file
set(operants_manager_source_file
${CMAKE_SOURCE_DIR}/paddle/phi/api/lib/operants_manager.cc)
set(operants_base_file_tmp ${operants_base_file}.tmp)
set(tensor_api_source_file_tmp ${tensor_api_source_file}.tmp)
set(phi_tensor_operants_header_file_tmp ${phi_tensor_operants_header_file}.tmp)
set(phi_tensor_operants_source_file_tmp ${phi_tensor_operants_source_file}.tmp)
set(operants_manager_header_file_tmp ${operants_manager_header_file}.tmp)
......@@ -235,35 +237,43 @@ add_custom_command(
VERBATIM)
# generate tensor and tensor operants file
add_custom_command(
OUTPUT ${operants_base_file} ${phi_tensor_operants_header_file}
${phi_tensor_operants_source_file} ${operants_manager_header_file}
${operants_manager_source_file}
COMMAND ${PYTHON_EXECUTABLE} -m pip install pyyaml
message("create or copy auto-geneated tensor files")
execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip install pyyaml)
execute_process(
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/paddle/phi/api/yaml/generator
COMMAND
${PYTHON_EXECUTABLE} ${tensor_gen_file} --api_yaml_path ${api_yaml_file}
${legacy_api_yaml_file} --operants_base_path ${operants_base_file_tmp}
--tensor_api_source_path ${tensor_api_source_file_tmp}
--phi_tensor_operants_header_path ${phi_tensor_operants_header_file_tmp}
--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}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${operants_base_file_tmp}
${operants_base_file}
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${phi_tensor_operants_header_file_tmp}
${phi_tensor_operants_header_file}
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${phi_tensor_operants_source_file_tmp}
${phi_tensor_operants_source_file}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${operants_manager_header_file_tmp} ${operants_manager_header_file}
RESULT_VARIABLE _result)
if(${_result})
message(FATAL_ERROR "tensor codegen failed, exiting.")
endif()
set(generated_tensor_files
"${operants_base_file}" "${tensor_api_source_file}"
"${phi_tensor_operants_header_file}" "${phi_tensor_operants_source_file}"
"${operants_manager_header_file}" "${operants_manager_source_file}")
foreach(generated_tensor_file ${generated_tensor_files})
if(EXISTS "${generated_tensor_file}.tmp" AND EXISTS
"${generated_tensor_file}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${operants_manager_source_file_tmp} ${operants_manager_source_file}
COMMENT
"copy_if_different ${phi_tensor_operants_header_file} ${phi_tensor_operants_source_file}"
DEPENDS ${api_yaml_file} ${legacy_api_yaml_file} ${tensor_gen_file}
${api_gen_base} ${api_gen_file}
VERBATIM)
"${generated_tensor_file}.tmp" "${generated_tensor_file}")
message(
"copy if different ${generated_tensor_file}.tmp ${generated_tensor_file}")
elseif(EXISTS "${generated_tensor_file}.tmp")
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "${generated_tensor_file}.tmp"
"${generated_tensor_file}")
message("copy ${generated_tensor_file}.tmp ${generated_tensor_file}")
endif()
endforeach()
cc_library(
op_meta_info
......@@ -388,5 +398,5 @@ cc_library(
DEPS phi_enforce)
cc_library(
tensor_api
SRCS tensor_api.cc
SRCS ${tensor_api_source_file}
DEPS operants_manager)
/* Copyright (c) 2023 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/api/include/tensor.h"
#include "paddle/phi/api/include/operants_manager.h"
namespace paddle {
namespace experimental {
Tensor Tensor::operator+(const Tensor &other) const {
return paddle::OperantsManager::Instance().add(
static_cast<const Tensor &>(*this), other);
}
Tensor Tensor::operator-(const Tensor &other) const {
return paddle::OperantsManager::Instance().subtract(
static_cast<const Tensor &>(*this), other);
}
Tensor Tensor::operator*(const Tensor &other) const {
return paddle::OperantsManager::Instance().multiply(
static_cast<const Tensor &>(*this), other);
}
Tensor Tensor::operator/(const Tensor &other) const {
return paddle::OperantsManager::Instance().divide(
static_cast<const Tensor &>(*this), other);
}
} // namespace experimental
} // namespace paddle
......@@ -58,6 +58,43 @@ operants_base_end = """};
"""
tensor_api_source_include = """// Generated by paddle/phi/api/yaml/generator/tensor_gen.py
#include "paddle/phi/api/include/tensor.h"
#include "paddle/phi/api/include/operants_manager.h"
"""
tensor_api_source_start = """
namespace paddle {
namespace experimental {
Tensor Tensor::operator+(const Tensor &other) const {
return add(other);
}
Tensor Tensor::operator-(const Tensor &other) const {
return subtract(other);
}
Tensor Tensor::operator*(const Tensor &other) const {
return multiply(other);
}
Tensor Tensor::operator/(const Tensor &other) const {
return divide(other);
}
"""
tensor_api_source_end = """
} // namespace experimental
} // namespace paddle
"""
operants_header_include = """// Generated by paddle/phi/api/yaml/generator/tensor_gen.py
......@@ -231,6 +268,40 @@ class OperantsAPI(ForwardAPI):
else:
return f"""
{indent}virtual {self.get_return_type(inplace_flag=True)} {api_func_name}({self.get_declare_args(inplace_flag=True)}) = 0;
"""
def get_define_args_without_first_tensor(self, inplace_flag=False):
# NOTE(HongyuJia): consider vector<Tensor> becomes first input argument.
define_args = self.get_input_tensor_args(inplace_flag)
assert (
len(define_args) > 1
), "Can't use tensor api without Tensor inputs"
for name in self.attrs['names']:
define_args.append(self.attrs['attr_info'][name][0] + ' ' + name)
# remove first Tensor argument
return ", ".join(define_args[1:])
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"
# remove first Tensor argument
func_args = self.inputs['names'][1:] + self.attrs['names']
func_args_code = ", ".join(func_args)
# 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<const Tensor &>(*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<const Tensor &>(*this), {func_args_code});
}}
"""
def gene_operants_declaration(self):
......@@ -318,6 +389,7 @@ class OperantsAPI(ForwardAPI):
def generate_tensor_operants_api(
api_yaml_path,
operants_base_path,
tensor_api_source_path,
operants_header_path,
operants_source_path,
operants_manager_header_path,
......@@ -332,6 +404,7 @@ def generate_tensor_operants_api(
apis.extend(api_list)
operants_base_file = open(operants_base_path, 'w')
tensor_api_source_file = open(tensor_api_source_path, 'w')
operants_header_file = open(operants_header_path, 'w')
operants_source_file = open(operants_source_path, 'w')
operants_manager_header_file = open(operants_manager_header_path, 'w')
......@@ -339,6 +412,8 @@ def generate_tensor_operants_api(
operants_base_file.write(operants_base_include)
operants_base_file.write(operants_base_start)
tensor_api_source_file.write(tensor_api_source_include)
tensor_api_source_file.write(tensor_api_source_start)
operants_header_file.write(operants_header_include)
operants_header_file.write(operants_header_start)
operants_source_file.write(operants_source_include)
......@@ -355,6 +430,9 @@ def generate_tensor_operants_api(
operants_api = OperantsAPI(api, api_prims)
if operants_api.is_prim_api:
operants_base_file.write(operants_api.gene_operants_base())
tensor_api_source_file.write(
operants_api.gene_tensor_api_implementation()
)
operants_header_file.write(operants_api.gene_operants_declaration())
operants_source_file.write(
operants_api.gene_operants_implementation()
......@@ -367,12 +445,14 @@ def generate_tensor_operants_api(
)
operants_base_file.write(operants_base_end)
tensor_api_source_file.write(tensor_api_source_end)
operants_header_file.write(operants_header_end)
operants_source_file.write(operants_source_end)
operants_manager_header_file.write(operants_manager_header_end)
operants_manager_source_file.write(operants_manager_source_end)
operants_base_file.close()
tensor_api_source_file.close()
operants_header_file.close()
operants_source_file.close()
operants_manager_header_file.close()
......@@ -396,6 +476,12 @@ def main():
default='paddle/phi/api/include/operants_base.h',
)
parser.add_argument(
'--tensor_api_source_path',
help='output of generated tensor_api source code file',
default='paddle/phi/api/lib/tensor_api.cc',
)
parser.add_argument(
'--phi_tensor_operants_header_path',
help='output of generated phi_tensor_operants header code file',
......@@ -424,6 +510,7 @@ def main():
api_yaml_path = options.api_yaml_path
operants_base_path = options.operants_base_path
tensor_api_source_path = options.tensor_api_source_path
operants_header_path = options.phi_tensor_operants_header_path
operants_source_path = options.phi_tensor_operants_source_path
operants_manager_header_path = options.operants_manager_header_path
......@@ -432,6 +519,7 @@ def main():
generate_tensor_operants_api(
api_yaml_path,
operants_base_path,
tensor_api_source_path,
operants_header_path,
operants_source_path,
operants_manager_header_path,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册