Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Sphinx configuration for the tvm-ffi documentation site."""

# -*- coding: utf-8 -*-
import os
from pathlib import Path

import tomli

Expand All @@ -25,9 +28,8 @@


# -- General configuration ------------------------------------------------

# Load version from pyproject.toml
with open("../pyproject.toml", "rb") as f:
with Path("../pyproject.toml").open("rb") as f:
pyproject_data = tomli.load(f)
__version__ = pyproject_data["project"]["version"]

Expand Down Expand Up @@ -181,6 +183,7 @@


def footer_html():
"""Generate HTML for the documentation footer."""
# Create footer HTML with two-line layout
# Generate dropdown menu items
dropdown_items = ""
Expand Down
3 changes: 2 additions & 1 deletion examples/inline_module/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Example: Build and run an inline C++/CUDA tvm-ffi module."""

import torch

import tvm_ffi.cpp
from tvm_ffi.module import Module


def main():
"""Build, load, and run inline CPU/CUDA functions."""
mod: Module = tvm_ffi.cpp.load_inline(
name="hello",
cpp_sources=r"""
Expand Down
9 changes: 5 additions & 4 deletions examples/packaging/python/my_ffi_extension/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,28 @@
# specific language governing permissions and limitations.
# order matters here so we need to skip isort here
# isort: skip_file
"""Public Python API for the example tvm-ffi extension package."""

from .base import _LIB
from . import _ffi_api


def add_one(x, y):
"""
Adds one to the input tensor.
"""Add one to the input tensor.

Parameters
----------
x : Tensor
The input tensor.
y : Tensor
The output tensor.

"""
return _LIB.add_one(x, y)


def raise_error(msg):
"""
Raises an error with the given message.
"""Raise an error with the given message.

Parameters
----------
Expand All @@ -47,5 +47,6 @@ def raise_error(msg):
------
RuntimeError
The error raised by the function.

"""
return _ffi_api.raise_error(msg)
1 change: 1 addition & 0 deletions examples/packaging/python/my_ffi_extension/_ffi_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import tvm_ffi

# make sure lib is loaded first
from .base import _LIB # noqa: F401

# this is a short cut to register all the global functions
# prefixed by `my_ffi_extension.` to this module
Expand Down
10 changes: 6 additions & 4 deletions examples/packaging/python/my_ffi_extension/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations.
# Base logic to load library for extension package
import os
"""Utilities to locate and load the example extension shared library."""

import sys
from pathlib import Path

import tvm_ffi


def _load_lib():
# first look at the directory of the current file
file_dir = os.path.dirname(os.path.realpath(__file__))
file_dir = Path(__file__).resolve().parent

if sys.platform.startswith("win32"):
lib_dll_name = "my_ffi_extension.dll"
Expand All @@ -31,8 +33,8 @@ def _load_lib():
else:
lib_dll_name = "my_ffi_extension.so"

lib_path = os.path.join(file_dir, lib_dll_name)
return tvm_ffi.load_module(lib_path)
lib_path = file_dir / lib_dll_name
return tvm_ffi.load_module(str(lib_path))


_LIB = _load_lib()
4 changes: 4 additions & 0 deletions examples/packaging/run_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,24 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations.
# Base logic to load library for extension package
"""Run functions from the example packaged tvm-ffi extension."""

import sys

import my_ffi_extension
import torch


def run_add_one():
"""Invoke add_one from the extension and print the result."""
x = torch.tensor([1, 2, 3, 4, 5], dtype=torch.float32)
y = torch.empty_like(x)
my_ffi_extension.add_one(x, y)
print(y)


def run_raise_error():
"""Invoke raise_error from the extension to demonstrate error handling."""
my_ffi_extension.raise_error("This is an error")


Expand Down
4 changes: 3 additions & 1 deletion examples/quick_start/run_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Quick start script to run tvm-ffi examples from prebuilt libraries."""

import tvm_ffi

try:
Expand Down Expand Up @@ -93,7 +95,7 @@ def run_add_one_cuda():


def main():
"""Main function to run the example."""
"""Run the quick start example."""
run_add_one_cpu()
run_add_one_c()
run_add_one_cuda()
Expand Down
90 changes: 51 additions & 39 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ cmake.build-type = "Release"
cmake.args = [
"-DTVM_FFI_ATTACH_DEBUG_SYMBOLS=ON",
"-DTVM_FFI_BUILD_TESTS=OFF",
"-DTVM_FFI_BUILD_PYTHON_MODULE=ON"
"-DTVM_FFI_BUILD_PYTHON_MODULE=ON",
]

# Logging
Expand Down Expand Up @@ -106,64 +106,76 @@ sdist.include = [
"/tests/**/*",
]

sdist.exclude = ["**/.git", "**/.github", "**/__pycache__", "**/*.pyc", "build", "dist"]
sdist.exclude = [
"**/.git",
"**/.github",
"**/__pycache__",
"**/*.pyc",
"build",
"dist",
]

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.black]
line-length = 100
skip-magic-trailing-comma = true

