arraybridge 0.3.2__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {arraybridge-0.3.2 → arraybridge-0.3.4}/.github/workflows/publish.yml +1 -1
- {arraybridge-0.3.2 → arraybridge-0.3.4}/PKG-INFO +1 -1
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/conf.py +3 -1
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/gpu_features.rst +5 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/pyproject.toml +4 -1
- arraybridge-0.3.4/scripts/update_version.py +60 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/scripts/verify_release_ready.py +2 -17
- arraybridge-0.3.4/src/arraybridge/__init__.py +109 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/types.py +91 -21
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_types.py +52 -0
- arraybridge-0.3.2/scripts/update_version.py +0 -79
- arraybridge-0.3.2/src/arraybridge/__init__.py +0 -75
- {arraybridge-0.3.2 → arraybridge-0.3.4}/.github/workflows/ci.yml +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/.github/workflows/coverage-pages.yml +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/.github/workflows/gpu-tests.yml +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/.gitignore +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/.readthedocs.yml +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/ADDING_NEW_FRAMEWORKS.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/CONTRIBUTING.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/LICENSE +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/README.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/TESTING.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/Makefile +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/CI_ARTIFACT_UPDATE.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/CI_CUPY_FIX.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/CI_IMPROVEMENTS.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/CONFLICT_VISUALIZATION.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/COVERAGE_AUDIT_PLAN.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/DEPLOYMENT_SUMMARY.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/GPU_TESTING_SETUP.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/MERGE_CONFLICT_RESOLUTION.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/MIGRATION_SUMMARY.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/QUICK_FIX_GUIDE.txt +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/README.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/archive/RESOLVED_FILES.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/ci-cd.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/.gitignore +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/Makefile +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/README.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/advanced_topics.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/api_reference.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/ci-cd.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/contributing.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/converters.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/decorators.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/examples/basic_conversion.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/examples/decorators.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/examples/index.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/examples/multi_framework.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/index.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/installation.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/quickstart.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/stack_utils.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/docs/source/user_guide.rst +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/paper.bib +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/paper.md +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/scripts/release.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/array_geometry.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/array_operations.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/array_payload.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/converters.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/converters_registry.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/decorators.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/dtype_scaling.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/exceptions.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/framework_config.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/framework_ops.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/gpu_cleanup.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/oom_recovery.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/slice_processing.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/stack_utils.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/src/arraybridge/utils.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/__init__.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/conftest.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_array_geometry.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_converters.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_converters_registry.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_decorators.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_dtype_scaling.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_exceptions.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_framework_config.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_gpu_cleanup.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_integration.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_oom_recovery.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_registry_integration.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_slice_processing.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_stack_utils.py +0 -0
- {arraybridge-0.3.2 → arraybridge-0.3.4}/tests/test_utils.py +0 -0
|
@@ -42,7 +42,7 @@ jobs:
|
|
|
42
42
|
|
|
43
43
|
- name: Verify release tag and main ancestry
|
|
44
44
|
run: |
|
|
45
|
-
declared_version=$(python -c 'import
|
|
45
|
+
declared_version=$(python -c 'import arraybridge; print(arraybridge.__version__)')
|
|
46
46
|
test "$GITHUB_REF_NAME" = "v$declared_version"
|
|
47
47
|
git fetch origin main
|
|
48
48
|
git merge-base --is-ancestor "$GITHUB_SHA" origin/main
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: arraybridge
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Unified API for NumPy, CuPy, PyTorch, TensorFlow, JAX, and pyclesperanto with automatic memory type conversion
|
|
5
5
|
Project-URL: Homepage, https://github.com/OpenHCSDev/arraybridge
|
|
6
6
|
Project-URL: Documentation, https://arraybridge.readthedocs.io
|
|
@@ -16,13 +16,15 @@ EXTERNAL_ROOT = PACKAGE_ROOT.parent
|
|
|
16
16
|
sys.path.insert(0, str(EXTERNAL_ROOT / "metaclass-registry" / "src"))
|
|
17
17
|
sys.path.insert(0, str(PACKAGE_ROOT / "src"))
|
|
18
18
|
|
|
19
|
+
from arraybridge import __version__
|
|
20
|
+
|
|
19
21
|
# -- Project information -----------------------------------------------------
|
|
20
22
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
|
21
23
|
|
|
22
24
|
project = 'arraybridge'
|
|
23
25
|
copyright = '2025, Tristan Simas'
|
|
24
26
|
author = 'Tristan Simas'
|
|
25
|
-
release =
|
|
27
|
+
release = __version__
|
|
26
28
|
|
|
27
29
|
# -- General configuration ---------------------------------------------------
|
|
28
30
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
|
@@ -15,6 +15,11 @@ overwritten. Hosts that import optional frameworks themselves should call
|
|
|
15
15
|
``MemoryType.prepare_import()`` first. ArrayBridge warns when it encounters an
|
|
16
16
|
already-loaded framework whose import-time defaults were absent.
|
|
17
17
|
|
|
18
|
+
``MemoryType.subprocess_environment()`` projects the same member-owned import
|
|
19
|
+
defaults into a child-process environment. The CuPy member also derives native
|
|
20
|
+
library search paths from installed NVIDIA wheels, so a fresh child interpreter
|
|
21
|
+
does not depend on another framework having loaded CUDA libraries first.
|
|
22
|
+
|
|
18
23
|
JAX float64 output requires x64 mode to be enabled before import. ArrayBridge
|
|
19
24
|
raises instead of silently returning float32 when a caller requests float64
|
|
20
25
|
while that capability is disabled.
|
|
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "arraybridge"
|
|
8
|
-
|
|
8
|
+
dynamic = ["version"]
|
|
9
9
|
description = "Unified API for NumPy, CuPy, PyTorch, TensorFlow, JAX, and pyclesperanto with automatic memory type conversion"
|
|
10
10
|
authors = [{name = "Tristan Simas", email = "tristan.simas@mail.mcgill.ca"}]
|
|
11
11
|
license = {text = "MIT"}
|
|
@@ -98,6 +98,9 @@ Issues = "https://github.com/OpenHCSDev/arraybridge/issues"
|
|
|
98
98
|
[tool.hatch.build.targets.wheel]
|
|
99
99
|
packages = ["src/arraybridge"]
|
|
100
100
|
|
|
101
|
+
[tool.hatch.version]
|
|
102
|
+
path = "src/arraybridge/__init__.py"
|
|
103
|
+
|
|
101
104
|
[tool.pytest.ini_options]
|
|
102
105
|
testpaths = ["tests"]
|
|
103
106
|
python_files = ["test_*.py"]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Update ArrayBridge's canonical package version without Git side effects."""
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import re
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from packaging.version import InvalidVersion, Version
|
|
9
|
+
|
|
10
|
+
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
11
|
+
VERSION_FILE = PROJECT_ROOT / "src/arraybridge/__init__.py"
|
|
12
|
+
VERSION_PATTERN = r"(__version__\s*=\s*['\"])([^'\"]+)(['\"])"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def current_version() -> Version:
|
|
16
|
+
"""Return the package-owned canonical version."""
|
|
17
|
+
|
|
18
|
+
match = re.search(
|
|
19
|
+
VERSION_PATTERN,
|
|
20
|
+
VERSION_FILE.read_text(encoding="utf-8"),
|
|
21
|
+
flags=re.MULTILINE,
|
|
22
|
+
)
|
|
23
|
+
if match is None:
|
|
24
|
+
raise RuntimeError(f"Version declaration is missing from {VERSION_FILE}")
|
|
25
|
+
return Version(match.group(2))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def update_version(version_text: str) -> None:
|
|
29
|
+
try:
|
|
30
|
+
requested = Version(version_text)
|
|
31
|
+
except InvalidVersion as error:
|
|
32
|
+
raise ValueError(f"Invalid version: {version_text}") from error
|
|
33
|
+
current = current_version()
|
|
34
|
+
if requested <= current:
|
|
35
|
+
raise ValueError(f"New version {requested} must be greater than {current}")
|
|
36
|
+
|
|
37
|
+
content = VERSION_FILE.read_text(encoding="utf-8")
|
|
38
|
+
updated, count = re.subn(
|
|
39
|
+
VERSION_PATTERN,
|
|
40
|
+
rf"\g<1>{requested}\g<3>",
|
|
41
|
+
content,
|
|
42
|
+
flags=re.MULTILINE,
|
|
43
|
+
)
|
|
44
|
+
if count != 1:
|
|
45
|
+
raise RuntimeError(f"Expected one version declaration in {VERSION_FILE}, found {count}")
|
|
46
|
+
VERSION_FILE.write_text(updated, encoding="utf-8")
|
|
47
|
+
|
|
48
|
+
print(f"Updated ArrayBridge version to {requested}")
|
|
49
|
+
print("Run scripts/verify_release_ready.py --allow-dirty, then review and commit.")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def main() -> None:
|
|
53
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
54
|
+
parser.add_argument("version", help="New release version, for example 0.3.0")
|
|
55
|
+
args = parser.parse_args()
|
|
56
|
+
update_version(args.version)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
main()
|
|
@@ -16,8 +16,6 @@ import sys
|
|
|
16
16
|
import tempfile
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
|
|
19
|
-
import tomllib
|
|
20
|
-
|
|
21
19
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
22
20
|
|
|
23
21
|
|
|
@@ -41,20 +39,6 @@ def check_version():
|
|
|
41
39
|
print(f" ❌ Version '{version}' doesn't follow semantic versioning (MAJOR.MINOR.PATCH)")
|
|
42
40
|
return False
|
|
43
41
|
|
|
44
|
-
pyproject_version = tomllib.loads(
|
|
45
|
-
(PROJECT_ROOT / "pyproject.toml").read_text(encoding="utf-8")
|
|
46
|
-
)["project"]["version"]
|
|
47
|
-
docs_match = re.search(
|
|
48
|
-
r"release\s*=\s*['\"]([^'\"]+)",
|
|
49
|
-
(PROJECT_ROOT / "docs/source/conf.py").read_text(encoding="utf-8"),
|
|
50
|
-
)
|
|
51
|
-
docs_version = docs_match.group(1) if docs_match else None
|
|
52
|
-
if len({version, pyproject_version, docs_version}) != 1:
|
|
53
|
-
print(
|
|
54
|
-
" ❌ Version authorities disagree: "
|
|
55
|
-
f"package={version}, pyproject={pyproject_version}, docs={docs_version}"
|
|
56
|
-
)
|
|
57
|
-
return False
|
|
58
42
|
print(f" ✅ Version: {version}")
|
|
59
43
|
return True
|
|
60
44
|
|
|
@@ -70,7 +54,8 @@ def check_pyproject_toml():
|
|
|
70
54
|
content = pyproject_file.read_text(encoding="utf-8")
|
|
71
55
|
required_fields = {
|
|
72
56
|
"name": r'name\s*=\s*["\']arraybridge["\']',
|
|
73
|
-
"version": r"version\
|
|
57
|
+
"dynamic version": r'dynamic\s*=\s*\[["\']version["\']\]',
|
|
58
|
+
"version authority": r'path\s*=\s*["\']src/arraybridge/__init__\.py["\']',
|
|
74
59
|
"description": r"description\s*=",
|
|
75
60
|
"authors": r"authors\s*=",
|
|
76
61
|
"build-backend": r'build-backend\s*=\s*["\']hatchling\.build["\']',
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""
|
|
2
|
+
arraybridge: Unified API for NumPy, CuPy, PyTorch, TensorFlow, JAX, and pyclesperanto.
|
|
3
|
+
|
|
4
|
+
This package provides automatic memory type conversion, declarative decorators,
|
|
5
|
+
and unified utilities for working with multiple array/tensor frameworks.
|
|
6
|
+
|
|
7
|
+
Package-root imports stay lightweight: submodule exports load on first
|
|
8
|
+
attribute access instead of at import time. Declaration-only consumers
|
|
9
|
+
(memory-type tables, configuration modules) therefore do not pay the
|
|
10
|
+
NumPy/numcodecs import cost.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
__version__ = "0.3.4"
|
|
14
|
+
|
|
15
|
+
_LAZY_EXPORTS: dict[str, str] = {
|
|
16
|
+
"MemoryType": ".types",
|
|
17
|
+
"MemoryContractAttribute": ".types",
|
|
18
|
+
"ArrayPayload": ".array_payload",
|
|
19
|
+
"ArrayGeometry": ".array_geometry",
|
|
20
|
+
"CPU_MEMORY_TYPES": ".types",
|
|
21
|
+
"GPU_MEMORY_TYPES": ".types",
|
|
22
|
+
"SUPPORTED_MEMORY_TYPES": ".types",
|
|
23
|
+
"convert_memory": ".converters",
|
|
24
|
+
"detect_memory_type": ".converters",
|
|
25
|
+
"memory_types": ".decorators",
|
|
26
|
+
"DtypeConversion": ".decorators",
|
|
27
|
+
"SliceBySliceRuntimeParameter": ".decorators",
|
|
28
|
+
"wrap_dtype_preserving_callable": ".decorators",
|
|
29
|
+
"stack_slices": ".stack_utils",
|
|
30
|
+
"unstack_slices": ".stack_utils",
|
|
31
|
+
"process_slices": ".slice_processing",
|
|
32
|
+
"cleanup_all_gpu_frameworks": ".gpu_cleanup",
|
|
33
|
+
"MemoryConversionError": ".exceptions",
|
|
34
|
+
"SCALING_FUNCTIONS": ".dtype_scaling",
|
|
35
|
+
"_FRAMEWORK_CONFIG": ".framework_config",
|
|
36
|
+
"_FRAMEWORK_OPS": ".framework_ops",
|
|
37
|
+
"_execute_with_oom_recovery": ".oom_recovery",
|
|
38
|
+
"_ensure_module": ".utils",
|
|
39
|
+
"_supports_dlpack": ".utils",
|
|
40
|
+
"_get_device_id": ".utils",
|
|
41
|
+
# Decorator exports named after each memory type (numpy, cupy, torch, ...).
|
|
42
|
+
"numpy": ".decorators",
|
|
43
|
+
"cupy": ".decorators",
|
|
44
|
+
"torch": ".decorators",
|
|
45
|
+
"tensorflow": ".decorators",
|
|
46
|
+
"jax": ".decorators",
|
|
47
|
+
"pyclesperanto": ".decorators",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
# Types
|
|
52
|
+
"MemoryType",
|
|
53
|
+
"MemoryContractAttribute",
|
|
54
|
+
"ArrayPayload",
|
|
55
|
+
"ArrayGeometry",
|
|
56
|
+
"CPU_MEMORY_TYPES",
|
|
57
|
+
"GPU_MEMORY_TYPES",
|
|
58
|
+
"SUPPORTED_MEMORY_TYPES",
|
|
59
|
+
# Converters
|
|
60
|
+
"convert_memory",
|
|
61
|
+
"detect_memory_type",
|
|
62
|
+
# Decorators
|
|
63
|
+
"memory_types",
|
|
64
|
+
"DtypeConversion",
|
|
65
|
+
"SliceBySliceRuntimeParameter",
|
|
66
|
+
"wrap_dtype_preserving_callable",
|
|
67
|
+
# Stack utilities
|
|
68
|
+
"stack_slices",
|
|
69
|
+
"unstack_slices",
|
|
70
|
+
# Slice processing
|
|
71
|
+
"process_slices",
|
|
72
|
+
# GPU cleanup
|
|
73
|
+
"cleanup_all_gpu_frameworks",
|
|
74
|
+
# Exceptions
|
|
75
|
+
"MemoryConversionError",
|
|
76
|
+
# Scaling
|
|
77
|
+
"SCALING_FUNCTIONS",
|
|
78
|
+
# Framework config (internal but needed by some consumers)
|
|
79
|
+
"_FRAMEWORK_CONFIG",
|
|
80
|
+
"_FRAMEWORK_OPS",
|
|
81
|
+
# OOM recovery
|
|
82
|
+
"_execute_with_oom_recovery",
|
|
83
|
+
# Utils
|
|
84
|
+
"_ensure_module",
|
|
85
|
+
"_supports_dlpack",
|
|
86
|
+
"_get_device_id",
|
|
87
|
+
"numpy",
|
|
88
|
+
"cupy",
|
|
89
|
+
"torch",
|
|
90
|
+
"tensorflow",
|
|
91
|
+
"jax",
|
|
92
|
+
"pyclesperanto",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def __getattr__(name: str):
|
|
97
|
+
module_name = _LAZY_EXPORTS.get(name)
|
|
98
|
+
if module_name is None:
|
|
99
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
100
|
+
|
|
101
|
+
import importlib
|
|
102
|
+
|
|
103
|
+
value = getattr(importlib.import_module(module_name, __name__), name)
|
|
104
|
+
globals()[name] = value
|
|
105
|
+
return value
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def __dir__() -> list[str]:
|
|
109
|
+
return sorted(set(globals()) | set(_LAZY_EXPORTS))
|
|
@@ -5,6 +5,8 @@ This module defines the MemoryType enum and related constants for managing
|
|
|
5
5
|
different array/tensor frameworks.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
8
10
|
import importlib
|
|
9
11
|
import importlib.util
|
|
10
12
|
import logging
|
|
@@ -14,17 +16,11 @@ from collections.abc import Callable, Iterator, Mapping, MutableMapping
|
|
|
14
16
|
from contextlib import AbstractContextManager, contextmanager, nullcontext
|
|
15
17
|
from dataclasses import dataclass
|
|
16
18
|
from enum import Enum
|
|
17
|
-
from
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
NUMPY_OPERATIONS,
|
|
23
|
-
PYCLESPERANTO_OPERATIONS,
|
|
24
|
-
TENSORFLOW_OPERATIONS,
|
|
25
|
-
TORCH_OPERATIONS,
|
|
26
|
-
ArrayOperations,
|
|
27
|
-
)
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from arraybridge.array_operations import ArrayOperations
|
|
28
24
|
|
|
29
25
|
T = TypeVar("T")
|
|
30
26
|
logger = logging.getLogger(__name__)
|
|
@@ -41,6 +37,55 @@ StreamScopeFactory = Callable[[Any, Any], AbstractContextManager[None]]
|
|
|
41
37
|
DLPackExporter = Callable[[Any, Any], Any | None]
|
|
42
38
|
DLPackValidator = Callable[[Any, Any], bool]
|
|
43
39
|
OOMMatcher = Callable[[BaseException, Any | None], bool]
|
|
40
|
+
SubprocessEnvironmentResolver = Callable[[Mapping[str, str]], dict[str, str]]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _identity_subprocess_environment(
|
|
44
|
+
environment: Mapping[str, str],
|
|
45
|
+
) -> dict[str, str]:
|
|
46
|
+
return dict(environment)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _nvidia_wheel_library_paths() -> tuple[str, ...]:
|
|
50
|
+
"""Return native-library directories declared by installed NVIDIA wheels."""
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
spec = importlib.util.find_spec("nvidia")
|
|
54
|
+
except (ImportError, ModuleNotFoundError, ValueError):
|
|
55
|
+
return ()
|
|
56
|
+
if spec is None or spec.submodule_search_locations is None:
|
|
57
|
+
return ()
|
|
58
|
+
|
|
59
|
+
paths: set[str] = set()
|
|
60
|
+
for package_root in map(Path, spec.submodule_search_locations):
|
|
61
|
+
try:
|
|
62
|
+
components = tuple(package_root.iterdir())
|
|
63
|
+
except OSError:
|
|
64
|
+
continue
|
|
65
|
+
for component in components:
|
|
66
|
+
for library_directory_name in ("lib", "bin"):
|
|
67
|
+
candidate = component / library_directory_name
|
|
68
|
+
if candidate.is_dir():
|
|
69
|
+
paths.add(str(candidate))
|
|
70
|
+
return tuple(sorted(paths))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _nvidia_wheel_subprocess_environment(
|
|
74
|
+
environment: Mapping[str, str],
|
|
75
|
+
) -> dict[str, str]:
|
|
76
|
+
"""Prepend installed NVIDIA wheel libraries to a child environment."""
|
|
77
|
+
|
|
78
|
+
prepared = dict(environment)
|
|
79
|
+
library_paths = _nvidia_wheel_library_paths()
|
|
80
|
+
if not library_paths:
|
|
81
|
+
return prepared
|
|
82
|
+
|
|
83
|
+
search_variable = "PATH" if os.name == "nt" else "LD_LIBRARY_PATH"
|
|
84
|
+
existing_paths = tuple(
|
|
85
|
+
path for path in prepared.get(search_variable, "").split(os.pathsep) if path
|
|
86
|
+
)
|
|
87
|
+
prepared[search_variable] = os.pathsep.join(dict.fromkeys((*library_paths, *existing_paths)))
|
|
88
|
+
return prepared
|
|
44
89
|
|
|
45
90
|
|
|
46
91
|
class MemoryContractAttribute(str, Enum):
|
|
@@ -501,6 +546,7 @@ class FrameworkRuntime:
|
|
|
501
546
|
dlpack_exporter: DLPackExporter | None = None
|
|
502
547
|
dlpack_validator: DLPackValidator = _protocol_dlpack
|
|
503
548
|
oom_matcher: OOMMatcher = _never_oom
|
|
549
|
+
subprocess_environment: SubprocessEnvironmentResolver = _identity_subprocess_environment
|
|
504
550
|
|
|
505
551
|
|
|
506
552
|
class _MemoryTypeFields:
|
|
@@ -510,7 +556,7 @@ class _MemoryTypeFields:
|
|
|
510
556
|
module_aliases: tuple[str, ...]
|
|
511
557
|
import_environment: tuple[tuple[str, str], ...]
|
|
512
558
|
_runtime: FrameworkRuntime
|
|
513
|
-
|
|
559
|
+
_operations_name: str
|
|
514
560
|
|
|
515
561
|
|
|
516
562
|
class MemoryType(_MemoryTypeFields, Enum):
|
|
@@ -520,7 +566,7 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
520
566
|
cls,
|
|
521
567
|
value: str,
|
|
522
568
|
*declaration: Any,
|
|
523
|
-
) ->
|
|
569
|
+
) -> MemoryType:
|
|
524
570
|
(
|
|
525
571
|
import_name,
|
|
526
572
|
display_name,
|
|
@@ -538,9 +584,18 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
538
584
|
member.module_aliases = cast(tuple[str, ...], module_aliases)
|
|
539
585
|
member.import_environment = cast(tuple[tuple[str, str], ...], import_environment)
|
|
540
586
|
member._runtime = cast(FrameworkRuntime, runtime)
|
|
541
|
-
member.
|
|
587
|
+
member._operations_name = cast(str, operations)
|
|
542
588
|
return member
|
|
543
589
|
|
|
590
|
+
@property
|
|
591
|
+
def _operations(self) -> ArrayOperations:
|
|
592
|
+
"""Resolve this declaration's operations registry on first access."""
|
|
593
|
+
|
|
594
|
+
from arraybridge import array_operations
|
|
595
|
+
|
|
596
|
+
operations: ArrayOperations = getattr(array_operations, self._operations_name)
|
|
597
|
+
return operations
|
|
598
|
+
|
|
544
599
|
NUMPY = (
|
|
545
600
|
"numpy",
|
|
546
601
|
"numpy",
|
|
@@ -549,7 +604,7 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
549
604
|
(),
|
|
550
605
|
(),
|
|
551
606
|
FrameworkRuntime(oom_matcher=_numpy_oom),
|
|
552
|
-
NUMPY_OPERATIONS,
|
|
607
|
+
"NUMPY_OPERATIONS",
|
|
553
608
|
)
|
|
554
609
|
CUPY = (
|
|
555
610
|
"cupy",
|
|
@@ -571,8 +626,9 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
571
626
|
dlpack_importer=_cupy_from_dlpack,
|
|
572
627
|
dlpack_exporter=_protocol_dlpack_export,
|
|
573
628
|
oom_matcher=_cupy_oom,
|
|
629
|
+
subprocess_environment=_nvidia_wheel_subprocess_environment,
|
|
574
630
|
),
|
|
575
|
-
CUPY_OPERATIONS,
|
|
631
|
+
"CUPY_OPERATIONS",
|
|
576
632
|
)
|
|
577
633
|
TORCH = (
|
|
578
634
|
"torch",
|
|
@@ -595,7 +651,7 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
595
651
|
dlpack_exporter=_protocol_dlpack_export,
|
|
596
652
|
oom_matcher=_torch_oom,
|
|
597
653
|
),
|
|
598
|
-
TORCH_OPERATIONS,
|
|
654
|
+
"TORCH_OPERATIONS",
|
|
599
655
|
)
|
|
600
656
|
TENSORFLOW = (
|
|
601
657
|
"tensorflow",
|
|
@@ -614,7 +670,7 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
614
670
|
dlpack_validator=_tensorflow_dlpack,
|
|
615
671
|
oom_matcher=_tensorflow_oom,
|
|
616
672
|
),
|
|
617
|
-
TENSORFLOW_OPERATIONS,
|
|
673
|
+
"TENSORFLOW_OPERATIONS",
|
|
618
674
|
)
|
|
619
675
|
JAX = (
|
|
620
676
|
"jax",
|
|
@@ -632,7 +688,7 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
632
688
|
dlpack_exporter=_protocol_dlpack_export,
|
|
633
689
|
oom_matcher=_jax_oom,
|
|
634
690
|
),
|
|
635
|
-
JAX_OPERATIONS,
|
|
691
|
+
"JAX_OPERATIONS",
|
|
636
692
|
)
|
|
637
693
|
PYCLESPERANTO = (
|
|
638
694
|
"pyclesperanto",
|
|
@@ -649,7 +705,7 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
649
705
|
move_to_active_device=_pyclesperanto_device_move,
|
|
650
706
|
oom_matcher=_pyclesperanto_oom,
|
|
651
707
|
),
|
|
652
|
-
PYCLESPERANTO_OPERATIONS,
|
|
708
|
+
"PYCLESPERANTO_OPERATIONS",
|
|
653
709
|
)
|
|
654
710
|
|
|
655
711
|
@property
|
|
@@ -682,6 +738,20 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
682
738
|
for name, value in self.import_environment:
|
|
683
739
|
os.environ.setdefault(name, value)
|
|
684
740
|
|
|
741
|
+
@classmethod
|
|
742
|
+
def subprocess_environment(
|
|
743
|
+
cls,
|
|
744
|
+
environment: Mapping[str, str] | None = None,
|
|
745
|
+
) -> dict[str, str]:
|
|
746
|
+
"""Project framework import requirements into a child environment."""
|
|
747
|
+
|
|
748
|
+
prepared = dict(os.environ if environment is None else environment)
|
|
749
|
+
for memory_type in cls:
|
|
750
|
+
for name, value in memory_type.import_environment:
|
|
751
|
+
prepared.setdefault(name, value)
|
|
752
|
+
prepared = memory_type._runtime.subprocess_environment(prepared)
|
|
753
|
+
return prepared
|
|
754
|
+
|
|
685
755
|
def loaded_module(self) -> Any | None:
|
|
686
756
|
"""Return an already-loaded framework without causing an import."""
|
|
687
757
|
|
|
@@ -887,7 +957,7 @@ class MemoryType(_MemoryTypeFields, Enum):
|
|
|
887
957
|
payload = data if isinstance(data, DLPackPayload) else DLPackPayload(data, data)
|
|
888
958
|
return importer(payload, framework)
|
|
889
959
|
|
|
890
|
-
def convert_to(self, data: Any, target:
|
|
960
|
+
def convert_to(self, data: Any, target: MemoryType, device_id: int) -> Any:
|
|
891
961
|
"""Convert one array through the source and target declarations."""
|
|
892
962
|
|
|
893
963
|
if self is target:
|
|
@@ -145,6 +145,58 @@ class TestMemoryTypeOwnership:
|
|
|
145
145
|
assert os.environ["TF_FORCE_GPU_ALLOW_GROWTH"] == "true"
|
|
146
146
|
assert os.environ["XLA_PYTHON_CLIENT_PREALLOCATE"] == "custom"
|
|
147
147
|
|
|
148
|
+
def test_subprocess_environment_derives_nvidia_wheel_paths_from_cupy_owner(
|
|
149
|
+
self,
|
|
150
|
+
monkeypatch,
|
|
151
|
+
tmp_path,
|
|
152
|
+
):
|
|
153
|
+
from arraybridge import types
|
|
154
|
+
|
|
155
|
+
nvidia_root = tmp_path / "nvidia"
|
|
156
|
+
cublas_lib = nvidia_root / "cublas" / "lib"
|
|
157
|
+
runtime_bin = nvidia_root / "cuda_runtime" / "bin"
|
|
158
|
+
cublas_lib.mkdir(parents=True)
|
|
159
|
+
runtime_bin.mkdir(parents=True)
|
|
160
|
+
monkeypatch.setattr(
|
|
161
|
+
types.importlib.util,
|
|
162
|
+
"find_spec",
|
|
163
|
+
lambda name: (
|
|
164
|
+
SimpleNamespace(submodule_search_locations=(str(nvidia_root),))
|
|
165
|
+
if name == "nvidia"
|
|
166
|
+
else None
|
|
167
|
+
),
|
|
168
|
+
)
|
|
169
|
+
search_variable = "PATH" if os.name == "nt" else "LD_LIBRARY_PATH"
|
|
170
|
+
original = {search_variable: "/existing", "CUSTOM": "value"}
|
|
171
|
+
|
|
172
|
+
prepared = MemoryType.subprocess_environment(original)
|
|
173
|
+
|
|
174
|
+
assert original == {search_variable: "/existing", "CUSTOM": "value"}
|
|
175
|
+
assert prepared[search_variable].split(os.pathsep) == [
|
|
176
|
+
*sorted((str(cublas_lib), str(runtime_bin))),
|
|
177
|
+
"/existing",
|
|
178
|
+
]
|
|
179
|
+
assert prepared["CUSTOM"] == "value"
|
|
180
|
+
assert prepared["TF_FORCE_GPU_ALLOW_GROWTH"] == "true"
|
|
181
|
+
assert prepared["XLA_PYTHON_CLIENT_PREALLOCATE"] == "false"
|
|
182
|
+
|
|
183
|
+
def test_subprocess_environment_preserves_host_values_without_nvidia_wheels(
|
|
184
|
+
self,
|
|
185
|
+
monkeypatch,
|
|
186
|
+
):
|
|
187
|
+
from arraybridge import types
|
|
188
|
+
|
|
189
|
+
monkeypatch.setattr(types.importlib.util, "find_spec", lambda name: None)
|
|
190
|
+
original = {
|
|
191
|
+
"TF_FORCE_GPU_ALLOW_GROWTH": "host",
|
|
192
|
+
"XLA_PYTHON_CLIENT_PREALLOCATE": "host",
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
prepared = MemoryType.subprocess_environment(original)
|
|
196
|
+
|
|
197
|
+
assert prepared == original
|
|
198
|
+
assert prepared is not original
|
|
199
|
+
|
|
148
200
|
def test_preloaded_framework_reports_late_import_preparation(
|
|
149
201
|
self,
|
|
150
202
|
monkeypatch,
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Update ArrayBridge's three version projections without Git side effects."""
|
|
3
|
-
|
|
4
|
-
import argparse
|
|
5
|
-
import re
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
|
|
8
|
-
from packaging.version import InvalidVersion, Version
|
|
9
|
-
|
|
10
|
-
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
11
|
-
VERSION_FILES = {
|
|
12
|
-
PROJECT_ROOT
|
|
13
|
-
/ "src/arraybridge/__init__.py": (
|
|
14
|
-
r"(__version__\s*=\s*['\"])([^'\"]+)(['\"])",
|
|
15
|
-
"package",
|
|
16
|
-
),
|
|
17
|
-
PROJECT_ROOT
|
|
18
|
-
/ "pyproject.toml": (
|
|
19
|
-
r"(^version\s*=\s*['\"])([^'\"]+)(['\"])",
|
|
20
|
-
"project",
|
|
21
|
-
),
|
|
22
|
-
PROJECT_ROOT
|
|
23
|
-
/ "docs/source/conf.py": (
|
|
24
|
-
r"(^release\s*=\s*['\"])([^'\"]+)(['\"])",
|
|
25
|
-
"documentation",
|
|
26
|
-
),
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def current_version() -> Version:
|
|
31
|
-
"""Return the agreed version, failing when a projection has drifted."""
|
|
32
|
-
declared_versions: dict[str, Version] = {}
|
|
33
|
-
for path, (pattern, projection_name) in VERSION_FILES.items():
|
|
34
|
-
match = re.search(pattern, path.read_text(encoding="utf-8"), flags=re.MULTILINE)
|
|
35
|
-
if match is None:
|
|
36
|
-
raise RuntimeError(f"Version declaration is missing from {path}")
|
|
37
|
-
declared_versions[projection_name] = Version(match.group(2))
|
|
38
|
-
|
|
39
|
-
unique_versions = set(declared_versions.values())
|
|
40
|
-
if len(unique_versions) != 1:
|
|
41
|
-
declarations = ", ".join(f"{name}={version}" for name, version in declared_versions.items())
|
|
42
|
-
raise RuntimeError(f"Version projections have drifted: {declarations}")
|
|
43
|
-
return unique_versions.pop()
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def update_version(version_text: str) -> None:
|
|
47
|
-
try:
|
|
48
|
-
requested = Version(version_text)
|
|
49
|
-
except InvalidVersion as error:
|
|
50
|
-
raise ValueError(f"Invalid version: {version_text}") from error
|
|
51
|
-
current = current_version()
|
|
52
|
-
if requested <= current:
|
|
53
|
-
raise ValueError(f"New version {requested} must be greater than {current}")
|
|
54
|
-
|
|
55
|
-
for path, (pattern, _projection_name) in VERSION_FILES.items():
|
|
56
|
-
content = path.read_text(encoding="utf-8")
|
|
57
|
-
updated, count = re.subn(
|
|
58
|
-
pattern,
|
|
59
|
-
rf"\g<1>{requested}\g<3>",
|
|
60
|
-
content,
|
|
61
|
-
flags=re.MULTILINE,
|
|
62
|
-
)
|
|
63
|
-
if count != 1:
|
|
64
|
-
raise RuntimeError(f"Expected one version declaration in {path}, found {count}")
|
|
65
|
-
path.write_text(updated, encoding="utf-8")
|
|
66
|
-
|
|
67
|
-
print(f"Updated ArrayBridge version projections to {requested}")
|
|
68
|
-
print("Run scripts/verify_release_ready.py --allow-dirty, then review and commit.")
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def main() -> None:
|
|
72
|
-
parser = argparse.ArgumentParser(description=__doc__)
|
|
73
|
-
parser.add_argument("version", help="New release version, for example 0.3.0")
|
|
74
|
-
args = parser.parse_args()
|
|
75
|
-
update_version(args.version)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if __name__ == "__main__":
|
|
79
|
-
main()
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
arraybridge: Unified API for NumPy, CuPy, PyTorch, TensorFlow, JAX, and pyclesperanto.
|
|
3
|
-
|
|
4
|
-
This package provides automatic memory type conversion, declarative decorators,
|
|
5
|
-
and unified utilities for working with multiple array/tensor frameworks.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
__version__ = "0.3.2"
|
|
9
|
-
|
|
10
|
-
from . import decorators as _decorators
|
|
11
|
-
from .array_geometry import ArrayGeometry
|
|
12
|
-
from .array_payload import ArrayPayload
|
|
13
|
-
from .converters import convert_memory, detect_memory_type
|
|
14
|
-
from .dtype_scaling import SCALING_FUNCTIONS
|
|
15
|
-
from .exceptions import MemoryConversionError
|
|
16
|
-
from .framework_config import _FRAMEWORK_CONFIG
|
|
17
|
-
from .framework_ops import _FRAMEWORK_OPS
|
|
18
|
-
from .gpu_cleanup import cleanup_all_gpu_frameworks
|
|
19
|
-
from .oom_recovery import _execute_with_oom_recovery
|
|
20
|
-
from .slice_processing import process_slices
|
|
21
|
-
from .stack_utils import stack_slices, unstack_slices
|
|
22
|
-
from .types import (
|
|
23
|
-
CPU_MEMORY_TYPES,
|
|
24
|
-
GPU_MEMORY_TYPES,
|
|
25
|
-
SUPPORTED_MEMORY_TYPES,
|
|
26
|
-
MemoryContractAttribute,
|
|
27
|
-
MemoryType,
|
|
28
|
-
)
|
|
29
|
-
from .utils import _ensure_module, _get_device_id, _supports_dlpack
|
|
30
|
-
|
|
31
|
-
DtypeConversion = _decorators.DtypeConversion
|
|
32
|
-
SliceBySliceRuntimeParameter = _decorators.SliceBySliceRuntimeParameter
|
|
33
|
-
memory_types = _decorators.memory_types
|
|
34
|
-
wrap_dtype_preserving_callable = _decorators.wrap_dtype_preserving_callable
|
|
35
|
-
for _memory_type in MemoryType:
|
|
36
|
-
globals()[_memory_type.value] = getattr(_decorators, _memory_type.value)
|
|
37
|
-
|
|
38
|
-
__all__ = [
|
|
39
|
-
# Types
|
|
40
|
-
"MemoryType",
|
|
41
|
-
"MemoryContractAttribute",
|
|
42
|
-
"ArrayPayload",
|
|
43
|
-
"ArrayGeometry",
|
|
44
|
-
"CPU_MEMORY_TYPES",
|
|
45
|
-
"GPU_MEMORY_TYPES",
|
|
46
|
-
"SUPPORTED_MEMORY_TYPES",
|
|
47
|
-
# Converters
|
|
48
|
-
"convert_memory",
|
|
49
|
-
"detect_memory_type",
|
|
50
|
-
# Decorators
|
|
51
|
-
"memory_types",
|
|
52
|
-
"DtypeConversion",
|
|
53
|
-
"SliceBySliceRuntimeParameter",
|
|
54
|
-
"wrap_dtype_preserving_callable",
|
|
55
|
-
# Stack utilities
|
|
56
|
-
"stack_slices",
|
|
57
|
-
"unstack_slices",
|
|
58
|
-
# Slice processing
|
|
59
|
-
"process_slices",
|
|
60
|
-
# GPU cleanup
|
|
61
|
-
"cleanup_all_gpu_frameworks",
|
|
62
|
-
# Exceptions
|
|
63
|
-
"MemoryConversionError",
|
|
64
|
-
# Scaling
|
|
65
|
-
"SCALING_FUNCTIONS",
|
|
66
|
-
# Framework config (internal but needed by some consumers)
|
|
67
|
-
"_FRAMEWORK_CONFIG",
|
|
68
|
-
"_FRAMEWORK_OPS",
|
|
69
|
-
# OOM recovery
|
|
70
|
-
"_execute_with_oom_recovery",
|
|
71
|
-
# Utils
|
|
72
|
-
"_ensure_module",
|
|
73
|
-
"_supports_dlpack",
|
|
74
|
-
"_get_device_id",
|
|
75
|
-
] + [memory_type.value for memory_type in MemoryType]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|