Commit 60f60093 authored by Artur Wojcik's avatar Artur Wojcik
Browse files

convert 'make generate' to Python

parent a7b7ddfb
......@@ -22,4 +22,16 @@
# THE SOFTWARE.
#####################################################################################
add_custom_target(generate ${CMAKE_COMMAND} -P generate.cmake WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
find_package(Python 3 COMPONENTS Interpreter)
if(NOT Python_EXECUTABLE)
message(WARNING "Python 3 interpreter not found - skipping 'generate' target!")
return()
endif()
find_program(CLANG_FORMAT clang-format PATHS /opt/rocm/llvm $ENV{HIP_PATH})
if(NOT CLANG_FORMAT)
message(WARNING "clang-format not found - skipping 'generate' target!")
return()
endif()
add_custom_target(generate ${Python_EXECUTABLE} generate.py -f ${CLANG_FORMAT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
......@@ -27,6 +27,7 @@ import re
import runpy
from functools import wraps
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
from pathlib import Path
type_map: Dict[str, Callable[['Parameter'], None]] = {}
cpp_type_map: Dict[str, str] = {}
......@@ -678,6 +679,10 @@ def add_function(name: str, *args, **kwargs) -> Function:
return f
def register_functions(path: Union[Path, str]) -> None:
runpy.run_path(path if isinstance(path, str) else str(path))
def once(f: Callable) -> Any:
@wraps(f)
def decorated(*args, **kwargs):
......@@ -1281,11 +1286,14 @@ def template_eval(template, **kwargs):
return template
def invoke(path: Union[Path, str]) -> str:
return template_eval(open(path).read())
def run(args: List[str]) -> None:
runpy.run_path(args[0])
register_functions(args[0])
if len(args) > 1:
f = open(args[1]).read()
r = template_eval(f)
r = invoke(args[1])
sys.stdout.write(r)
else:
sys.stdout.write(generate_c_header())
......
#####################################################################################
# The MIT License (MIT)
#
# Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
# Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -21,62 +21,69 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#####################################################################################
import os, sys, argparse, subprocess, te, api
from pathlib import Path
find_program(CLANG_FORMAT clang-format PATHS /opt/rocm/llvm $ENV{HIP_PATH})
if(NOT CLANG_FORMAT)
message(WARNING "clang-format not found - skipping 'generate' target!")
return()
endif()
clang_format_path = Path('clang-format.exe' if os.name ==
'nt' else '/opt/rocm/llvm/bin/clang-format')
work_dir = Path().cwd()
src_dir = (work_dir / '../src').absolute()
migraphx_py_path = src_dir / 'api/migraphx.py'
cmake_path(NATIVE_PATH CLANG_FORMAT NORMALIZE __clang_format)
if(WIN32)
set(__clang_format "C:${__clang_format}")
endif()
find_package(Python 3 COMPONENTS Interpreter)
if(NOT Python_EXECUTABLE)
message(WARNING "Python 3 interpreter not found - skipping 'generate' target!")
return()
endif()
def clang_format(buffer, **kwargs):
return subprocess.run(f'{clang_format_path} -style=file',
capture_output=True,
shell=True,
check=True,
input=buffer.encode('utf-8'),
cwd=work_dir,
**kwargs).stdout.decode('utf-8')
cmake_path(SET SRC_DIR NORMALIZE ${CMAKE_CURRENT_LIST_DIR}/../src)
file(GLOB __files ${CMAKE_CURRENT_LIST_DIR}/include/*.hpp)
foreach(__file ${__files})
cmake_path(NATIVE_PATH __file NORMALIZE __input_native_path)
cmake_path(GET __file FILENAME __file_name)
cmake_path(SET __output_path "${SRC_DIR}/include/migraphx/${__file_name}")
cmake_path(NATIVE_PATH __output_path __output_native_path)
message("Generating ${__output_native_path}")
execute_process(
COMMAND ${Python_EXECUTABLE} te.py ${__input_native_path} | ${__clang_format} -style=file
OUTPUT_FILE ${__output_native_path}
ERROR_VARIABLE __error_code
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
if(__error_code)
message(WARNING "${__error_code}")
endif()
endforeach()
def api_generate(input_path: Path, output_path: Path):
with open(output_path, 'w') as f:
f.write(clang_format(api.invoke(input_path)))
function(generate_api __input_path __output_path)
cmake_path(NATIVE_PATH __output_path NORMALIZE __output_native_path)
cmake_path(NATIVE_PATH __input_path NORMALIZE __input_native_path)
cmake_path(SET __migraphx_py_path "${SRC_DIR}/api/migraphx.py")
cmake_path(NATIVE_PATH __migraphx_py_path __migraphx_py_native_path)
cmake_path(SET __api_py_path "${CMAKE_CURRENT_LIST_DIR}/api.py")
cmake_path(NATIVE_PATH __api_py_path __api_py_native_path)
message("Generating ${__output_native_path}")
execute_process(
COMMAND ${Python_EXECUTABLE} ${__api_py_native_path} ${__migraphx_py_native_path} ${__input_native_path} | ${__clang_format} -style=file
OUTPUT_FILE ${__output_native_path}
ERROR_VARIABLE __error_code
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
if(__error_code)
message(WARNING "${__error_code}")
endif()
endfunction()
generate_api("${CMAKE_CURRENT_LIST_DIR}/api/migraphx.h" "${SRC_DIR}/api/include/migraphx/migraphx.h")
generate_api("${CMAKE_CURRENT_LIST_DIR}/api/api.cpp" "${SRC_DIR}/api/api.cpp")
def te_generate(input_path: Path, output_path: Path):
with open(output_path, 'w') as f:
f.write(clang_format(te.invoke(input_path)))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--clang-format', type=Path)
args = parser.parse_args()
global clang_format_path
if args.clang_format:
clang_format_path = args.clang_format
if not clang_format_path.is_file():
print(f"{clang_format_path}: invalid path or not installed",
file=sys.stderr)
return
try:
for f in [
f for f in Path('include').absolute().iterdir() if f.is_file()
]:
te_generate(f, src_dir / f'include/migraphx/{f.name}')
api.register_functions(str(migraphx_py_path))
api_generate(work_dir / 'api/migraphx.h',
src_dir / 'api/include/migraphx/migraphx.h')
print('Finished generating header migraphx.h')
api_generate(work_dir / 'api/api.cpp', src_dir / 'api/api.cpp')
print('Finished generating source api.cpp')
except subprocess.CalledProcessError as ex:
if ex.stdout:
print(ex.stdout.decode('utf-8'))
if ex.stderr:
print(ex.stdout.decode('utf-8'))
print(f"Command '{ex.cmd}' returned {ex.returncode}")
raise
if __name__ == "__main__":
main()
......@@ -431,6 +431,9 @@ def template_eval(template, **kwargs):
return template
f = open(sys.argv[1]).read()
r = template_eval(f)
sys.stdout.write(r)
def invoke(p):
return template_eval(open(p).read())
if __name__ == '__main__':
sys.stdout.write(invoke(sys.argv[1]))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment