Files
2026-07-13 12:40:42 +08:00

116 lines
3.9 KiB
Python

# 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.
# Notice: This file will be automatically executed during building of whole paddle project.
# You can also run this file separately if you want to preview generated file without building.
import argparse
import json
import re
import yaml
def ParseArguments():
parser = argparse.ArgumentParser(
description='prim ops Code Generator Args Parser'
)
parser.add_argument('--ops_yaml_path', type=str, help="path to ops.yaml")
parser.add_argument(
'--ops_legacy_yaml_path', type=str, help="path to dygraph_ops.yaml"
)
parser.add_argument(
'--ops_compat_yaml_path', type=str, help="path to op_compat.yaml"
)
parser.add_argument(
'--phi_ops_map_path',
type=str,
default="./phi_ops_map.py",
help='path to target phi_ops_map.py',
)
args = parser.parse_args()
return args
def _trans_value_type(item):
for key in item.keys():
for subkey in item[key]:
value = str(item[key][subkey])
item[key][subkey] = value
def generate_code(
ops_yaml_path, ops_legacy_yaml_path, ops_compat_yaml_path, phi_ops_map_path
):
"""
Generate dictionary and save to file phi_ops_map.py. The target file records gap
of description between current op and standard ones.
"""
dct = {}
map_dct = {}
for op_path in [ops_yaml_path, ops_legacy_yaml_path]:
pattern = re.compile(r'[(](.*)[)]', re.DOTALL)
with open(op_path, "rt") as f:
ops = yaml.safe_load(f)
for item in ops:
key = item['op']
if key in dct:
raise ValueError(f"There already exists op {key}")
dct[key] = {
"args": re.findall(pattern, item["args"])[0],
"output": item["output"],
}
with open(ops_compat_yaml_path, "rt") as f:
ops_compat = yaml.safe_load(f)
for item in ops_compat:
key = item['op']
if key.endswith(")"):
tmp = re.match("(.*)\\((.*)\\)", key.replace(" ", ""))
phi_name, op_name = tmp.group(1), tmp.group(2)
map_dct[op_name] = {"phi_name": phi_name}
else:
op_name = key
map_dct[op_name] = {"phi_name": op_name}
for element in ["inputs", "outputs", "attrs"]:
if element in item.keys():
map_dct[op_name][element] = item[element]
for element in ["scalar", "int_array"]:
if element in item.keys():
_trans_value_type(item[element])
map_dct[op_name][element] = item[element]
with open(phi_ops_map_path, "w") as f:
f.write("op_map = ")
json.dump(map_dct, f, indent=4)
f.write('\n')
f.write("op_info = ")
json.dump(dct, f, indent=4)
f.write('\n')
if __name__ == "__main__":
args = ParseArguments()
ops_yaml_path = args.ops_yaml_path
ops_legacy_yaml_path = args.ops_legacy_yaml_path
ops_compat_yaml_path = args.ops_compat_yaml_path
phi_ops_map_path = args.phi_ops_map_path
generate_code(
ops_yaml_path,
ops_legacy_yaml_path,
ops_compat_yaml_path,
phi_ops_map_path,
)