Coverage for openhcs/core/memory/converters.py: 5.6%
82 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 05:57 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 05:57 +0000
1"""
2Memory conversion functions for OpenHCS.
4This module provides functions for converting between different memory types,
5enforcing Clause 65 (Fail Loudly), Clause 88 (No Inferred Capabilities),
6and Clause 251 (Declarative Memory Conversion).
7"""
9from typing import Any
11from openhcs.constants.constants import MemoryType
13from .conversion_functions import (_cupy_to_jax, _cupy_to_numpy,
14 _cupy_to_pyclesperanto, _cupy_to_tensorflow, _cupy_to_torch,
15 _jax_to_cupy, _jax_to_jax, _jax_to_numpy, _jax_to_pyclesperanto,
16 _jax_to_tensorflow, _jax_to_torch,
17 _numpy_to_cupy, _numpy_to_jax,
18 _numpy_to_pyclesperanto, _numpy_to_tensorflow, _numpy_to_torch,
19 _pyclesperanto_to_cupy, _pyclesperanto_to_jax, _pyclesperanto_to_numpy,
20 _pyclesperanto_to_pyclesperanto, _pyclesperanto_to_tensorflow, _pyclesperanto_to_torch,
21 _tensorflow_to_cupy, _tensorflow_to_jax, _tensorflow_to_pyclesperanto,
22 _tensorflow_to_numpy, _tensorflow_to_torch,
23 _torch_to_cupy, _torch_to_jax, _torch_to_pyclesperanto,
24 _torch_to_numpy, _torch_to_tensorflow)
27def validate_memory_type(memory_type: str) -> None:
28 """
29 Validate that a memory type is supported.
31 Args:
32 memory_type: The memory type to validate
34 Raises:
35 ValueError: If the memory type is not supported
36 """
37 if memory_type not in [m.value for m in MemoryType]:
38 raise ValueError(
39 f"Unsupported memory type: {memory_type}. "
40 f"Supported types are: {', '.join([m.value for m in MemoryType])}"
41 )
44def validate_data_compatibility(data: Any, memory_type: str) -> None:
45 """
46 Validate that data is compatible with a memory type.
48 Args:
49 data: The data to validate
50 memory_type: The memory type to validate against
52 Raises:
53 ValueError: If the data is not compatible with the memory type
54 """
55 # This is a placeholder for future validation logic
56 # Currently, we don't have a way to validate data compatibility
57 # without importing the memory type modules
58 pass
61def convert_memory(
62 data: Any,
63 source_type: str,
64 target_type: str,
65 gpu_id: int,
66 allow_cpu_roundtrip: bool = False,
67) -> Any:
68 """
69 Convert data between memory types.
71 Args:
72 data: The data to convert
73 source_type: The source memory type
74 target_type: The target memory type
75 gpu_id: The target GPU device ID (required)
76 allow_cpu_roundtrip: Whether to allow fallback to CPU roundtrip
78 Returns:
79 The converted data
81 Raises:
82 ValueError: If source_type or target_type is not supported
83 MemoryConversionError: If conversion fails
84 """
85 # If source and target types are the same, return the data as is
86 if source_type == target_type: 86 ↛ 90line 86 didn't jump to line 90 because the condition on line 86 was always true
87 return data
89 # NumPy to X conversions
90 if source_type == MemoryType.NUMPY.value:
91 if target_type == MemoryType.CUPY.value:
92 return _numpy_to_cupy(data, gpu_id)
93 elif target_type == MemoryType.TORCH.value:
94 return _numpy_to_torch(data, gpu_id)
95 elif target_type == MemoryType.TENSORFLOW.value:
96 return _numpy_to_tensorflow(data, gpu_id)
97 elif target_type == MemoryType.JAX.value:
98 return _numpy_to_jax(data, gpu_id)
99 elif target_type == MemoryType.PYCLESPERANTO.value:
100 return _numpy_to_pyclesperanto(data, gpu_id)
102 # CuPy to X conversions
103 elif source_type == MemoryType.CUPY.value:
104 if target_type == MemoryType.NUMPY.value:
105 return _cupy_to_numpy(data)
106 elif target_type == MemoryType.TORCH.value:
107 return _cupy_to_torch(data, allow_cpu_roundtrip, gpu_id)
108 elif target_type == MemoryType.TENSORFLOW.value:
109 return _cupy_to_tensorflow(data, allow_cpu_roundtrip, gpu_id)
110 elif target_type == MemoryType.JAX.value:
111 return _cupy_to_jax(data, allow_cpu_roundtrip, gpu_id)
112 elif target_type == MemoryType.PYCLESPERANTO.value:
113 return _cupy_to_pyclesperanto(data, allow_cpu_roundtrip, gpu_id)
115 # PyTorch to X conversions
116 elif source_type == MemoryType.TORCH.value:
117 if target_type == MemoryType.NUMPY.value:
118 return _torch_to_numpy(data)
119 elif target_type == MemoryType.CUPY.value:
120 return _torch_to_cupy(data, allow_cpu_roundtrip, gpu_id)
121 elif target_type == MemoryType.TENSORFLOW.value:
122 return _torch_to_tensorflow(data, allow_cpu_roundtrip, gpu_id)
123 elif target_type == MemoryType.JAX.value:
124 return _torch_to_jax(data, allow_cpu_roundtrip, gpu_id)
125 elif target_type == MemoryType.PYCLESPERANTO.value:
126 return _torch_to_pyclesperanto(data, allow_cpu_roundtrip, gpu_id)
128 # TensorFlow to X conversions
129 elif source_type == MemoryType.TENSORFLOW.value:
130 if target_type == MemoryType.NUMPY.value:
131 return _tensorflow_to_numpy(data)
132 elif target_type == MemoryType.CUPY.value:
133 return _tensorflow_to_cupy(data, allow_cpu_roundtrip, gpu_id)
134 elif target_type == MemoryType.TORCH.value:
135 return _tensorflow_to_torch(data, allow_cpu_roundtrip, gpu_id)
136 elif target_type == MemoryType.JAX.value:
137 return _tensorflow_to_jax(data, allow_cpu_roundtrip, gpu_id)
138 elif target_type == MemoryType.PYCLESPERANTO.value:
139 return _tensorflow_to_pyclesperanto(data, allow_cpu_roundtrip, gpu_id)
141 # JAX to X conversions
142 elif source_type == MemoryType.JAX.value:
143 if target_type == MemoryType.NUMPY.value:
144 return _jax_to_numpy(data)
145 elif target_type == MemoryType.CUPY.value:
146 return _jax_to_cupy(data, allow_cpu_roundtrip, gpu_id)
147 elif target_type == MemoryType.TORCH.value:
148 return _jax_to_torch(data, allow_cpu_roundtrip, gpu_id)
149 elif target_type == MemoryType.TENSORFLOW.value:
150 return _jax_to_tensorflow(data, allow_cpu_roundtrip, gpu_id)
151 elif target_type == MemoryType.JAX.value:
152 return _jax_to_jax(data, gpu_id)
153 elif target_type == MemoryType.PYCLESPERANTO.value:
154 return _jax_to_pyclesperanto(data, allow_cpu_roundtrip, gpu_id)
156 # pyclesperanto to X conversions
157 elif source_type == MemoryType.PYCLESPERANTO.value:
158 if target_type == MemoryType.NUMPY.value:
159 return _pyclesperanto_to_numpy(data)
160 elif target_type == MemoryType.CUPY.value:
161 return _pyclesperanto_to_cupy(data, allow_cpu_roundtrip, gpu_id)
162 elif target_type == MemoryType.TORCH.value:
163 return _pyclesperanto_to_torch(data, allow_cpu_roundtrip, gpu_id)
164 elif target_type == MemoryType.TENSORFLOW.value:
165 return _pyclesperanto_to_tensorflow(data, allow_cpu_roundtrip, gpu_id)
166 elif target_type == MemoryType.JAX.value:
167 return _pyclesperanto_to_jax(data, allow_cpu_roundtrip, gpu_id)
168 elif target_type == MemoryType.PYCLESPERANTO.value:
169 return _pyclesperanto_to_pyclesperanto(data)
171 # If we get here, the conversion is not supported
172 raise ValueError(
173 f"Unsupported memory conversion: {source_type} -> {target_type}"
174 )