From a7677c8a127690caca619e02e817f562c3b2866c Mon Sep 17 00:00:00 2001 From: jjwilke Date: Thu, 6 Apr 2023 10:40:45 -0700 Subject: [PATCH 1/6] add python generator script for project templates --- cmake/cpp_header_template | 34 +++++ cmake/cpp_source_template | 50 +++++++ cmake/legate_gen_library.in | 211 ++++++++++++++++++++++++++++ cmake/legate_helper_functions.cmake | 194 ++++--------------------- cmake/python_template | 54 +++++++ legate_core_cpp.cmake | 17 +++ setup.py | 2 +- 7 files changed, 391 insertions(+), 171 deletions(-) create mode 100644 cmake/cpp_header_template create mode 100644 cmake/cpp_source_template create mode 100644 cmake/legate_gen_library.in create mode 100644 cmake/python_template diff --git a/cmake/cpp_header_template b/cmake/cpp_header_template new file mode 100644 index 0000000000..657760b866 --- /dev/null +++ b/cmake/cpp_header_template @@ -0,0 +1,34 @@ +/* Copyright 2023 NVIDIA Corporation + * + * 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. + * + */ + +#pragma once + +#include "legate.h" + +namespace @target@ { + +struct Registry { + public: + static legate::TaskRegistrar& get_registrar(); +}; + +template +struct Task : public legate::LegateTask { + using Registrar = Registry; + static constexpr int TASK_ID = ID; +}; + +} diff --git a/cmake/cpp_source_template b/cmake/cpp_source_template new file mode 100644 index 0000000000..d51e1116a6 --- /dev/null +++ b/cmake/cpp_source_template @@ -0,0 +1,50 @@ +/* Copyright 2023 NVIDIA Corporation + * + * 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 "legate_library.h" + +namespace @target@ { + +static const char* const library_name = "@target@"; + +Legion::Logger log_@target@(library_name); + +/*static*/ legate::TaskRegistrar& Registry::get_registrar() +{ + static legate::TaskRegistrar registrar; + return registrar; +} + +void registration_callback() +{ + auto context = legate::Runtime::get_runtime()->create_library(library_name); + + Registry::get_registrar().register_all_tasks(context); +} + +} // namespace @target@ + +extern "C" { + +void @target@_perform_registration(void) +{ + // Tell the runtime about our registration callback so we hook it + // in before the runtime starts and make it global so that we know + // that this call back is invoked everywhere across all nodes + legate::Core::perform_registration<@target@::registration_callback>(); +} + +} diff --git a/cmake/legate_gen_library.in b/cmake/legate_gen_library.in new file mode 100644 index 0000000000..295355b89d --- /dev/null +++ b/cmake/legate_gen_library.in @@ -0,0 +1,211 @@ +#! /usr/bin/env python + +from __future__ import annotations + +import os +import stat +import sys +from pathlib import Path +from typing import Union + +if len(sys.argv) != 2: + sys.exit("Must give a single argument with the library name") +libname = sys.argv[1] + +cpp_source_template = """ +@cpp_source_template@ +""" + +cpp_header_template = """ +@cpp_header_template@ +""" + +python_template = """ +@python_template@ +""" + + +cmake_toplevel_template = """ +#============================================================================= +# Copyright 2023 NVIDIA Corporation +# +# 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. +#============================================================================= + +cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR) + +project($target VERSION 1.0 LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 17) +set(BUILD_SHARED_LIBS ON) + +find_package(legate_core REQUIRED) + +legate_add_cpp_subdirectory(src TARGET $target EXPORT $target-export) + +legate_add_cffi(${CMAKE_CURRENT_SOURCE_DIR}/src/$target_cffi.h TARGET $target) +legate_default_python_install($target EXPORT $target-export) +""" + +cmake_src_template = """ +#============================================================================= +# Copyright 2023 NVIDIA Corporation +# +# 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. +#============================================================================= + +add_library( + $target + legate_library.h + legate_library.cc +) + +target_include_directories($target + PRIVATE + $ + INTERFACE + $ +) + +target_link_libraries($target PRIVATE legate::core) +""" + +setup_template = """ +#!/usr/bin/env python3 + +# Copyright 2023 NVIDIA Corporation +# +# 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. +# +import os +from pathlib import Path + +from setuptools import find_packages +from skbuild import setup + +import legate.install_info as lg_install_info + +legate_dir = Path(lg_install_info.libpath).parent.as_posix() + +cmake_flags = [ + f"-Dlegate_core_ROOT:STRING={legate_dir}", +] + +env_cmake_args = os.environ.get("CMAKE_ARGS") +if env_cmake_args is not None: + cmake_flags.append(env_cmake_args) +os.environ["CMAKE_ARGS"] = " ".join(cmake_flags) + + +setup( + name="Legate $target", + version="0.1", + description="$target for Legate", + author="NVIDIA Corporation", + license="Apache 2.0", + classifiers=[ + "Intended Audience :: Developers", + "Topic :: Database", + "Topic :: Scientific/Engineering", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + ], + packages=find_packages( + where=".", + include=["$target", "$target.*"], + ), + include_package_data=True, + zip_safe=False, +) +""" + +editable_script = """ +legate_root=`python -c 'import legate.install_info as i; from pathlib import Path; print(Path(i.libpath).parent.resolve())'` +echo "Using Legate at $legate_root" +cmake -S . -B build -D legate_core_ROOT=$legate_root +cmake --build build +python -m pip install -e . -vv +""" + +install_script = """ +python -m pip install . +""" + +def generate_file(libname: str, template: str, path: Union[Path,str], executable: bool = False): + target_path = Path(libname) / Path(path) + if not target_path.parent.is_dir(): + target_path.parent.mkdir(parents=True) + + text = template.replace("$target", libname) + text = text.replace("@" "target" "@", libname) + with open(target_path, "w") as f: + f.write(text) + + if executable: + st = os.stat(target_path) + os.chmod(target_path, st.st_mode | stat.S_IRWXU) + +cffi_template = """ +/* Copyright 2023 NVIDIA Corporation + * + * 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. + * + */ + +enum $targetOpCode { +}; +""" + +generate_file(libname, cpp_source_template, "src/legate_library.cc") +generate_file(libname, cpp_header_template, "src/legate_library.h") +generate_file(libname, python_template, Path(libname) / f"{libname}.py") +generate_file(libname, "", Path(libname) / "__init__.py") +generate_file(libname, setup_template, "setup.py") +generate_file(libname, editable_script, "editable-install.sh", executable=True) +generate_file(libname, install_script, "install.sh", executable=True) +generate_file(libname, cmake_toplevel_template, "CMakeLists.txt") +generate_file(libname, cmake_src_template, "src/CMakeLists.txt") +generate_file(libname, cffi_template, f"src/{libname}_cffi.h") diff --git a/cmake/legate_helper_functions.cmake b/cmake/legate_helper_functions.cmake index 2f79006350..373ef38801 100644 --- a/cmake/legate_helper_functions.cmake +++ b/cmake/legate_helper_functions.cmake @@ -278,99 +278,10 @@ function(legate_add_cpp_subdirectory dir) endfunction() function(legate_cpp_library_template target output_sources_variable) - set(file_template -[=[ -/* Copyright 2023 NVIDIA Corporation - * - * 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. - * - */ - -#pragma once - -#include "legate.h" - -namespace @target@ { - -struct Registry { - static legate::TaskRegistrar& get_registrar(); -}; - -template -struct Task : public legate::LegateTask { - using Registrar = Registry; - static constexpr int TASK_ID = ID; -}; - -} -]=]) - string(CONFIGURE "${file_template}" file_content @ONLY) + string(CONFIGURE "${Legate_CPP_HEADER_TEMPLATE}" file_content @ONLY) file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/legate_library.h "${file_content}") - set(file_template -[=[ -/* Copyright 2023 NVIDIA Corporation - * - * 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 "legate_library.h" - -namespace @target@ { - -static const char* const library_name = "@target@"; - -Legion::Logger log_@target@(library_name); - -/*static*/ legate::TaskRegistrar& Registry::get_registrar() -{ - static legate::TaskRegistrar registrar; - return registrar; -} - -void registration_callback() -{ - auto context = legate::Runtime::get_runtime()->create_library(library_name); - - Registry::get_registrar().register_all_tasks(context); -} - -} // namespace @target@ - -extern "C" { - -void @target@_perform_registration(void) -{ - // Tell the runtime about our registration callback so we hook it - // in before the runtime starts and make it global so that we know - // that this call back is invoked everywhere across all nodes - legate::Core::perform_registration<@target@::registration_callback>(); -} - -} -]=]) - string(CONFIGURE "${file_template}" file_content @ONLY) + string(CONFIGURE "${Legate_CPP_SOURCE_TEMPLATE}" file_content @ONLY) file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/legate_library.cc "${file_content}") set(${output_sources_variable} @@ -381,88 +292,31 @@ void @target@_perform_registration(void) endfunction() function(legate_python_library_template py_path) -set(options) -set(one_value_args TARGET PY_IMPORT_PATH) -set(multi_value_args) -cmake_parse_arguments( - LEGATE_OPT - "${options}" - "${one_value_args}" - "${multi_value_args}" - ${ARGN} -) - -if (DEFINED LEGATE_OPT_TARGET) - set(target "${LEGATE_OPT_TARGET}") -else() - string(REPLACE "/" "_" target "${py_path}") -endif() - -if (DEFINED LEGATE_OPT_PY_IMPORT_PATH) - set(py_import_path "${LEGATE_OPT_PY_IMPORT_PATH}") -else() - string(REPLACE "/" "." py_import_path "${py_path}") -endif() - -set(fn_library "${CMAKE_CURRENT_SOURCE_DIR}/${py_path}/library.py") - -set(file_template -[=[ -# Copyright 2023 NVIDIA Corporation -# -# 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. -# - -from legate.core import ( - Library, - get_legate_runtime, -) -import os -from typing import Any - -class UserLibrary(Library): - def __init__(self, name: str) -> None: - self.name = name - self.shared_object: Any = None - - @property - def cffi(self) -> Any: - return self.shared_object - - def get_name(self) -> str: - return self.name - - def get_shared_library(self) -> str: - from @py_import_path@.install_info import libpath - return os.path.join(libpath, f"lib@target@{self.get_library_extension()}") - - def get_c_header(self) -> str: - from @py_import_path@.install_info import header - - return header + set(options) + set(one_value_args TARGET PY_IMPORT_PATH) + set(multi_value_args) + cmake_parse_arguments( + LEGATE_OPT + "${options}" + "${one_value_args}" + "${multi_value_args}" + ${ARGN} + ) - def get_registration_callback(self) -> str: - return "@target@_perform_registration" + if (DEFINED LEGATE_OPT_TARGET) + set(target "${LEGATE_OPT_TARGET}") + else() + string(REPLACE "/" "_" target "${py_path}") + endif() - def initialize(self, shared_object: Any) -> None: - self.shared_object = shared_object + if (DEFINED LEGATE_OPT_PY_IMPORT_PATH) + set(py_import_path "${LEGATE_OPT_PY_IMPORT_PATH}") + else() + string(REPLACE "/" "." py_import_path "${py_path}") + endif() - def destroy(self) -> None: - pass + set(fn_library "${CMAKE_CURRENT_SOURCE_DIR}/${py_path}/library.py") -user_lib = UserLibrary("@target@") -user_context = get_legate_runtime().register_library(user_lib) -]=]) - string(CONFIGURE "${file_template}" file_content @ONLY) + string(CONFIGURE "${Legate_PYTHON_TEMPLATE}" file_content @ONLY) file(WRITE "${fn_library}" "${file_content}") endfunction() diff --git a/cmake/python_template b/cmake/python_template new file mode 100644 index 0000000000..f8602a74c8 --- /dev/null +++ b/cmake/python_template @@ -0,0 +1,54 @@ +# Copyright 2023 NVIDIA Corporation +# +# 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. +# + +from legate.core import ( + Library, + get_legate_runtime, +) +import os +from typing import Any + +class UserLibrary(Library): + def __init__(self, name: str) -> None: + self.name = name + self.shared_object: Any = None + + @property + def cffi(self) -> Any: + return self.shared_object + + def get_name(self) -> str: + return self.name + + def get_shared_library(self) -> str: + from @py_import_path@.install_info import libpath + return os.path.join(libpath, f"lib@target@{self.get_library_extension()}") + + def get_c_header(self) -> str: + from @target@.install_info import header + + return header + + def get_registration_callback(self) -> str: + return "@target@_perform_registration" + + def initialize(self, shared_object: Any) -> None: + self.shared_object = shared_object + + def destroy(self) -> None: + pass + +user_lib = UserLibrary("@target@") +user_context = get_legate_runtime().register_library(user_lib) diff --git a/legate_core_cpp.cmake b/legate_core_cpp.cmake index 05f6394b40..dee32c6ead 100644 --- a/legate_core_cpp.cmake +++ b/legate_core_cpp.cmake @@ -464,6 +464,14 @@ Imported Targets: ]=]) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/legate_helper_functions.cmake helper_functions) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpp_source_template cpp_source_template) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpp_header_template cpp_header_template) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/python_template python_template) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/legate_gen_library.in + ${CMAKE_CURRENT_SOURCE_DIR}/legate_gen_library + FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + @ONLY) string(JOIN "\n" code_string [=[ @@ -481,6 +489,15 @@ if(Legion_NETWORKS) find_package(MPI REQUIRED COMPONENTS CXX) endif() ]=] +"set(Legate_CPP_HEADER_TEMPLATE [=[" +"${cpp_header_template}" +"]=])" +"set(Legate_CPP_SOURCE_TEMPLATE [=[" +"${cpp_source_template}" +"]=])" +"set(Legate_PYTHON_TEMPLATE [=[" +"${python_template}" +"]=])" "${helper_functions}" ) diff --git a/setup.py b/setup.py index 83912f31f8..a0e2dd68c3 100755 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ "lgpatch = legate.lgpatch:main", ], }, - scripts=["bind.sh"], + scripts=["bind.sh", "gen_library"], cmdclass=versioneer.get_cmdclass(), install_requires=["numpy>=1.22"], zip_safe=False, From 1d9264b6312a68845b553d204b29ac1db6d414d1 Mon Sep 17 00:00:00 2001 From: jjwilke Date: Mon, 10 Apr 2023 14:25:07 -0700 Subject: [PATCH 2/6] clearer file names --- cmake/{ => tmpl}/cpp_header_template | 0 cmake/{ => tmpl}/cpp_source_template | 0 .../create-legate-library.in} | 0 cmake/{ => tmpl}/python_template | 0 legate_core_cpp.cmake | 10 +++++----- setup.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename cmake/{ => tmpl}/cpp_header_template (100%) rename cmake/{ => tmpl}/cpp_source_template (100%) rename cmake/{legate_gen_library.in => tmpl/create-legate-library.in} (100%) rename cmake/{ => tmpl}/python_template (100%) diff --git a/cmake/cpp_header_template b/cmake/tmpl/cpp_header_template similarity index 100% rename from cmake/cpp_header_template rename to cmake/tmpl/cpp_header_template diff --git a/cmake/cpp_source_template b/cmake/tmpl/cpp_source_template similarity index 100% rename from cmake/cpp_source_template rename to cmake/tmpl/cpp_source_template diff --git a/cmake/legate_gen_library.in b/cmake/tmpl/create-legate-library.in similarity index 100% rename from cmake/legate_gen_library.in rename to cmake/tmpl/create-legate-library.in diff --git a/cmake/python_template b/cmake/tmpl/python_template similarity index 100% rename from cmake/python_template rename to cmake/tmpl/python_template diff --git a/legate_core_cpp.cmake b/legate_core_cpp.cmake index dee32c6ead..28fe72e4da 100644 --- a/legate_core_cpp.cmake +++ b/legate_core_cpp.cmake @@ -464,12 +464,12 @@ Imported Targets: ]=]) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/legate_helper_functions.cmake helper_functions) -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpp_source_template cpp_source_template) -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpp_header_template cpp_header_template) -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/python_template python_template) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/cpp_source_template cpp_source_template) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/cpp_header_template cpp_header_template) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/python_template python_template) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/legate_gen_library.in - ${CMAKE_CURRENT_SOURCE_DIR}/legate_gen_library +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/create-legate-library.in + ${CMAKE_CURRENT_SOURCE_DIR}/create-legate-library FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ @ONLY) diff --git a/setup.py b/setup.py index a0e2dd68c3..65007097e1 100755 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ "lgpatch = legate.lgpatch:main", ], }, - scripts=["bind.sh", "gen_library"], + scripts=["bind.sh", "create-legate-library"], cmdclass=versioneer.get_cmdclass(), install_requires=["numpy>=1.22"], zip_safe=False, From 1403abe9ddd0359890c64359c638fdb6b9d75b45 Mon Sep 17 00:00:00 2001 From: jjwilke Date: Thu, 25 May 2023 15:17:06 -0700 Subject: [PATCH 3/6] fix generator script --- cmake/tmpl/create-legate-library.in | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/tmpl/create-legate-library.in b/cmake/tmpl/create-legate-library.in index 295355b89d..1bece1a565 100644 --- a/cmake/tmpl/create-legate-library.in +++ b/cmake/tmpl/create-legate-library.in @@ -171,6 +171,7 @@ def generate_file(libname: str, template: str, path: Union[Path,str], executable text = template.replace("$target", libname) text = text.replace("@" "target" "@", libname) + text = text.replace("@" "py_import_path" "@", libname) with open(target_path, "w") as f: f.write(text) From 9afe26c0517885066d2f33de5d774f7eea998b08 Mon Sep 17 00:00:00 2001 From: jjwilke Date: Thu, 25 May 2023 16:34:47 -0700 Subject: [PATCH 4/6] cleanup of template library generation --- .gitignore | 2 +- CMakeLists.txt | 4 ++++ .../{create-legate-library.in => legate-create-library.in} | 0 examples/io/src/read_file.cc | 3 ++- legate_core_cpp.cmake | 5 ----- setup.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename cmake/tmpl/{create-legate-library.in => legate-create-library.in} (100%) diff --git a/.gitignore b/.gitignore index 7bcfe8bf45..9ab2e494b3 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,4 @@ config.mk _cmake_test_compile !cmake/versions.json legate.core.code-workspace - +legate-create-library diff --git a/CMakeLists.txt b/CMakeLists.txt index 72a4b7cc14..cb4d406a7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,3 +124,7 @@ if(CMAKE_GENERATOR STREQUAL "Ninja") add_touch_legate_core_ninja_build_target() endif() +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/legate-create-library.in + ${CMAKE_CURRENT_SOURCE_DIR}/legate-create-library + FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + @ONLY) diff --git a/cmake/tmpl/create-legate-library.in b/cmake/tmpl/legate-create-library.in similarity index 100% rename from cmake/tmpl/create-legate-library.in rename to cmake/tmpl/legate-create-library.in diff --git a/examples/io/src/read_file.cc b/examples/io/src/read_file.cc index 9d2c3f5601..fb96a71324 100644 --- a/examples/io/src/read_file.cc +++ b/examples/io/src/read_file.cc @@ -48,7 +48,8 @@ struct read_fn { // Compute the absolute offsets to the section that this reader task // is supposed to read from the file int64_t my_lo = my_id * size / num_readers; - int64_t my_hi = std::min((my_id + 1) * size / num_readers, size); + // force min comparison in int64_t + int64_t my_hi = std::min((my_id + 1) * size / num_readers, size); // Then compute the extent for the output and create the output buffer to populate int64_t my_ext = my_hi - my_lo; diff --git a/legate_core_cpp.cmake b/legate_core_cpp.cmake index 28fe72e4da..ad706d11ba 100644 --- a/legate_core_cpp.cmake +++ b/legate_core_cpp.cmake @@ -468,11 +468,6 @@ file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/cpp_source_template cpp_source_ file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/cpp_header_template cpp_header_template) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/python_template python_template) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/create-legate-library.in - ${CMAKE_CURRENT_SOURCE_DIR}/create-legate-library - FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - @ONLY) - string(JOIN "\n" code_string [=[ if(NOT TARGET legate::Thrust) diff --git a/setup.py b/setup.py index 65007097e1..0403d40564 100755 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ "lgpatch = legate.lgpatch:main", ], }, - scripts=["bind.sh", "create-legate-library"], + scripts=["bind.sh", "legate-create-library"], cmdclass=versioneer.get_cmdclass(), install_requires=["numpy>=1.22"], zip_safe=False, From fa85194b508d022439a89d866f08438dd6974b9f Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 3 Jun 2023 11:39:58 -0700 Subject: [PATCH 5/6] change legate library to regular script + package_data, add docs --- .gitignore | 1 - CMakeLists.txt | 4 - MANIFEST.in | 5 +- README.md | 26 +++++- ...create-library.in => legate-create-library | 91 +++++++++++-------- {cmake/tmpl => legate}/cpp_header_template | 2 +- {cmake/tmpl => legate}/cpp_source_template | 0 {cmake/tmpl => legate}/python_template | 0 8 files changed, 84 insertions(+), 45 deletions(-) rename cmake/tmpl/legate-create-library.in => legate-create-library (74%) mode change 100644 => 100755 rename {cmake/tmpl => legate}/cpp_header_template (97%) rename {cmake/tmpl => legate}/cpp_source_template (100%) rename {cmake/tmpl => legate}/python_template (100%) diff --git a/.gitignore b/.gitignore index 9ab2e494b3..c472c9da48 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,3 @@ config.mk _cmake_test_compile !cmake/versions.json legate.core.code-workspace -legate-create-library diff --git a/CMakeLists.txt b/CMakeLists.txt index cb4d406a7c..72a4b7cc14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,3 @@ if(CMAKE_GENERATOR STREQUAL "Ninja") add_touch_legate_core_ninja_build_target() endif() -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/legate-create-library.in - ${CMAKE_CURRENT_SOURCE_DIR}/legate-create-library - FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - @ONLY) diff --git a/MANIFEST.in b/MANIFEST.in index 9f4e99bebd..679a29d47c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,9 @@ include versioneer.py include legate/_version.py include legate/py.typed +include legate/cpp_source_template +include legate/cpp_header_template +include legate/python_template # include interface files -recursive-include legate *.pyi \ No newline at end of file +recursive-include legate *.pyi diff --git a/README.md b/README.md index 87d001510c..03bddf2947 100644 --- a/README.md +++ b/README.md @@ -417,6 +417,30 @@ Memory: Registered CPU-side pinned memory per rank (in MBs) : 0 ``` +## Getting Your Own Legate Project Started + + +### Hello World + +For basic code examples illustrating how Legate tasks are created +and enqueued, users can look at the [hello world](examples/hello/README.md) example. +The folder includes both a basic "Hello World" as well numerical +examples like variance showing both elementwise array operations +and distributed reductions. + +### Library Template + +To bootstrap your own Legate library, the `legate-create-library` script +can be used to generate both the build system and initial set of +C++ and Python files. + +```bash +$ legate-create-library myproject +$ ls myproject +CMakeLists.txt editable-install.sh install.sh myproject setup.py src +``` + + ## Other FAQs * *Does Legate only work on NVIDIA hardware?* @@ -465,7 +489,7 @@ See the discussion of contributing in [CONTRIBUTING.md](CONTRIBUTING.md). ## Documentation -A complete list of available features can is found in the [Legate Core +A complete list of available features can be found in the [Legate Core documentation](https://nv-legate.github.io/legate.core). ## Next Steps diff --git a/cmake/tmpl/legate-create-library.in b/legate-create-library old mode 100644 new mode 100755 similarity index 74% rename from cmake/tmpl/legate-create-library.in rename to legate-create-library index 1bece1a565..8f4906a5c1 --- a/cmake/tmpl/legate-create-library.in +++ b/legate-create-library @@ -2,28 +2,36 @@ from __future__ import annotations +import argparse +import importlib.resources import os import stat import sys from pathlib import Path from typing import Union -if len(sys.argv) != 2: - sys.exit("Must give a single argument with the library name") -libname = sys.argv[1] +parser = argparse.ArgumentParser() -cpp_source_template = """ -@cpp_source_template@ -""" +parser.add_argument("name", type=str, help="The name of the Legate library") -cpp_header_template = """ -@cpp_header_template@ -""" +args, _ = parser.parse_known_args() + + +libname = args.name +if not libname.isidentifier(): + sys.exit(f"Name '{libname}' is not valid, must be a C++/Python name") + +package_data_root = importlib.resources.files("legate") -python_template = """ -@python_template@ -""" +def get_template(relpath): + with open(package_data_root / relpath) as f: + return f.read() + + +cpp_source_template = get_template("cpp_source_template") +cpp_header_template = get_template("cpp_header_template") +python_template = get_template("python_template") cmake_toplevel_template = """ #============================================================================= @@ -44,18 +52,18 @@ cmake_toplevel_template = """ cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR) -project($target VERSION 1.0 LANGUAGES C CXX) +project(@target@ VERSION 1.0 LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) set(BUILD_SHARED_LIBS ON) find_package(legate_core REQUIRED) -legate_add_cpp_subdirectory(src TARGET $target EXPORT $target-export) +legate_add_cpp_subdirectory(src TARGET @target@ EXPORT @target@-export) -legate_add_cffi(${CMAKE_CURRENT_SOURCE_DIR}/src/$target_cffi.h TARGET $target) -legate_default_python_install($target EXPORT $target-export) -""" +legate_add_cffi(${CMAKE_CURRENT_SOURCE_DIR}/src/@target@_cffi.h TARGET @target@) +legate_default_python_install(@target@ EXPORT @target@-export) +""" # noqa: E501 cmake_src_template = """ #============================================================================= @@ -75,19 +83,19 @@ cmake_src_template = """ #============================================================================= add_library( - $target + @target@ legate_library.h legate_library.cc ) -target_include_directories($target +target_include_directories(@target@ PRIVATE $ INTERFACE $ ) -target_link_libraries($target PRIVATE legate::core) +target_link_libraries(@target@ PRIVATE legate::core) """ setup_template = """ @@ -128,9 +136,9 @@ os.environ["CMAKE_ARGS"] = " ".join(cmake_flags) setup( - name="Legate $target", + name="Legate @target@", version="0.1", - description="$target for Legate", + description="@target@ for Legate", author="NVIDIA Corporation", license="Apache 2.0", classifiers=[ @@ -145,7 +153,7 @@ setup( ], packages=find_packages( where=".", - include=["$target", "$target.*"], + include=["@target@", "@target@.*"], ), include_package_data=True, zip_safe=False, @@ -158,26 +166,35 @@ echo "Using Legate at $legate_root" cmake -S . -B build -D legate_core_ROOT=$legate_root cmake --build build python -m pip install -e . -vv -""" +""" # noqa: E501 install_script = """ python -m pip install . """ -def generate_file(libname: str, template: str, path: Union[Path,str], executable: bool = False): - target_path = Path(libname) / Path(path) - if not target_path.parent.is_dir(): - target_path.parent.mkdir(parents=True) - text = template.replace("$target", libname) - text = text.replace("@" "target" "@", libname) - text = text.replace("@" "py_import_path" "@", libname) - with open(target_path, "w") as f: - f.write(text) +def generate_file( + libname: str, + template: str, + path: Union[Path, str], + executable: bool = False, +): + target_path = Path(libname) / Path(path) + if not target_path.parent.is_dir(): + target_path.parent.mkdir(parents=True) + + # Use CMake @ONLY for template substitution instead + # of string.Template so that CMake and Python + # share a common set of templates. + text = template.replace("@target@", libname) + text = text.replace("@py_import_path@", libname) + with open(target_path, "w") as f: + f.write(text) + + if executable: + st = os.stat(target_path) + os.chmod(target_path, st.st_mode | stat.S_IRWXU) - if executable: - st = os.stat(target_path) - os.chmod(target_path, st.st_mode | stat.S_IRWXU) cffi_template = """ /* Copyright 2023 NVIDIA Corporation @@ -196,7 +213,7 @@ cffi_template = """ * */ -enum $targetOpCode { +enum OpCode { }; """ diff --git a/cmake/tmpl/cpp_header_template b/legate/cpp_header_template similarity index 97% rename from cmake/tmpl/cpp_header_template rename to legate/cpp_header_template index 657760b866..e05d0ff138 100644 --- a/cmake/tmpl/cpp_header_template +++ b/legate/cpp_header_template @@ -18,7 +18,7 @@ #include "legate.h" -namespace @target@ { +namespace @targe@ { struct Registry { public: diff --git a/cmake/tmpl/cpp_source_template b/legate/cpp_source_template similarity index 100% rename from cmake/tmpl/cpp_source_template rename to legate/cpp_source_template diff --git a/cmake/tmpl/python_template b/legate/python_template similarity index 100% rename from cmake/tmpl/python_template rename to legate/python_template From 4e356b66a84c15deb330c051915658a1c496efe5 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 5 Jun 2023 15:04:26 -0700 Subject: [PATCH 6/6] more type-o fixes --- legate/cpp_header_template | 2 +- legate_core_cpp.cmake | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/legate/cpp_header_template b/legate/cpp_header_template index e05d0ff138..657760b866 100644 --- a/legate/cpp_header_template +++ b/legate/cpp_header_template @@ -18,7 +18,7 @@ #include "legate.h" -namespace @targe@ { +namespace @target@ { struct Registry { public: diff --git a/legate_core_cpp.cmake b/legate_core_cpp.cmake index ad706d11ba..9683256cc1 100644 --- a/legate_core_cpp.cmake +++ b/legate_core_cpp.cmake @@ -464,9 +464,9 @@ Imported Targets: ]=]) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/legate_helper_functions.cmake helper_functions) -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/cpp_source_template cpp_source_template) -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/cpp_header_template cpp_header_template) -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tmpl/python_template python_template) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/legate/cpp_source_template cpp_source_template) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/legate/cpp_header_template cpp_header_template) +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/legate/python_template python_template) string(JOIN "\n" code_string [=[