arraybridge 0.2.9__tar.gz → 0.2.11__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.
Files changed (111) hide show
  1. arraybridge-0.2.11/.github/badges/coverage.svg +1 -0
  2. {arraybridge-0.2.9 → arraybridge-0.2.11}/ADDING_NEW_FRAMEWORKS.md +11 -7
  3. {arraybridge-0.2.9 → arraybridge-0.2.11}/CONTRIBUTING.md +2 -4
  4. arraybridge-0.2.11/PKG-INFO +137 -0
  5. arraybridge-0.2.11/README.md +70 -0
  6. {arraybridge-0.2.9 → arraybridge-0.2.11}/SETUP_INSTRUCTIONS.md +4 -4
  7. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/CI_IMPROVEMENTS.md +0 -1
  8. arraybridge-0.2.11/docs/archive/README.md +5 -0
  9. arraybridge-0.2.11/docs/ci-cd.md +7 -0
  10. arraybridge-0.2.11/docs/source/README.md +15 -0
  11. arraybridge-0.2.11/docs/source/advanced_topics.rst +20 -0
  12. arraybridge-0.2.11/docs/source/api_reference.rst +38 -0
  13. arraybridge-0.2.11/docs/source/ci-cd.rst +25 -0
  14. {arraybridge-0.2.9 → arraybridge-0.2.11}/docs/source/conf.py +13 -5
  15. arraybridge-0.2.11/docs/source/contributing.rst +27 -0
  16. arraybridge-0.2.11/docs/source/converters.rst +36 -0
  17. arraybridge-0.2.11/docs/source/decorators.rst +40 -0
  18. arraybridge-0.2.11/docs/source/examples/basic_conversion.rst +16 -0
  19. arraybridge-0.2.11/docs/source/examples/decorators.rst +18 -0
  20. arraybridge-0.2.11/docs/source/examples/multi_framework.rst +18 -0
  21. arraybridge-0.2.11/docs/source/gpu_features.rst +19 -0
  22. arraybridge-0.2.11/docs/source/index.rst +33 -0
  23. arraybridge-0.2.11/docs/source/installation.rst +58 -0
  24. arraybridge-0.2.11/docs/source/quickstart.rst +54 -0
  25. arraybridge-0.2.11/docs/source/stack_utils.rst +25 -0
  26. arraybridge-0.2.11/docs/source/user_guide.rst +35 -0
  27. {arraybridge-0.2.9 → arraybridge-0.2.11}/pyproject.toml +6 -7
  28. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/__init__.py +1 -1
  29. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/decorators.py +306 -50
  30. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_converters_registry.py +10 -8
  31. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_decorators.py +23 -7
  32. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_registry_integration.py +3 -2
  33. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_types.py +5 -15
  34. arraybridge-0.2.9/.github/badges/coverage.svg +0 -1
  35. arraybridge-0.2.9/PKG-INFO +0 -243
  36. arraybridge-0.2.9/README.md +0 -175
  37. arraybridge-0.2.9/docs/ci-cd.md +0 -352
  38. arraybridge-0.2.9/docs/source/README.md +0 -145
  39. arraybridge-0.2.9/docs/source/advanced_topics.rst +0 -637
  40. arraybridge-0.2.9/docs/source/api/converters.rst +0 -46
  41. arraybridge-0.2.9/docs/source/api/decorators.rst +0 -72
  42. arraybridge-0.2.9/docs/source/api/exceptions.rst +0 -39
  43. arraybridge-0.2.9/docs/source/api/index.rst +0 -24
  44. arraybridge-0.2.9/docs/source/api/types.rst +0 -54
  45. arraybridge-0.2.9/docs/source/api/utils.rst +0 -70
  46. arraybridge-0.2.9/docs/source/api_reference.rst +0 -629
  47. arraybridge-0.2.9/docs/source/ci-cd.rst +0 -32
  48. arraybridge-0.2.9/docs/source/contributing.rst +0 -24
  49. arraybridge-0.2.9/docs/source/converters.rst +0 -474
  50. arraybridge-0.2.9/docs/source/decorators.rst +0 -638
  51. arraybridge-0.2.9/docs/source/examples/basic_conversion.rst +0 -98
  52. arraybridge-0.2.9/docs/source/examples/decorators.rst +0 -124
  53. arraybridge-0.2.9/docs/source/examples/multi_framework.rst +0 -132
  54. arraybridge-0.2.9/docs/source/gpu_features.rst +0 -624
  55. arraybridge-0.2.9/docs/source/index.rst +0 -96
  56. arraybridge-0.2.9/docs/source/installation.rst +0 -229
  57. arraybridge-0.2.9/docs/source/quickstart.rst +0 -281
  58. arraybridge-0.2.9/docs/source/stack_utils.rst +0 -603
  59. arraybridge-0.2.9/docs/source/user_guide.rst +0 -568
  60. {arraybridge-0.2.9 → arraybridge-0.2.11}/.github/workflows/ci.yml +0 -0
  61. {arraybridge-0.2.9 → arraybridge-0.2.11}/.github/workflows/coverage-pages.yml +0 -0
  62. {arraybridge-0.2.9 → arraybridge-0.2.11}/.github/workflows/gpu-tests.yml +0 -0
  63. {arraybridge-0.2.9 → arraybridge-0.2.11}/.github/workflows/publish.yml +0 -0
  64. {arraybridge-0.2.9 → arraybridge-0.2.11}/.gitignore +0 -0
  65. {arraybridge-0.2.9 → arraybridge-0.2.11}/.readthedocs.yml +0 -0
  66. {arraybridge-0.2.9 → arraybridge-0.2.11}/LICENSE +0 -0
  67. {arraybridge-0.2.9 → arraybridge-0.2.11}/TESTING.md +0 -0
  68. {arraybridge-0.2.9 → arraybridge-0.2.11}/docs/Makefile +0 -0
  69. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/CI_ARTIFACT_UPDATE.md +0 -0
  70. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/CI_CUPY_FIX.md +0 -0
  71. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/CONFLICT_VISUALIZATION.md +0 -0
  72. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/COVERAGE_AUDIT_PLAN.md +0 -0
  73. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/DEPLOYMENT_SUMMARY.md +0 -0
  74. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/GPU_TESTING_SETUP.md +0 -0
  75. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/MERGE_CONFLICT_RESOLUTION.md +0 -0
  76. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/MIGRATION_SUMMARY.md +0 -0
  77. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/QUICK_FIX_GUIDE.txt +0 -0
  78. {arraybridge-0.2.9 → arraybridge-0.2.11/docs/archive}/RESOLVED_FILES.md +0 -0
  79. {arraybridge-0.2.9 → arraybridge-0.2.11}/docs/source/.gitignore +0 -0
  80. {arraybridge-0.2.9 → arraybridge-0.2.11}/docs/source/Makefile +0 -0
  81. {arraybridge-0.2.9 → arraybridge-0.2.11}/docs/source/examples/index.rst +0 -0
  82. {arraybridge-0.2.9 → arraybridge-0.2.11}/paper.bib +0 -0
  83. {arraybridge-0.2.9 → arraybridge-0.2.11}/paper.md +0 -0
  84. {arraybridge-0.2.9 → arraybridge-0.2.11}/scripts/release.py +0 -0
  85. {arraybridge-0.2.9 → arraybridge-0.2.11}/scripts/update_and_release.py +0 -0
  86. {arraybridge-0.2.9 → arraybridge-0.2.11}/scripts/update_version.py +0 -0
  87. {arraybridge-0.2.9 → arraybridge-0.2.11}/scripts/verify_release_ready.py +0 -0
  88. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/converters.py +0 -0
  89. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/converters_registry.py +0 -0
  90. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/dtype_scaling.py +0 -0
  91. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/exceptions.py +0 -0
  92. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/framework_config.py +0 -0
  93. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/framework_ops.py +0 -0
  94. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/gpu_cleanup.py +0 -0
  95. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/oom_recovery.py +0 -0
  96. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/slice_processing.py +0 -0
  97. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/stack_utils.py +0 -0
  98. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/types.py +0 -0
  99. {arraybridge-0.2.9 → arraybridge-0.2.11}/src/arraybridge/utils.py +0 -0
  100. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/__init__.py +0 -0
  101. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/conftest.py +0 -0
  102. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_converters.py +0 -0
  103. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_dtype_scaling.py +0 -0
  104. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_exceptions.py +0 -0
  105. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_framework_config.py +0 -0
  106. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_gpu_cleanup.py +0 -0
  107. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_integration.py +0 -0
  108. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_oom_recovery.py +0 -0
  109. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_slice_processing.py +0 -0
  110. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_stack_utils.py +0 -0
  111. {arraybridge-0.2.9 → arraybridge-0.2.11}/tests/test_utils.py +0 -0
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 75.14%"><title>coverage: 75.14%</title><filter id="blur"><feGaussianBlur stdDeviation="16"/></filter><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#67ac09"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="315" y="150" fill-opacity=".8" filter="url(#blur)" textLength="510">coverage</text><text x="315" y="150" fill-opacity=".3" textLength="510">coverage</text></g><text x="315" y="140" textLength="510">coverage</text></g><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="865" y="150" fill-opacity=".8" filter="url(#blur)" textLength="430">75.14%</text><text x="865" y="150" fill-opacity=".3" textLength="430">75.14%</text></g><text x="865" y="140" textLength="430">75.14%</text></g></g></svg>
@@ -99,13 +99,15 @@ converter = MemoryType.MXNET.converter
99
99
  class MxnetConverter(MemoryTypeConverter):
