Skip to content

Commit

Permalink
This might do something different, but it probably won't
Browse files Browse the repository at this point in the history
  • Loading branch information
Pencilcaseman committed Nov 2, 2023
1 parent 6074124 commit e889486
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 43 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ librapid/librapid.egg-info
librapid/bindings/python/generated

dist/
librapid/bindings/generators/*.hpp
librapid/bindings/generators/*.cpp

*.pyc
1 change: 1 addition & 0 deletions librapid/bindings/generators/arrayGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ def generateArrayModule(config):
name=f"librapid.{config['name']}",
includeGuard=includeGuard
)

arrayModule.addClass(arrayClass)
arrayModule.functions.extend(functions)

Expand Down
20 changes: 20 additions & 0 deletions librapid/bindings/generators/boilerplate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import textwrap


def boilerplate():
return textwrap.dedent(f"""
#pragma once
#ifndef LIBRAPID_DEBUG
#define LIBRAPID_DEBUG
#endif
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <librapid/librapid.hpp>
namespace py = pybind11;
namespace lrc = librapid;
""").strip()
74 changes: 63 additions & 11 deletions librapid/bindings/generators/class_.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from argument import Argument
import function
import os
import textwrap
import boilerplate


class Class:
Expand All @@ -24,21 +27,68 @@ def genImplicitConversions(self):

return ret

def genInterface(self, parent="module"):
ret = f"py::class_<{self.type}>({parent}, \"{self.name}\")\n"
for func in self.functions:
ret += func.gen(self, False)
def genInterface(self, parent="module", root="./", includeGuard=None):
mainInterface = f"py::class_<{self.type}> {self.name}Class({parent}, \"{self.name}\");\n"
includes = []

# Ensure directory exists
if not os.path.exists(f"{root}/{self.name}"):
os.makedirs(f"{root}/{self.name}")

if func is not self.functions[-1]:
ret += "\n"
# Ensure function names are unique
functionCount = 0

ret += ";\n"
for func in self.functions:
functionName = f"librapidPython_{self.name}_{func.name}_{functionCount}"
fileName = f"{func.name}_{functionCount}"
filePath = f"{root}/{self.name}/{fileName}"

# Write definition
with open(f"{filePath}.hpp", "w") as f:
f.write(textwrap.dedent(f"""
{boilerplate.boilerplate()}
void {functionName}(py::class_<{self.type}>& module);
"""))
includes.append(f"{filePath}.hpp")

# Write implementation
with open(f"{filePath}.cpp", "w") as f:
f.write(f"#include \"{fileName}.hpp\"\n")

if includeGuard is not None:
f.write(f"#if {includeGuard}\n")

f.write(textwrap.dedent(f"""
void {functionName}(py::class_<{self.type}>& {self.name}) {{
{func.gen(self, True)};
}}
"""))

if includeGuard is not None:
f.write(f"#else\n")
f.write(textwrap.dedent(f"""
void {functionName}(py::class_<{self.type}>& module) {{
return;
}}
"""))
f.write(f"#endif\n")

# Add function call to interface
mainInterface += f"{functionName}({self.name}Class);\n"

functionCount += 1

# ret += func.gen(self, False)
#
# if func is not self.functions[-1]:
# ret += "\n"

if len(self.implicitConversions) > 0:
ret += "\n"
ret += self.genImplicitConversions()
mainInterface += "\n"
mainInterface += self.genImplicitConversions()

return ret
return mainInterface, includes

def __str__(self):
return self.name
Expand Down Expand Up @@ -109,4 +159,6 @@ def __str__(self):

vector.addImplicitConversion(vector)

print(vector.genInterface())
mainInterface, includes = vector.genInterface(root="../python/generated", includeGuard="defined(LIBRAPID_HAS_CUDA)")
print(mainInterface)
print(includes)
14 changes: 11 additions & 3 deletions librapid/bindings/generators/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,28 @@ def addModule(self, module):

def genInterface(self):
interfaceFunctions = []
includes = []
ret = ""

root = self.path[:self.path.rfind("/")]

for module in self.modules:
ret += module.genInterface()
moduleInterface, moduleIncludes = module.genInterface(root=root)
ret += moduleInterface
ret += "\n"

interfaceFunctions.append((module.genInterfaceDefinition, module.genInterfaceCall))
includes += moduleIncludes

return ret, interfaceFunctions
return ret, interfaceFunctions, includes

def write(self, path=None):
interfaceFunctions = []
with open(path if path is not None else self.path, "w") as f:
f.write("#include \"librapidPython.hpp\"\n\n")
interface, interfaceFunctionsTmp = self.genInterface()
interface, interfaceFunctionsTmp, includes = self.genInterface()
for include in includes:
f.write(f"#include \"{include.strip('../python/generated/')}.hpp\"\n")
f.write(interface.strip())
interfaceFunctions.extend(interfaceFunctionsTmp)

Expand Down
50 changes: 26 additions & 24 deletions librapid/bindings/generators/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,10 @@
import shapeGenerator
import arrayGenerator
import generalArrayViewGenerator
import boilerplate

outputDir = "../python/generated"

boilerplate = textwrap.dedent(f"""
#pragma once
#ifndef LIBRAPID_DEBUG
#define LIBRAPID_DEBUG
#endif
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <librapid/librapid.hpp>
namespace py = pybind11;
namespace lrc = librapid;
""").strip()

postBoilerplate = textwrap.dedent(f"""
#if defined(LIBRAPID_HAS_OPENCL)
module.def("configureOpenCL", [](bool verbose, bool ask) {{
Expand Down Expand Up @@ -84,7 +68,7 @@ def main():
interfaceFunctions += generalArrayViewGenerator.write(outputDir)

with open(f"{outputDir}/librapidPython.hpp", "w") as f:
f.write(boilerplate)
f.write(boilerplate.boilerplate())
f.write("\n\n")
for interfaceDef, _ in interfaceFunctions:
f.write(f"{interfaceDef()};\n")
Expand All @@ -103,13 +87,31 @@ def main():
f.write("}\n")

# Apply clang-format to the generated files
# import subprocess
# for file in os.listdir("../python/generated"):
# if file.endswith(".hpp") or file.endswith(".cpp"):
# try:
# subprocess.run(["clang-format", "-i", "-style=llvm", f"librapid/bindings/python/generated/{file}"], cwd="../../../")
# except Exception as e:
# print("Unable to run clang-format:", e)

# Apply clang-format to the generated files (recursive)
import subprocess
for file in os.listdir("../python/generated"):
if file.endswith(".hpp") or file.endswith(".cpp"):
try:
subprocess.run(["clang-format", "-i", "-style=llvm", f"librapid/bindings/python/generated/{file}"], cwd="../../../")
except Exception as e:
print("Unable to run clang-format:", e)
prevChars = 0
for root, dirs, files in os.walk("../python/generated"):
for file in files:

print(" " * prevChars, end='\r')
text = f"Formatting {root}/{file}"
print(text, end='\r')
prevChars = len(text)


if file.endswith(".hpp") or file.endswith(".cpp"):
try:
subprocess.run(["clang-format", "-i", "-style=llvm", f"{root}/{file}"], cwd="./")
except Exception as e:
print(f"Unable to run clang-format on {root}/{file}:", e)


if __name__ == "__main__":
Expand Down
13 changes: 8 additions & 5 deletions librapid/bindings/generators/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ def genInterfaceCall(self, moduleName):
tmpName = self.name.replace(".", "_")
return f"genInterface_{tmpName}({moduleName})"

def genInterface(self):
def genInterface(self, root="./"):
ret = f"{self.genInterfaceDefinition()} {{\n"
includes = []

if self.parent is None:
moduleName = "module"
Expand All @@ -40,7 +41,9 @@ def genInterface(self):
ret += f"{moduleName}.doc() = \"{self.docstring}\";\n\n"

for class_ in self.classes:
ret += class_.genInterface(moduleName)
classInterface, classIncludes = class_.genInterface(moduleName, root=root, includeGuard=self.includeGuard)
includes += classIncludes
ret += classInterface
ret += "\n"

for func in self.functions:
Expand All @@ -50,15 +53,15 @@ def genInterface(self):
ret += "}\n"

if self.includeGuard is None:
return ret
return ret, includes
else:
return textwrap.dedent(f"""
guardedInterface = textwrap.dedent(f"""
#if {self.includeGuard}
{ret}
#else
{self.genInterfaceDefinition()} {{}}
#endif
""")
"""), includes


if __name__ == "__main__":
Expand Down

0 comments on commit e889486

Please sign in to comment.