exclude = '''
/(
\.venv
| build
| docs
| dist
| 3rdparty/*
)/
'''

[tool.isort]
profile = "black"
src_paths = ["python", "tests"]
extend_skip = ["3rdparty"]
line_length = 100
skip_gitignore = true

[tool.ruff]
include = ["python/**/*.py", "tests/**/*.py"]
line-length = 100
indent-width = 4
target-version = "py39"

[tool.ruff.lint]
select = [
"UP", # pyupgrade, https://docs.astral.sh/ruff/rules/#pyupgrade-up
"PL", # pylint, https://docs.astral.sh/ruff/rules/#pylint-pl
"I", # isort, https://docs.astral.sh/ruff/rules/#isort-i
"RUF", # ruff, https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
"NPY", # numpy, https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy
"F", # pyflakes, https://docs.astral.sh/ruff/rules/#pyflakes-f
# "ANN", # flake8-annotations, https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
"PTH", # flake8-use-pathlib, https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
"D", # pydocstyle, https://docs.astral.sh/ruff/rules/#pydocstyle-d
]
ignore = [
"PLR2004", # pylint: magic-value-comparison
"ANN401", # flake8-annotations: any-type
"D203", # pydocstyle: incorrect-blank-line-before-class
"D213", # pydocstyle: multi-line-summary-second-line
]
fixable = ["ALL"]
unfixable = []

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
"tests/*" = ["E741"]
"__init__.py" = ["F401"] # pyflakes: unused-import
"tests/*" = [
"E741", # pycodestyle: ambiguous-variable-name
"D100", # pydocstyle: undocumented-public-module
"D101", # pydocstyle: undocumented-public-class
"D103", # pydocstyle: undocumented-public-function
"D107", # pydocstyle: undocumented-public-init
"D205", # pydocstyle: missing-blank-line-after-summary
]

[tool.ruff.lint.pylint]
max-args = 10

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
docstring-code-format = false
docstring-code-line-length = "dynamic"

[tool.cibuildwheel]
build-verbosity = 1

# only build up to cp312, cp312
# will be abi3 and can be used in future versions
build = [
"cp39-*",
"cp310-*",
"cp311-*",
"cp312-*",
]
skip = [
"*musllinux*"
]
build = ["cp39-*", "cp310-*", "cp311-*", "cp312-*"]
skip = ["*musllinux*"]
# we only need to test on cp312
test-skip = [
"cp39-*",
"cp310-*",
"cp311-*",
]
test-skip = ["cp39-*", "cp310-*", "cp311-*"]
# focus on testing abi3 wheel
build-frontend = "build[uv]"
test-command = "pytest {package}/tests/python -vvs"
Expand Down
36 changes: 18 additions & 18 deletions python/tvm_ffi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,31 @@
from . import _optional_torch_c_dlpack

__all__ = [
"dtype",
"Array",
"DLDeviceType",
"Device",
"Device",
"Function",
"Map",
"Module",
"Object",
"register_object",
"register_global_func",
"get_global_func",
"remove_global_func",
"init_ffi_api",
"Object",
"ObjectConvertible",
"Function",
"Shape",
"Tensor",
"access_path",
"convert",
"register_error",
"Device",
"device",
"DLDeviceType",
"dtype",
"from_dlpack",
"Tensor",
"Shape",
"Array",
"Map",
"testing",
"access_path",
"get_global_func",
"init_ffi_api",
"load_module",
"register_error",
"register_global_func",
"register_object",
"remove_global_func",
"serialization",
"Module",
"system_lib",
"load_module",
"testing",
]
3 changes: 2 additions & 1 deletion python/tvm_ffi/_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from . import container, core


def convert(value: Any) -> Any:
def convert(value: Any) -> Any: # noqa: PLR0911
"""Convert a python object to ffi values.

Parameters
Expand All @@ -40,6 +40,7 @@ def convert(value: Any) -> Any:
Function arguments to ffi function calls are
automatically converted. So this function is mainly
only used in internal or testing scenarios.

"""
if isinstance(value, (core.Object, core.PyNativeObject, bool, Number)):
return value
Expand Down
Loading
Loading