100
100
  def to_numpy(self, data, gpu_id):
101
101
  return data.asnumpy()
102
+
102
103
  def from_numpy(self, data, gpu_id):
103
104
  return mxnet.nd.array(data)
105
+
104
106
  def to_torch(self, data, gpu_id):
105
- # ... manual implementation
107
+ raise NotImplementedError
108
+
106
109
  def to_cupy(self, data, gpu_id):
107
- # ... manual implementation
108
- # ... 6+ more methods
110
+ raise NotImplementedError
109
111
 
110
112
  # Had to manually register
111
113
  _CONVERTERS[MemoryType.MXNET] = MxnetConverter()
@@ -113,8 +115,10 @@ _CONVERTERS[MemoryType.MXNET] = MxnetConverter()
113
115
 
114
116
  ### After (Auto-registration - New System)
115
117
  ```python
116
- # Just add to enum and config - everything else is automatic!
117
- MemoryType.MXNET = "mxnet"
118
+ # Add one enum member and one config entry; everything else is automatic.
119
+ class MemoryType(Enum):
120
+ # Existing members omitted.
121
+ MXNET = "mxnet"
118
122
 
119
123
  _FRAMEWORK_CONFIG[MemoryType.MXNET] = {
120
124
  'conversion_ops': {
@@ -160,7 +164,7 @@ def test_convert_numpy_to_mxnet(self, mxnet_available):
160
164
 
161
165
  ### GPU Framework with DLPack
162
166
  ```python
