Skip to content

Commit

Permalink
add python generator script for project templates
Browse files Browse the repository at this point in the history
  • Loading branch information
jjwilke committed Apr 6, 2023
1 parent 9d2504d commit d41b048
Show file tree
Hide file tree
Showing 7 changed files with 440 additions and 221 deletions.
39 changes: 39 additions & 0 deletions cmake/cpp_header_template
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* 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:
template <typename... Args>
static void record_variant(Args&&... args)
{
get_registrar().record_variant(std::forward<Args>(args)...);
}
static legate::TaskRegistrar& get_registrar();
};

template <typename T, int ID>
struct Task : public legate::LegateTask<T> {
using Registrar = Registry;
static constexpr int TASK_ID = ID;
};

}
104 changes: 104 additions & 0 deletions cmake/cpp_source_template
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* 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"
#include "core/mapping/mapping.h"

namespace @target@ {

class Mapper : public legate::mapping::LegateMapper {
public:
Mapper(){}

private:
Mapper(const Mapper& rhs) = delete;
Mapper& operator=(const Mapper& rhs) = delete;

// Legate mapping functions
public:
void set_machine(const legate::mapping::MachineQueryInterface* machine) override {
machine_ = machine;
}

legate::mapping::TaskTarget task_target(
const legate::mapping::Task& task,
const std::vector<legate::mapping::TaskTarget>& options) override {
return *options.begin();
}

std::vector<legate::mapping::StoreMapping> store_mappings(
const legate::mapping::Task& task,
const std::vector<legate::mapping::StoreTarget>& options) override {
using legate::mapping::StoreMapping;
std::vector<StoreMapping> mappings;
auto& inputs = task.inputs();
auto& outputs = task.outputs();
for (auto& input : inputs) {
mappings.push_back(StoreMapping::default_mapping(input, options.front()));
mappings.back().policy.exact = true;
}
for (auto& output : outputs) {
mappings.push_back(StoreMapping::default_mapping(output, options.front()));
mappings.back().policy.exact = true;
}
return std::move(mappings);
}

legate::Scalar tunable_value(legate::TunableID tunable_id) override {
return 0;
}

private:
const legate::mapping::MachineQueryInterface* machine_;
};

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()
{
legate::ResourceConfig config;
config.max_mappers = 1;
config.max_tasks = 1024;
config.max_reduction_ops = 8;
legate::LibraryContext context(library_name, config);

Registry::get_registrar().register_all_tasks(context);

// Now we can register our mapper with the runtime
context.register_mapper(std::make_unique<Mapper>(), 0);
}

} // 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>();
}

}
211 changes: 211 additions & 0 deletions cmake/legate_gen_library.in
Original file line number Diff line number Diff line change
@@ -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
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
INTERFACE
$<INSTALL_INTERFACE:include>
)
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")
Loading

0 comments on commit d41b048

Please sign in to comment.