Skip to content

Commit

Permalink
Merge branch 'aotuai_main'
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenli2000 committed Apr 12, 2023
2 parents c1745e3 + 39f509c commit 7412902
Show file tree
Hide file tree
Showing 42 changed files with 2,151 additions and 231 deletions.
47 changes: 47 additions & 0 deletions tools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# How to Build

```shell
python3 compile.py build_ext build_binaries
```
Clean up a build,

```shell
python3 compile.py clean
```

# Capsule Infer

This tool is used during development to quickly and easily run inference
with a capsule.

## Usage
Make sure you are running in an environment with `vcap` and `vcap-utils`
installed.

Running is simple. Point the script to the capsule of choice, and list one
or more images to run inference on. For example:
```shell
python3 capsule_infer.py --capsule my-detector-capsule/ --images img.png
img2.png
```

You can also point `--images` to a path that contains images.

# Capsule Classifier accuracy

This tool is used during development to quickly and easily run accuracy benchmark
with a capsule. The output is a set of benchmark reports.

## Usage
Make sure you are running in an environment with `vcap` and `vcap-utils`
installed.

Running is simple. Point the script to the capsule of choice, and list one
or more images to run inference on. For example:
```shell
python3 capsule_classifier_accuracy.py --capsule <capsule directory or .cap> --images-true <true image directory> --images-false <false image directory> --data attribute=<name> true_threshold=0.0 false_threshold=0.0 detection=<class name>
```

Optional image categories are as follows,

`--images`, `--images-true`, `--images-false`
23 changes: 0 additions & 23 deletions tools/capsule_infer/README.md

This file was deleted.

124 changes: 0 additions & 124 deletions tools/capsule_infer/capsule_infer.py

This file was deleted.

184 changes: 184 additions & 0 deletions tools/compile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#
# Copyright (c) 2021 Dilili Labs, Inc. All rights reserved. Contains Dilili Labs Proprietary Information. RESTRICTED COMPUTER SOFTWARE. LIMITED RIGHTS DATA.
#
# This script compiles a Python app using Cython.

import multiprocessing
import re
import subprocess
import sysconfig
from distutils.cmd import Command
from distutils.command.build_ext import build_ext
from pathlib import Path

from Cython.Build import cythonize
from Cython.Compiler import Options as CompilerOptions
from setuptools import setup
from setuptools.extension import Extension

THREAD_COUNT = multiprocessing.cpu_count() * 2

BUILD_PATH = Path("build/")
PYTHON_VER = "python3.8"

BFAPP_PY_DIRS = [
"capsule_infer",
"capsule_classifier_accuracy",
]

# Used to exclude various Python files from Cythonization. If the path is a
# file, then that file will not by Cythonized. If the path is a directory, then
# everything in that directory will not be Cythonized.
cythonize_excludes = [
# These aren't runtime files
r"tests/.*",
]


def is_excluded(path):
"""
:param path: The path to check
:return: True if the file should be excluded from build-related actions
"""
for exclude in cythonize_excludes:
if re.match(exclude, str(path)):
return True

return False


class BuildBinariesCommand(Command):
"""Builds a Python App run files into a binary."""

description = "build the main scripts into binaries"
user_options = []

def __init__(self, dist, executable_paths):
self._executable_paths = executable_paths
super().__init__(dist)

def initialize_options(self):
pass

def finalize_options(self):
pass

def run(self):
for path in self._executable_paths:
self._build_binary(path)

@staticmethod
def _build_binary(source: Path):
c_file = source.parent / (source.stem + ".c")
exe_file = source.with_suffix("")

cython_command = f"python3 -m cython --embed -3 -o {c_file} {source}"
subprocess.run(cython_command, shell=True, check=True)

gcc_command = (
f"gcc -Os "
f"-I {sysconfig.get_path('include')} "
f"-o {exe_file} "
f"{c_file} "
f"-l{PYTHON_VER} -lpthread -lm -lutil -ldl "
)
subprocess.run(gcc_command, shell=True, check=True)


class BuildBinariesCommand(BuildBinariesCommand):
def __init__(self, dist):
binaries = []
for BFAPP_PY_DIR in BFAPP_PY_DIRS:
binaries += list(Path(BFAPP_PY_DIR).glob(BFAPP_PY_DIR + ".py"))
super().__init__(dist, binaries)


class CleanCommand(Command):
"""Cleans the resulting build files from the project directory."""

description = "delete output files from the build"
user_options = []

def initialize_options(self):
pass

def finalize_options(self):
pass

def run(self):
clean_paths = (Path(BFAPP_PY_DIR) for BFAPP_PY_DIR in BFAPP_PY_DIRS)
clean_extensions = ["*.so", "*.c", "*.html"] + BFAPP_PY_DIRS

for clean_path in clean_paths:
for clean_extension in clean_extensions:
for clean_file in clean_path.rglob(clean_extension):
if not is_excluded(clean_file):
print(f"delete {clean_file}")
clean_file.unlink()

# Delete the output files from creating the executables
build_folder_files = list(BUILD_PATH.glob("**/**/*"))

for path in build_folder_files: # executable_paths:
if path.is_file():
print(f"delete {path}")
path.unlink()


class BuildExtParallel(build_ext):
def __init__(self, dist, extension_path):
self._extension_path = extension_path

dist.ext_modules = cythonize(
self._find_extension_modules(),
compiler_directives={
"language_level": "3",
},
annotate=False,
nthreads=THREAD_COUNT,
)
super().__init__(dist)

def finalize_options(self):
super().finalize_options()
if self.parallel is None:
self.parallel = THREAD_COUNT

def _find_extension_modules(self):
extension_modules = []
for extension_path in self._extension_path:
for py_file in extension_path.rglob("*.py"):
if not is_excluded(py_file):
mod_path = str(py_file).replace("/", ".").replace(".py", "")
extension = Extension(
# In past releases, -O3 causes segfaults after ~4-6 hours of use.
# If changed, make sure to run 24h to confirm no stability regressions.
mod_path,
[str(py_file)],
extra_compile_args=["-O1"],
)
extension_modules.append(extension)
return extension_modules


class BuildExtParallel(BuildExtParallel):
def __init__(self, dist):
paths = []
paths += (Path(BFAPP_PY_DIR) for BFAPP_PY_DIR in BFAPP_PY_DIRS)
super().__init__(dist, paths)


"""Information on Compiler Options:
https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html
"""
CompilerOptions.error_on_unknown_names = True
CompilerOptions.error_on_uninitialized = True

setup(
name="open_vision_capsule_tools_cython",
cmdclass={
"build_ext": BuildExtParallel,
"build_binaries": BuildBinariesCommand,
"clean": CleanCommand,
},
)

0 comments on commit 7412902

Please sign in to comment.