163
- 'conversion_ops': {
167
+ conversion_ops = {
164
168
  'to_numpy': 'data.cpu().numpy()',
165
169
  'from_numpy': '{mod}.from_numpy(data).to(device=gpu_id)',
166
170
  'from_dlpack': '{mod}.from_dlpack(data)',
@@ -170,7 +174,7 @@ def test_convert_numpy_to_mxnet(self, mxnet_available):
170
174
 
171
175
  ### CPU-only Framework
172
176
  ```python
173
- 'conversion_ops': {
177
+ conversion_ops = {
174
178
  'to_numpy': 'np.array(data)',
175
179
  'from_numpy': '{mod}.array(data)',
176
180
  'from_dlpack': None, # Not supported
@@ -35,7 +35,7 @@ We are committed to providing a welcoming and inclusive environment. Please be r
35
35
 
36
36
  ### Finding Issues
37
37
 
38
- - Check the [issue tracker](https://github.com/trissim/arraybridge/issues)
38
+ - Check the [issue tracker](https://github.com/OpenHCSDev/arraybridge/issues)
39
39
  - Look for issues labeled `good first issue` or `help wanted`
40
40
  - Feel free to create new issues for bugs or feature requests
41
41
 
@@ -49,7 +49,7 @@ git clone https://github.com/YOUR_USERNAME/arraybridge.git
49
49
  cd arraybridge
50
50
 
51
51
  # Add upstream remote
52
- git remote add upstream https://github.com/trissim/arraybridge.git
52
+ git remote add upstream https://github.com/OpenHCSDev/arraybridge.git
53
53
  ```
54
54
 
55
55
  ### 2. Create Virtual Environment
@@ -135,13 +135,11 @@ def convert_memory(data: Any, source_type: str, target_type: str, gpu_id: int) -
135
135
  MemoryConversionError: If conversion fails
136
136
 
137
137
  Example:
138
- ```python
139
138
  import numpy as np
140
139
  from arraybridge import convert_memory
141
140
 
142
141
  data = np.array([1, 2, 3])
143
142
  result = convert_memory(data, "numpy", "torch", gpu_id=0)
144
- ```
145
143
  """
146
144
  ```
147
145
 
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: arraybridge
3
+ Version: 0.2.11
4
+ Summary: Unified API for NumPy, CuPy, PyTorch, TensorFlow, JAX, and pyclesperanto with automatic memory type conversion
5
+ Project-URL: Homepage, https://github.com/OpenHCSDev/arraybridge
6
+ Project-URL: Documentation, https://arraybridge.readthedocs.io
7
+ Project-URL: Repository, https://github.com/OpenHCSDev/arraybridge
8
+ Project-URL: Issues, https://github.com/OpenHCSDev/arraybridge/issues
9
+ Author-email: Tristan Simas <tristan.simas@mail.mcgill.ca>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: array,conversion,cupy,gpu,jax,numpy,pytorch,tensor,tensorflow
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: metaclass-registry>=0.1.5
25
+ Requires-Dist: numpy>=1.20
26
+ Provides-Extra: all
27
+ Requires-Dist: cupy>=10.0; extra == 'all'
28
+ Requires-Dist: jax>=0.3; extra == 'all'
29
+ Requires-Dist: jaxlib>=0.3; extra == 'all'
30
+ Requires-Dist: pyclesperanto>=0.10; extra == 'all'
31
+ Requires-Dist: tensorflow>=2.8; extra == 'all'
32
+ Requires-Dist: torch>=1.10; extra == 'all'
33
+ Provides-Extra: cupy
34
+ Requires-Dist: cupy>=10.0; extra == 'cupy'
35
+ Provides-Extra: dev
36
+ Requires-Dist: black>=23.0; extra == 'dev'
37
+ Requires-Dist: mypy>=1.0; extra == 'dev'
38
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
39
+ Requires-Dist: pytest>=7.0; extra == 'dev'
40
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
41
+ Provides-Extra: docs
42
+ Requires-Dist: sphinx-autodoc-typehints>=1.25; extra == 'docs'
43
+ Requires-Dist: sphinx-rtd-theme>=2.0; extra == 'docs'
44
+ Requires-Dist: sphinx>=7.0; extra == 'docs'
45
+ Provides-Extra: gpu
46
+ Requires-Dist: cucim-cu12<26.0.0,>=25.6.0; extra == 'gpu'
47
+ Requires-Dist: cupy-cuda12x<14.0.0,>=13.3.0; extra == 'gpu'
48
+ Requires-Dist: jax-cuda12-pjrt<0.6.0,>=0.5.3; extra == 'gpu'
49
+ Requires-Dist: jax-cuda12-plugin<0.6.0,>=0.5.3; extra == 'gpu'
50
+ Requires-Dist: jax<0.6.0,>=0.5.3; extra == 'gpu'
51
+ Requires-Dist: jaxlib<0.6.0,>=0.5.3; extra == 'gpu'
52
+ Requires-Dist: pyclesperanto>=0.17.1; extra == 'gpu'
53
+ Requires-Dist: tensorflow-probability[tf]<0.26.0,>=0.25.0; extra == 'gpu'
54
+ Requires-Dist: tensorflow<2.20.0,>=2.19.0; extra == 'gpu'
55
+ Requires-Dist: torch<2.8.0,>=2.6.0; extra == 'gpu'
56
+ Requires-Dist: torchvision<0.23.0,>=0.21.0; extra == 'gpu'
57
+ Provides-Extra: jax
58
+ Requires-Dist: jax>=0.3; extra == 'jax'
59
+ Requires-Dist: jaxlib>=0.3; extra == 'jax'
60
+ Provides-Extra: pyclesperanto
61
+ Requires-Dist: pyclesperanto>=0.10; extra == 'pyclesperanto'
62
+ Provides-Extra: tensorflow
63
+ Requires-Dist: tensorflow>=2.8; extra == 'tensorflow'
64
+ Provides-Extra: torch
65
+ Requires-Dist: torch>=1.10; extra == 'torch'
66
+ Description-Content-Type: text/markdown
67
+
68
+ # arraybridge
69
+
70
+ ArrayBridge provides explicit conversion and shared lifecycle utilities for
71
+ NumPy, CuPy, PyTorch, TensorFlow, JAX, and pyclesperanto arrays.
72
+
73
+ Core dependencies are NumPy and metaclass-registry. Other frameworks are
74
+ optional.
75
+
76
+ ## Quick start
77
+
78
+ ```python
79
+ import numpy as np
80
+
81
+ from arraybridge import convert_memory, detect_memory_type
82
+
83
+ value = np.arange(6).reshape(2, 3)
84
+ assert detect_memory_type(value) == "numpy"
85
+
86
+ copy = convert_memory(
87
+ value,
88
+ source_type="numpy",
89
+ target_type="numpy",
90
+ gpu_id=0,
91
+ )
92
+ ```
93
+
94
+ `convert_memory` requires the declared source type, target type, and device id.
95
+ It uses the registered converter for the source framework. The device id is
96
+ required even for CPU conversions so call sites have one stable signature.
97
+
98
+ ## Declarative decorators
99
+
100
+ ```python
101
+ from arraybridge import numpy
102
+
103
+ @numpy
104
+ def normalize(image):
105
+ return image / max(float(image.max()), 1.0)
106
+ ```
107
+
108
+ The framework decorators attach `input_memory_type` and `output_memory_type`
109
+ metadata, provide dtype/slice runtime parameters, and add framework-specific
110
+ stream/OOM handling where supported. They do **not** convert inputs or outputs
111
+ between frameworks and do not accept a `gpu_id` argument. A host runtime must
112
+ call `convert_memory` at the boundary it plans.
113
+
114
+ ## Stack utilities
115
+
116
+ ```python
117
+ import numpy as np
118
+
119
+ from arraybridge import stack_slices, unstack_slices
120
+
121
+ slices = [np.zeros((8, 8)), np.ones((8, 8))]
122
+ stack = stack_slices(slices, memory_type="numpy", gpu_id=0)
123
+ restored = unstack_slices(stack, memory_type="numpy", gpu_id=0)
124
+ ```
125
+
126
+ `stack_slices` requires non-empty 2D inputs. `unstack_slices` requires a 3D
127
+ array. Both validate shape and use explicit target memory/device declarations.
128
+
129
+ ## Installation
130
+
131
+ ```bash
132
+ pip install arraybridge
133
+ pip install "arraybridge[torch]"
134
+ pip install "arraybridge[cupy]"
135
+ ```
136
+
137
+ Documentation: <https://arraybridge.readthedocs.io>
@@ -0,0 +1,70 @@
1
+ # arraybridge
2
+
3
+ ArrayBridge provides explicit conversion and shared lifecycle utilities for
4
+ NumPy, CuPy, PyTorch, TensorFlow, JAX, and pyclesperanto arrays.
5
+
6
+ Core dependencies are NumPy and metaclass-registry. Other frameworks are
7
+ optional.
8
+
9
+ ## Quick start
10
+
11
+ ```python
12
+ import numpy as np
13
+
14
+ from arraybridge import convert_memory, detect_memory_type
15
+
16
+ value = np.arange(6).reshape(2, 3)
17
+ assert detect_memory_type(value) == "numpy"
18
+
19
+ copy = convert_memory(
20
+ value,
21
+ source_type="numpy",
22
+ target_type="numpy",
23
+ gpu_id=0,
24
+ )
25
+ ```
26
+
27
+ `convert_memory` requires the declared source type, target type, and device id.
28
+ It uses the registered converter for the source framework. The device id is
29
+ required even for CPU conversions so call sites have one stable signature.
30
+
31
+ ## Declarative decorators
32
+
33
+ ```python
34
+ from arraybridge import numpy
35
+
36
+ @numpy
37
+ def normalize(image):
38
+ return image / max(float(image.max()), 1.0)
39
+ ```
40
+
41
+ The framework decorators attach `input_memory_type` and `output_memory_type`
42
+ metadata, provide dtype/slice runtime parameters, and add framework-specific
43
+ stream/OOM handling where supported. They do **not** convert inputs or outputs
44
+ between frameworks and do not accept a `gpu_id` argument. A host runtime must
45
+ call `convert_memory` at the boundary it plans.
46
+
47
+ ## Stack utilities
48
+
49
+ ```python
50
+ import numpy as np
51
+
52
+ from arraybridge import stack_slices, unstack_slices
53
+
54
+ slices = [np.zeros((8, 8)), np.ones((8, 8))]
55
+ stack = stack_slices(slices, memory_type="numpy", gpu_id=0)
56
+ restored = unstack_slices(stack, memory_type="numpy", gpu_id=0)
57
+ ```
58
+
59
+ `stack_slices` requires non-empty 2D inputs. `unstack_slices` requires a 3D
60
+ array. Both validate shape and use explicit target memory/device declarations.
61
+
62
+ ## Installation
63
+
64
+ ```bash
65
+ pip install arraybridge
66
+ pip install "arraybridge[torch]"
67
+ pip install "arraybridge[cupy]"
68
+ ```
69
+
70
+ Documentation: <https://arraybridge.readthedocs.io>
@@ -6,17 +6,17 @@ This document contains the manual steps needed to complete the badge and documen
6
6
 
7
7
  To display the coverage reports hosted on GitHub Pages:
8
8
 
9
- 1. Go to: https://github.com/trissim/arraybridge/settings/pages
9
+ 1. Go to: https://github.com/OpenHCSDev/arraybridge/settings/pages
10
10
  2. Under "Build and deployment" > "Source", select **"GitHub Actions"**
11
11
  3. Save the changes
12
12
 
13
- Once enabled, the coverage-pages.yml workflow will deploy coverage reports to https://trissim.github.io/arraybridge/coverage/
13
+ Once enabled, the coverage-pages.yml workflow will deploy coverage reports to https://openhcsdev.github.io/arraybridge/coverage/
14
14
 
15
15
  ## 2. Update Repository Description
16
16
 
17
17
  To add the ReadTheDocs link to the repository description:
18
18
 
19
- 1. Go to: https://github.com/trissim/arraybridge
19
+ 1. Go to: https://github.com/OpenHCSDev/arraybridge
20
20
  2. Click the gear icon (⚙️) next to "About" on the right side
21
21
  3. In the "Website" field, enter: `https://arraybridge.readthedocs.io`
22
22
  4. Optionally add topics/tags to improve discoverability
@@ -55,7 +55,7 @@ After merging this PR to main:
55
55
  The following badges have been added to README.md:
56
56
 
57
57
  - **ReadTheDocs**: `[![Documentation Status](https://readthedocs.org/projects/arraybridge/badge/?version=latest)](https://arraybridge.readthedocs.io/en/latest/?badge=latest)`
58
- - **Coverage**: `[![Coverage](https://raw.githubusercontent.com/trissim/arraybridge/main/.github/badges/coverage.svg)](https://trissim.github.io/arraybridge/coverage/)`
58
+ - **Coverage**: `[![Coverage](https://raw.githubusercontent.com/OpenHCSDev/arraybridge/main/.github/badges/coverage.svg)](https://openhcsdev.github.io/arraybridge/coverage/)`
59
59
 
60
60
  ## Notes
61
61
 
@@ -190,4 +190,3 @@ If issues arise, revert to previous CI by:
190
190
  ## Questions?
191
191
 
192
192
  See `TESTING.md` for detailed testing documentation.
193
-
@@ -0,0 +1,5 @@
1
+ # Archived ArrayBridge notes
2
+
3
+ These CI incident reports, migration summaries, conflict guides, and dated
4
+ coverage plans are superseded history. Use `README.md`, `CONTRIBUTING.md`,
5
+ `TESTING.md`, and the active Sphinx site under `docs/source/`.
@@ -0,0 +1,7 @@
1
+ # CI/CD documentation
2
+
3
+ The maintained CI/CD documentation is
4
+ [`source/ci-cd.rst`](source/ci-cd.rst). It deliberately links to the current
5
+ [GitHub Actions workflows](https://github.com/OpenHCSDev/arraybridge/actions)
6
+ instead of duplicating a version matrix or release procedure that can drift
7
+ from the workflow files.
@@ -0,0 +1,15 @@
1
+ # ArrayBridge documentation source
2
+
3
+ The active Sphinx source is this directory.
4
+
5
+ From the repository root:
6
+
7
+ ```bash
8
+ python -m pip install -e ".[docs]"
9
+ python -m sphinx -E -W --keep-going -b html docs/source docs/source/_build/html
10
+ ```
11
+
12
+ Narrative pages document public behavior and ownership. `api_reference.rst`
13
+ tracks the root export surface. Keep code examples valid under
14
+ `scripts/validate_docs.py` in the OpenHCS superproject and verify signatures
15
+ against `src/arraybridge/` when public APIs change.
@@ -0,0 +1,20 @@
1
+ Advanced extension topics
2
+ =========================
3
+
4
+ Framework behavior is centralized in the registered conversion and framework
5
+ strategy families. Add a new framework by extending those owning declarations:
6
+
7
+ 1. add the ``MemoryType`` member;
8
+ 2. provide framework configuration and conversion strategies;
9
+ 3. define stack/allocation/device behavior where it differs;
10
+ 4. add cleanup and OOM behavior only when the framework supports them;
11
+ 5. exercise detection and every supported conversion pair.
12
+
13
+ Do not add a parallel framework-name table in a consumer. Generic consumers use
14
+ ``MemoryType``, the converter registry, and framework configuration owned by
15
+ ArrayBridge.
16
+
17
+ Conversion caching and batching belong to the caller because value lifetime and
18
+ semantic identity are application concerns. ArrayBridge functions remain
19
+ stateless at the conversion boundary except for declared thread-local GPU
20
+ context.
@@ -0,0 +1,38 @@
1
+ API reference
2
+ =============
3
+
4
+ Public imports
5
+ --------------
6
+
7
+ ``MemoryType``, ``CPU_MEMORY_TYPES``, ``GPU_MEMORY_TYPES``, ``SUPPORTED_MEMORY_TYPES``
8
+ Nominal framework identities.
9
+
10
+ ``detect_memory_type`` and ``convert_memory``
11
+ Detection and explicit conversion.
12
+
13
+ ``memory_types``, ``numpy``, ``cupy``, ``torch``, ``tensorflow``, ``jax``, ``pyclesperanto``
14
+ Callable memory declarations and wrappers.
15
+
16
+ ``DtypeConversion``
17
+ Output dtype policy values.
18
+
19
+ ``stack_slices``, ``unstack_slices``, ``process_slices``
20
+ Validated plane/stack operations.
21
+
22
+ ``cleanup_all_gpu_frameworks``
23
+ Installed-framework cache cleanup.
24
+
25
+ ``MemoryConversionError``
26
+ Conversion failure boundary.
27
+
28
+ The canonical export list is ``arraybridge.__all__``. Names beginning with an
29
+ underscore are implementation surfaces even when temporarily re-exported for a
30
+ host migration.
31
+
32
+ Documented public surface
33
+ -------------------------
34
+
35
+ .. automodule:: arraybridge
36
+ :members:
37
+ :exclude-members: _FRAMEWORK_CONFIG, _FRAMEWORK_OPS, _ensure_module, _execute_with_oom_recovery, _get_device_id, _supports_dlpack
38
+ :member-order: bysource
@@ -0,0 +1,25 @@
1
+ Continuous integration
2
+ ======================
3
+
4
+ The repository workflows are authoritative. The main test matrix currently
5
+ covers Python 3.10 through 3.13 on Linux, Windows, and macOS. Separate jobs
6
+ exercise optional GPU paths and code quality.
7
+
8
+ Before opening a change, run:
9
+
10
+ .. code-block:: bash
11
+
12
+ python -m pytest
13
+ ruff check src tests
14
+ black --check src tests
15
+ mypy src --ignore-missing-imports
16
+
17
+ Documentation changes should also build with warnings as errors:
18
+
19
+ .. code-block:: bash
20
+
21
+ python -m sphinx -E -W --keep-going -b html docs/source docs/source/_build/html
22
+
23
+ See the current `GitHub Actions workflows
24
+ <https://github.com/OpenHCSDev/arraybridge/actions>`_ instead of copying a
25
+ workflow matrix into downstream documentation.
@@ -5,7 +5,16 @@
5
5
 
6
6
  import os
7
7
  import sys
8
- sys.path.insert(0, os.path.abspath('../../src'))
8
+ from pathlib import Path
9
+
10
+ PACKAGE_ROOT = Path(__file__).resolve().parents[2]
11
+ EXTERNAL_ROOT = PACKAGE_ROOT.parent
12
+
13
+ # Prefer the sibling owner source when ArrayBridge is documented from the
14
+ # OpenHCS checkout; an installed metaclass-registry remains the standalone
15
+ # fallback when that sibling is absent.
16
+ sys.path.insert(0, str(EXTERNAL_ROOT / "metaclass-registry" / "src"))
17
+ sys.path.insert(0, str(PACKAGE_ROOT / "src"))
9
18
 
10
19
  # -- Project information -----------------------------------------------------
11
20
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
@@ -13,7 +22,7 @@ sys.path.insert(0, os.path.abspath('../../src'))
13
22
  project = 'arraybridge'
14
23
  copyright = '2025, Tristan Simas'
15
24
  author = 'Tristan Simas'
16
- release = '0.1.0'
25
+ release = '0.2.11'
17
26
 
18
27
  # -- General configuration ---------------------------------------------------
19
28
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
@@ -29,13 +38,13 @@ extensions = [
29
38
  ]
30
39
 
31
40
  templates_path = ['_templates']
32
- exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
41
+ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'api/**']
33
42
 
34
43
  # -- Options for HTML output -------------------------------------------------
35
44
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
36
45
 
37
46
  html_theme = 'sphinx_rtd_theme'
38
- html_static_path = ['_static']
47
+ html_static_path = []
39
48
 
40
49
  # -- Extension configuration -------------------------------------------------
41
50
 
@@ -114,7 +123,6 @@ html_theme_options = {
114
123
  'sticky_navigation': True,
115
124
  'includehidden': True,
116
125
  'titles_only': False,
117
- 'display_version': True,
118
126
  'prev_next_buttons_location': 'both',
119
127
  'style_external_links': False,
120
128
  }
@@ -0,0 +1,27 @@
1
+ Contributing
2
+ ============
3
+
4
+ Install the editable development environment and run the same core checks used
5
+ by the repository:
6
+
7
+ .. code-block:: bash
8
+
9
+ python -m pip install -e ".[dev,docs]"
10
+ ruff check src tests
11
+ black --check src tests
12
+ mypy src --ignore-missing-imports
13
+ python -m pytest
14
+ python -m sphinx -E -W --keep-going -b html docs/source docs/source/_build/html
15
+
16
+ Framework extensions
17
+ --------------------
18
+
19
+ A framework extension must update the nominal ``MemoryType`` declaration and
20
+ the owning conversion/framework strategies. Add detection tests, conversion
21
+ pair tests, stack tests, and optional-dependency behavior. Consumers should not
22
+ maintain a second framework-name registry.
23
+
24
+ See :doc:`advanced_topics` for the ownership model and the repository's
25
+ `contribution guide
26
+ <https://github.com/OpenHCSDev/arraybridge/blob/main/CONTRIBUTING.md>`_ for the
27
+ review workflow.
@@ -0,0 +1,36 @@
1
+ Conversion system
2
+ =================
3
+
4
+ ``convert_memory(data, source_type, target_type, gpu_id)`` selects the converter
5
+ registered for ``source_type`` and invokes its target method.
6
+
7
+ .. code-block:: python
8
+
9
+ import numpy as np
10
+
11
+ from arraybridge import convert_memory
12
+
13
+ value = np.arange(4)
14
+ result = convert_memory(value, "numpy", "numpy", 0)
15
+
16
+ Call ``detect_memory_type`` when the source type is not already known. Passing a
17
+ wrong source declaration is a caller error; conversion planning should keep the
18
+ declared type aligned with the actual value.
19
+
20
+ Device semantics
21
+ ----------------
22
+
23
+ ``gpu_id`` is required. GPU converters use it for allocation or device
24
+ selection. CPU conversion accepts the same argument for a uniform API. Moving a
25
+ value between two devices is expressed as conversion with the target device id.
26
+
27
+ Converters prefer framework-native or DLPack paths when the registered strategy
28
+ supports them and otherwise use the strategy's explicit fallback. No zero-copy
29
+ guarantee applies to every pair.
30
+
31
+ Failures
32
+ --------
33
+
34
+ Invalid framework names raise ``ValueError``. Conversion failures raise
35
+ ``MemoryConversionError`` with source/target context. Optional frameworks are
36
+ loaded only when their converter is used.
@@ -0,0 +1,40 @@
1
+ Memory declaration decorators
2
+ =============================
3
+
4
+ ``memory_types`` and the six framework helpers declare callable memory
5
+ contracts.
6
+
7
+ .. code-block:: python
8
+
9
+ from arraybridge import memory_types, numpy
10
+
11
+ @memory_types(input_type="numpy", output_type="numpy")
12
+ def identity(image):
13
+ return image
14
+
15
+ @numpy(oom_recovery=False)
16
+ def offset(image, value=1):
17
+ return image + value
18
+
19
+ Framework helpers accept ``input_type``, ``output_type``, ``oom_recovery``, and
20
+ ``contract``. They may be used as ``@numpy`` or ``@numpy()``.
21
+
22
+ Direct-call behavior
23
+ --------------------
24
+
25
+ Decorators do not convert the input or output between frameworks. They attach
26
+ metadata, add keyword-only ``slice_by_slice`` and ``dtype_config`` runtime
27
+ parameters, apply the selected dtype policy, and wrap supported GPU frameworks
28
+ with thread-local stream/OOM handling.
29
+
30
+ The decorator does not accept ``gpu_id`` or ``clear_cuda_cache``. Device
31
+ selection belongs to explicit conversion or the host runtime. A non-callable
32
+ ``contract`` is stored as declarative metadata; a callable contract validates
33
+ the returned value.
34
+
35
+ Dtype policy
36
+ ------------
37
+
38
+ Direct calls default to preserving the input dtype. Hosts can pass an object
39
+ implementing ``DtypeConversionConfig`` to select native or explicit output dtype
40
+ behavior.
@@ -0,0 +1,16 @@
1
+ Basic conversion
2
+ ================
3
+
4
+ .. code-block:: python
5
+
6
+ import numpy as np
7
+
8
+ from arraybridge import convert_memory, detect_memory_type
9
+
10
+ source = np.arange(9).reshape(3, 3)
11
+ source_type = detect_memory_type(source)
12
+ result = convert_memory(source, source_type, "numpy", 0)
13
+
14
+ For an optional target such as ``torch`` or ``cupy``, install that framework and
15
+ replace the target string. The returned value is allocated according to the
16
+ registered converter and requested device.
@@ -0,0 +1,18 @@
1
+ Decorator declarations
2
+ ======================
3
+
4
+ .. code-block:: python
5
+
6
+ import numpy as np
7
+
8
+ from arraybridge import numpy
9
+
10
+ @numpy
11
+ def threshold(image, *, cutoff=0.5):
12
+ return image > cutoff
13
+
14
+ value = threshold(np.array([0.25, 0.75]))
15
+ assert threshold.input_memory_type == "numpy"
16
+
17
+ The caller supplies the NumPy value. A compiler or orchestration layer may use
18
+ the metadata to plan conversion before calling ``threshold``.
@@ -0,0 +1,18 @@
1
+ Multi-framework boundary
2
+ ========================
3
+
4
+ Keep conversion visible at the point that owns the boundary:
5
+
6
+ .. code-block:: python
7
+
8
+ from arraybridge import convert_memory, detect_memory_type
9
+
10
+ def as_framework(value, target, gpu_id):
11
+ source = detect_memory_type(value)
12
+ if source == target:
13
+ return value
14
+ return convert_memory(value, source, target, gpu_id)
15
+
16
+ For a sequence of framework-specific functions, a host compiler should read
17
+ their declared input/output memory types and create one conversion plan. The
18
+ functions themselves should not each guess the incoming framework.