XuPy 1.1.0__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.
- xupy-1.1.0/LICENSE +21 -0
- xupy-1.1.0/PKG-INFO +324 -0
- xupy-1.1.0/README.md +308 -0
- xupy-1.1.0/XuPy.egg-info/PKG-INFO +324 -0
- xupy-1.1.0/XuPy.egg-info/SOURCES.txt +17 -0
- xupy-1.1.0/XuPy.egg-info/dependency_links.txt +1 -0
- xupy-1.1.0/XuPy.egg-info/requires.txt +1 -0
- xupy-1.1.0/XuPy.egg-info/top_level.txt +1 -0
- xupy-1.1.0/pyproject.toml +24 -0
- xupy-1.1.0/setup.cfg +4 -0
- xupy-1.1.0/setup.py +33 -0
- xupy-1.1.0/test/test_xupy_focused.py +461 -0
- xupy-1.1.0/xupy/__init__.py +6 -0
- xupy-1.1.0/xupy/__version__.py +1 -0
- xupy-1.1.0/xupy/_core.py +1676 -0
- xupy-1.1.0/xupy/_cupy_install/__check_availability__.py +72 -0
- xupy-1.1.0/xupy/_cupy_install/__init__.py +0 -0
- xupy-1.1.0/xupy/_cupy_install/__install_cupy__.py +92 -0
- xupy-1.1.0/xupy/_typings.py +35 -0
xupy-1.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Pietro Ferraiuolo (pietro.ferraiuolo@inaf.it)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
xupy-1.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: XuPy
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Masked Arrays made simple for CuPy
|
|
5
|
+
Author: Pietro Ferraiuolo
|
|
6
|
+
Author-email: Pietro Ferraiuolo <pietro.ferraiuolo@inaf.it>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/pietroferraiuolo/XuPy
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: numpy
|
|
13
|
+
Dynamic: author
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
Dynamic: requires-python
|
|
16
|
+
|
|
17
|
+
# XuPy
|
|
18
|
+
|
|
19
|
+
XuPy is a comprehensive Python package that provides GPU-accelerated masked arrays and NumPy-compatible functionality using CuPy. It automatically handles GPU/CPU fallback and offers an intuitive interface for scientific computing with masked data.
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- **GPU Acceleration**: Automatic GPU detection with CuPy fallback to NumPy
|
|
24
|
+
- **Masked Arrays**: Full support for masked arrays with GPU acceleration
|
|
25
|
+
- **Statistical Functions**: Comprehensive statistical operations (mean, std, var, min, max, etc.)
|
|
26
|
+
- **Array Manipulation**: Reshape, transpose, squeeze, expand_dims, and more
|
|
27
|
+
- **Mathematical Functions**: Trigonometric, exponential, logarithmic, and rounding functions
|
|
28
|
+
- **Random Generation**: Various random number generators (normal, uniform, etc.)
|
|
29
|
+
- **Universal Functions**: Support for applying any CuPy/NumPy ufunc with mask preservation
|
|
30
|
+
- **Performance**: Optimized for large-scale data processing on GPU
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install .
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import xupy as xp
|
|
42
|
+
|
|
43
|
+
# Create arrays with automatic GPU detection
|
|
44
|
+
a = xp.random.normal(0, 1, (1000, 1000))
|
|
45
|
+
b = xp.random.normal(0, 1, (1000, 1000))
|
|
46
|
+
|
|
47
|
+
# Create masks
|
|
48
|
+
mask = xp.random.random((1000, 1000)) > 0.1
|
|
49
|
+
|
|
50
|
+
# Create masked arrays
|
|
51
|
+
am = xp.masked_array(a, mask)
|
|
52
|
+
bm = xp.masked_array(b, mask)
|
|
53
|
+
|
|
54
|
+
# Perform operations (masks are automatically handled)
|
|
55
|
+
result = am + bm
|
|
56
|
+
mean_val = am.mean()
|
|
57
|
+
std_val = am.std()
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Comprehensive Examples
|
|
61
|
+
|
|
62
|
+
### Array Creation
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import xupy as xp
|
|
66
|
+
|
|
67
|
+
# Basic array creation
|
|
68
|
+
zeros = xp.zeros((3, 3))
|
|
69
|
+
ones = xp.ones((3, 3))
|
|
70
|
+
eye = xp.eye(3)
|
|
71
|
+
identity = xp.identity(3)
|
|
72
|
+
|
|
73
|
+
# Sequences
|
|
74
|
+
linspace = xp.linspace(0, 10, 100)
|
|
75
|
+
logspace = xp.logspace(0, 3, 100)
|
|
76
|
+
arange = xp.arange(0, 10, 0.5)
|
|
77
|
+
|
|
78
|
+
# Random arrays
|
|
79
|
+
random = xp.random((100, 100))
|
|
80
|
+
normal = xp.normal(0, 1, (100, 100))
|
|
81
|
+
uniform = xp.uniform(-1, 1, (100, 100))
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Masked Array Operations
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
import xupy as xp
|
|
88
|
+
from skimage.draw import disk
|
|
89
|
+
|
|
90
|
+
# Create data and mask
|
|
91
|
+
data = xp.random.normal(0, 1, (500, 500))
|
|
92
|
+
mask = xp.ones((500, 500), dtype=bool)
|
|
93
|
+
|
|
94
|
+
# Create circular mask
|
|
95
|
+
circle_coords = disk((250, 250), 200)
|
|
96
|
+
mask[circle_coords] = False
|
|
97
|
+
|
|
98
|
+
# Create masked array
|
|
99
|
+
masked_data = xp.masked_array(data, mask)
|
|
100
|
+
|
|
101
|
+
# Statistical operations
|
|
102
|
+
global_mean = masked_data.mean()
|
|
103
|
+
global_std = masked_data.std()
|
|
104
|
+
global_var = masked_data.var()
|
|
105
|
+
global_min = masked_data.min()
|
|
106
|
+
global_max = masked_data.max()
|
|
107
|
+
|
|
108
|
+
# Axis-wise operations
|
|
109
|
+
row_means = masked_data.mean(axis=0)
|
|
110
|
+
col_sums = masked_data.sum(axis=1)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Mathematical Functions
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
import xupy as xp
|
|
117
|
+
|
|
118
|
+
# Create masked array
|
|
119
|
+
data = xp.random.normal(0, 1, (100, 100))
|
|
120
|
+
mask = xp.random.random((100, 100)) > 0.8
|
|
121
|
+
ma = xp.masked_array(data, mask)
|
|
122
|
+
|
|
123
|
+
# Trigonometric functions
|
|
124
|
+
sin_result = ma.sin()
|
|
125
|
+
cos_result = ma.cos()
|
|
126
|
+
tan_result = ma.tan()
|
|
127
|
+
|
|
128
|
+
# Inverse trigonometric functions
|
|
129
|
+
arcsin_result = ma.arcsin()
|
|
130
|
+
arccos_result = ma.arccos()
|
|
131
|
+
arctan_result = ma.arctan()
|
|
132
|
+
|
|
133
|
+
# Hyperbolic functions
|
|
134
|
+
sinh_result = ma.sinh()
|
|
135
|
+
cosh_result = ma.cosh()
|
|
136
|
+
tanh_result = ma.tanh()
|
|
137
|
+
|
|
138
|
+
# Exponential and logarithmic functions
|
|
139
|
+
exp_result = ma.exp()
|
|
140
|
+
log_result = ma.log()
|
|
141
|
+
log10_result = ma.log10()
|
|
142
|
+
|
|
143
|
+
# Rounding functions
|
|
144
|
+
floor_result = ma.floor()
|
|
145
|
+
ceil_result = ma.ceil()
|
|
146
|
+
round_result = ma.round(decimals=2)
|
|
147
|
+
|
|
148
|
+
# Square root
|
|
149
|
+
sqrt_result = ma.sqrt()
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Array Manipulation
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
import xupy as xp
|
|
156
|
+
|
|
157
|
+
# Create masked array
|
|
158
|
+
data = xp.random.normal(0, 1, (4, 4))
|
|
159
|
+
mask = xp.random.random((4, 4)) > 0.5
|
|
160
|
+
ma = xp.masked_array(data, mask)
|
|
161
|
+
|
|
162
|
+
# Reshape
|
|
163
|
+
reshaped = ma.reshape(2, 8)
|
|
164
|
+
flattened = ma.flatten()
|
|
165
|
+
raveled = ma.ravel()
|
|
166
|
+
|
|
167
|
+
# Transpose and axes
|
|
168
|
+
transposed = ma.T
|
|
169
|
+
swapped = ma.swapaxes(0, 1)
|
|
170
|
+
|
|
171
|
+
# Expand and squeeze dimensions
|
|
172
|
+
expanded = ma.expand_dims(axis=1)
|
|
173
|
+
squeezed = expanded.squeeze()
|
|
174
|
+
|
|
175
|
+
# Repeat and tile
|
|
176
|
+
repeated = ma.repeat(2, axis=0)
|
|
177
|
+
tiled = ma.tile((2, 2))
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Advanced Operations
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
import xupy as xp
|
|
184
|
+
|
|
185
|
+
# Create complex masked array
|
|
186
|
+
data = xp.random.normal(0, 1, (100, 100, 3))
|
|
187
|
+
mask = xp.random.random((100, 100, 3)) > 0.9
|
|
188
|
+
ma = xp.masked_array(data, mask)
|
|
189
|
+
|
|
190
|
+
# Multi-axis operations
|
|
191
|
+
result = ma.mean(axis=(0, 1))
|
|
192
|
+
variance = ma.var(axis=1, ddof=1)
|
|
193
|
+
|
|
194
|
+
# Boolean operations
|
|
195
|
+
any_true = ma.any(axis=0)
|
|
196
|
+
all_true = ma.all(axis=1)
|
|
197
|
+
|
|
198
|
+
# Mask information
|
|
199
|
+
masked_count = ma.count_masked()
|
|
200
|
+
unmasked_count = ma.count_unmasked()
|
|
201
|
+
is_masked = ma.is_masked()
|
|
202
|
+
|
|
203
|
+
# Compressed data
|
|
204
|
+
valid_data = ma.compressed()
|
|
205
|
+
|
|
206
|
+
# Fill masked values
|
|
207
|
+
ma.fill_value(0.0)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Performance Benefits
|
|
211
|
+
|
|
212
|
+
XuPy automatically detects GPU availability and provides significant speedup for large arrays:
|
|
213
|
+
|
|
214
|
+
- **Small arrays (< 1000 elements)**: CPU (NumPy) may be faster due to GPU overhead
|
|
215
|
+
- **Medium arrays (1000-10000 elements)**: GPU provides 2-5x speedup
|
|
216
|
+
- **Large arrays (> 10000 elements)**: GPU provides 5-20x speedup depending on operation complexity
|
|
217
|
+
|
|
218
|
+
## GPU Requirements
|
|
219
|
+
|
|
220
|
+
- **CUDA-compatible GPU** with compute capability 3.0+
|
|
221
|
+
- **CuPy** package installed (`pip install cupy-cuda12x` for CUDA 12.x)
|
|
222
|
+
- **Automatic fallback** to NumPy if GPU is unavailable
|
|
223
|
+
|
|
224
|
+
## API Compatibility
|
|
225
|
+
|
|
226
|
+
XuPy maintains high compatibility with NumPy's masked array interface while leveraging CuPy's optimized operations:
|
|
227
|
+
|
|
228
|
+
- All standard properties (`shape`, `dtype`, `size`, `ndim`, `T`)
|
|
229
|
+
- Comprehensive arithmetic operations with mask propagation
|
|
230
|
+
- **Memory-optimized statistical methods** (`mean`, `std`, `var`, `min`, `max`) using CuPy's native operations
|
|
231
|
+
- Array manipulation methods (`reshape`, `transpose`, `squeeze`)
|
|
232
|
+
- Universal function support through `apply_ufunc`
|
|
233
|
+
- Conversion to NumPy masked arrays via `asmarray()`
|
|
234
|
+
- **GPU memory management** through `MemoryContext`
|
|
235
|
+
|
|
236
|
+
## Key Improvements
|
|
237
|
+
|
|
238
|
+
- **Eliminated redundant functions** - Uses CuPy/NumPy directly for basic operations
|
|
239
|
+
- **Memory-efficient statistical operations** - Leverages CuPy's optimized reduction operations
|
|
240
|
+
- **Proper mask propagation** - Maintains mask integrity across all operations
|
|
241
|
+
- **GPU memory management** - Context manager for efficient memory usage
|
|
242
|
+
|
|
243
|
+
## GPU Memory Management
|
|
244
|
+
|
|
245
|
+
XuPy includes an advanced `MemoryContext` class for efficient GPU memory management:
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
import xupy as xp
|
|
249
|
+
|
|
250
|
+
# Basic usage with automatic cleanup
|
|
251
|
+
with xp.MemoryContext() as ctx:
|
|
252
|
+
# GPU operations
|
|
253
|
+
data = xp.random.normal(0, 1, (10000, 10000))
|
|
254
|
+
result = data.mean()
|
|
255
|
+
# Memory automatically cleaned up on exit
|
|
256
|
+
|
|
257
|
+
# Advanced features
|
|
258
|
+
with xp.MemoryContext(memory_threshold=0.8, auto_cleanup=True) as ctx:
|
|
259
|
+
# Monitor memory usage
|
|
260
|
+
mem_info = ctx.get_memory_info()
|
|
261
|
+
print(f"GPU Memory: {mem_info['used'] / (1024**3):.2f} GB")
|
|
262
|
+
|
|
263
|
+
# Aggressive cleanup when needed
|
|
264
|
+
if ctx.check_memory_pressure():
|
|
265
|
+
ctx.aggressive_cleanup()
|
|
266
|
+
|
|
267
|
+
# Emergency cleanup for critical situations
|
|
268
|
+
ctx.emergency_cleanup()
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### MemoryContext Features
|
|
272
|
+
|
|
273
|
+
- **Automatic Cleanup**: Memory freed automatically when exiting context
|
|
274
|
+
- **Memory Monitoring**: Real-time tracking of GPU memory usage
|
|
275
|
+
- **Pressure Detection**: Automatic cleanup when memory usage is high
|
|
276
|
+
- **Aggressive Cleanup**: Force garbage collection and cache clearing
|
|
277
|
+
- **Emergency Cleanup**: Nuclear option for out-of-memory situations
|
|
278
|
+
- **Object Tracking**: Track GPU objects for proper cleanup
|
|
279
|
+
- **Memory History**: Keep history of memory usage over time
|
|
280
|
+
|
|
281
|
+
Run the memory management demo:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
python memory_demo.py
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Examples
|
|
288
|
+
|
|
289
|
+
Run the comprehensive examples script to see XuPy in action:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
python examples.py
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
This script demonstrates:
|
|
296
|
+
|
|
297
|
+
- GPU detection and information
|
|
298
|
+
- Basic masked array operations
|
|
299
|
+
- GPU-accelerated computations
|
|
300
|
+
- Mathematical functions
|
|
301
|
+
- Memory management
|
|
302
|
+
- Scientific computing use cases
|
|
303
|
+
- Performance comparisons
|
|
304
|
+
|
|
305
|
+
## Documentation
|
|
306
|
+
|
|
307
|
+
For detailed documentation, including comprehensive API reference and advanced usage examples, see [docs.md](docs.md).
|
|
308
|
+
|
|
309
|
+
## License
|
|
310
|
+
|
|
311
|
+
See [LICENSE](LICENSE).
|
|
312
|
+
|
|
313
|
+
## Citation
|
|
314
|
+
|
|
315
|
+
If you use XuPy in your research, please cite:
|
|
316
|
+
|
|
317
|
+
```bibtex
|
|
318
|
+
@software{xupy2025,
|
|
319
|
+
title={XuPy: GPU-Accelerated Masked Arrays for Scientific Computing},
|
|
320
|
+
author={Ferraiuolo, Pietro},
|
|
321
|
+
year={2024},
|
|
322
|
+
url={https://github.com/pietroferraiuolo/XuPy}
|
|
323
|
+
}
|
|
324
|
+
```
|
xupy-1.1.0/README.md
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# XuPy
|
|
2
|
+
|
|
3
|
+
XuPy is a comprehensive Python package that provides GPU-accelerated masked arrays and NumPy-compatible functionality using CuPy. It automatically handles GPU/CPU fallback and offers an intuitive interface for scientific computing with masked data.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **GPU Acceleration**: Automatic GPU detection with CuPy fallback to NumPy
|
|
8
|
+
- **Masked Arrays**: Full support for masked arrays with GPU acceleration
|
|
9
|
+
- **Statistical Functions**: Comprehensive statistical operations (mean, std, var, min, max, etc.)
|
|
10
|
+
- **Array Manipulation**: Reshape, transpose, squeeze, expand_dims, and more
|
|
11
|
+
- **Mathematical Functions**: Trigonometric, exponential, logarithmic, and rounding functions
|
|
12
|
+
- **Random Generation**: Various random number generators (normal, uniform, etc.)
|
|
13
|
+
- **Universal Functions**: Support for applying any CuPy/NumPy ufunc with mask preservation
|
|
14
|
+
- **Performance**: Optimized for large-scale data processing on GPU
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install .
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
import xupy as xp
|
|
26
|
+
|
|
27
|
+
# Create arrays with automatic GPU detection
|
|
28
|
+
a = xp.random.normal(0, 1, (1000, 1000))
|
|
29
|
+
b = xp.random.normal(0, 1, (1000, 1000))
|
|
30
|
+
|
|
31
|
+
# Create masks
|
|
32
|
+
mask = xp.random.random((1000, 1000)) > 0.1
|
|
33
|
+
|
|
34
|
+
# Create masked arrays
|
|
35
|
+
am = xp.masked_array(a, mask)
|
|
36
|
+
bm = xp.masked_array(b, mask)
|
|
37
|
+
|
|
38
|
+
# Perform operations (masks are automatically handled)
|
|
39
|
+
result = am + bm
|
|
40
|
+
mean_val = am.mean()
|
|
41
|
+
std_val = am.std()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Comprehensive Examples
|
|
45
|
+
|
|
46
|
+
### Array Creation
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import xupy as xp
|
|
50
|
+
|
|
51
|
+
# Basic array creation
|
|
52
|
+
zeros = xp.zeros((3, 3))
|
|
53
|
+
ones = xp.ones((3, 3))
|
|
54
|
+
eye = xp.eye(3)
|
|
55
|
+
identity = xp.identity(3)
|
|
56
|
+
|
|
57
|
+
# Sequences
|
|
58
|
+
linspace = xp.linspace(0, 10, 100)
|
|
59
|
+
logspace = xp.logspace(0, 3, 100)
|
|
60
|
+
arange = xp.arange(0, 10, 0.5)
|
|
61
|
+
|
|
62
|
+
# Random arrays
|
|
63
|
+
random = xp.random((100, 100))
|
|
64
|
+
normal = xp.normal(0, 1, (100, 100))
|
|
65
|
+
uniform = xp.uniform(-1, 1, (100, 100))
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Masked Array Operations
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
import xupy as xp
|
|
72
|
+
from skimage.draw import disk
|
|
73
|
+
|
|
74
|
+
# Create data and mask
|
|
75
|
+
data = xp.random.normal(0, 1, (500, 500))
|
|
76
|
+
mask = xp.ones((500, 500), dtype=bool)
|
|
77
|
+
|
|
78
|
+
# Create circular mask
|
|
79
|
+
circle_coords = disk((250, 250), 200)
|
|
80
|
+
mask[circle_coords] = False
|
|
81
|
+
|
|
82
|
+
# Create masked array
|
|
83
|
+
masked_data = xp.masked_array(data, mask)
|
|
84
|
+
|
|
85
|
+
# Statistical operations
|
|
86
|
+
global_mean = masked_data.mean()
|
|
87
|
+
global_std = masked_data.std()
|
|
88
|
+
global_var = masked_data.var()
|
|
89
|
+
global_min = masked_data.min()
|
|
90
|
+
global_max = masked_data.max()
|
|
91
|
+
|
|
92
|
+
# Axis-wise operations
|
|
93
|
+
row_means = masked_data.mean(axis=0)
|
|
94
|
+
col_sums = masked_data.sum(axis=1)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Mathematical Functions
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
import xupy as xp
|
|
101
|
+
|
|
102
|
+
# Create masked array
|
|
103
|
+
data = xp.random.normal(0, 1, (100, 100))
|
|
104
|
+
mask = xp.random.random((100, 100)) > 0.8
|
|
105
|
+
ma = xp.masked_array(data, mask)
|
|
106
|
+
|
|
107
|
+
# Trigonometric functions
|
|
108
|
+
sin_result = ma.sin()
|
|
109
|
+
cos_result = ma.cos()
|
|
110
|
+
tan_result = ma.tan()
|
|
111
|
+
|
|
112
|
+
# Inverse trigonometric functions
|
|
113
|
+
arcsin_result = ma.arcsin()
|
|
114
|
+
arccos_result = ma.arccos()
|
|
115
|
+
arctan_result = ma.arctan()
|
|
116
|
+
|
|
117
|
+
# Hyperbolic functions
|
|
118
|
+
sinh_result = ma.sinh()
|
|
119
|
+
cosh_result = ma.cosh()
|
|
120
|
+
tanh_result = ma.tanh()
|
|
121
|
+
|
|
122
|
+
# Exponential and logarithmic functions
|
|
123
|
+
exp_result = ma.exp()
|
|
124
|
+
log_result = ma.log()
|
|
125
|
+
log10_result = ma.log10()
|
|
126
|
+
|
|
127
|
+
# Rounding functions
|
|
128
|
+
floor_result = ma.floor()
|
|
129
|
+
ceil_result = ma.ceil()
|
|
130
|
+
round_result = ma.round(decimals=2)
|
|
131
|
+
|
|
132
|
+
# Square root
|
|
133
|
+
sqrt_result = ma.sqrt()
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Array Manipulation
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
import xupy as xp
|
|
140
|
+
|
|
141
|
+
# Create masked array
|
|
142
|
+
data = xp.random.normal(0, 1, (4, 4))
|
|
143
|
+
mask = xp.random.random((4, 4)) > 0.5
|
|
144
|
+
ma = xp.masked_array(data, mask)
|
|
145
|
+
|
|
146
|
+
# Reshape
|
|
147
|
+
reshaped = ma.reshape(2, 8)
|
|
148
|
+
flattened = ma.flatten()
|
|
149
|
+
raveled = ma.ravel()
|
|
150
|
+
|
|
151
|
+
# Transpose and axes
|
|
152
|
+
transposed = ma.T
|
|
153
|
+
swapped = ma.swapaxes(0, 1)
|
|
154
|
+
|
|
155
|
+
# Expand and squeeze dimensions
|
|
156
|
+
expanded = ma.expand_dims(axis=1)
|
|
157
|
+
squeezed = expanded.squeeze()
|
|
158
|
+
|
|
159
|
+
# Repeat and tile
|
|
160
|
+
repeated = ma.repeat(2, axis=0)
|
|
161
|
+
tiled = ma.tile((2, 2))
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Advanced Operations
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
import xupy as xp
|
|
168
|
+
|
|
169
|
+
# Create complex masked array
|
|
170
|
+
data = xp.random.normal(0, 1, (100, 100, 3))
|
|
171
|
+
mask = xp.random.random((100, 100, 3)) > 0.9
|
|
172
|
+
ma = xp.masked_array(data, mask)
|
|
173
|
+
|
|
174
|
+
# Multi-axis operations
|
|
175
|
+
result = ma.mean(axis=(0, 1))
|
|
176
|
+
variance = ma.var(axis=1, ddof=1)
|
|
177
|
+
|
|
178
|
+
# Boolean operations
|
|
179
|
+
any_true = ma.any(axis=0)
|
|
180
|
+
all_true = ma.all(axis=1)
|
|
181
|
+
|
|
182
|
+
# Mask information
|
|
183
|
+
masked_count = ma.count_masked()
|
|
184
|
+
unmasked_count = ma.count_unmasked()
|
|
185
|
+
is_masked = ma.is_masked()
|
|
186
|
+
|
|
187
|
+
# Compressed data
|
|
188
|
+
valid_data = ma.compressed()
|
|
189
|
+
|
|
190
|
+
# Fill masked values
|
|
191
|
+
ma.fill_value(0.0)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Performance Benefits
|
|
195
|
+
|
|
196
|
+
XuPy automatically detects GPU availability and provides significant speedup for large arrays:
|
|
197
|
+
|
|
198
|
+
- **Small arrays (< 1000 elements)**: CPU (NumPy) may be faster due to GPU overhead
|
|
199
|
+
- **Medium arrays (1000-10000 elements)**: GPU provides 2-5x speedup
|
|
200
|
+
- **Large arrays (> 10000 elements)**: GPU provides 5-20x speedup depending on operation complexity
|
|
201
|
+
|
|
202
|
+
## GPU Requirements
|
|
203
|
+
|
|
204
|
+
- **CUDA-compatible GPU** with compute capability 3.0+
|
|
205
|
+
- **CuPy** package installed (`pip install cupy-cuda12x` for CUDA 12.x)
|
|
206
|
+
- **Automatic fallback** to NumPy if GPU is unavailable
|
|
207
|
+
|
|
208
|
+
## API Compatibility
|
|
209
|
+
|
|
210
|
+
XuPy maintains high compatibility with NumPy's masked array interface while leveraging CuPy's optimized operations:
|
|
211
|
+
|
|
212
|
+
- All standard properties (`shape`, `dtype`, `size`, `ndim`, `T`)
|
|
213
|
+
- Comprehensive arithmetic operations with mask propagation
|
|
214
|
+
- **Memory-optimized statistical methods** (`mean`, `std`, `var`, `min`, `max`) using CuPy's native operations
|
|
215
|
+
- Array manipulation methods (`reshape`, `transpose`, `squeeze`)
|
|
216
|
+
- Universal function support through `apply_ufunc`
|
|
217
|
+
- Conversion to NumPy masked arrays via `asmarray()`
|
|
218
|
+
- **GPU memory management** through `MemoryContext`
|
|
219
|
+
|
|
220
|
+
## Key Improvements
|
|
221
|
+
|
|
222
|
+
- **Eliminated redundant functions** - Uses CuPy/NumPy directly for basic operations
|
|
223
|
+
- **Memory-efficient statistical operations** - Leverages CuPy's optimized reduction operations
|
|
224
|
+
- **Proper mask propagation** - Maintains mask integrity across all operations
|
|
225
|
+
- **GPU memory management** - Context manager for efficient memory usage
|
|
226
|
+
|
|
227
|
+
## GPU Memory Management
|
|
228
|
+
|
|
229
|
+
XuPy includes an advanced `MemoryContext` class for efficient GPU memory management:
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
import xupy as xp
|
|
233
|
+
|
|
234
|
+
# Basic usage with automatic cleanup
|
|
235
|
+
with xp.MemoryContext() as ctx:
|
|
236
|
+
# GPU operations
|
|
237
|
+
data = xp.random.normal(0, 1, (10000, 10000))
|
|
238
|
+
result = data.mean()
|
|
239
|
+
# Memory automatically cleaned up on exit
|
|
240
|
+
|
|
241
|
+
# Advanced features
|
|
242
|
+
with xp.MemoryContext(memory_threshold=0.8, auto_cleanup=True) as ctx:
|
|
243
|
+
# Monitor memory usage
|
|
244
|
+
mem_info = ctx.get_memory_info()
|
|
245
|
+
print(f"GPU Memory: {mem_info['used'] / (1024**3):.2f} GB")
|
|
246
|
+
|
|
247
|
+
# Aggressive cleanup when needed
|
|
248
|
+
if ctx.check_memory_pressure():
|
|
249
|
+
ctx.aggressive_cleanup()
|
|
250
|
+
|
|
251
|
+
# Emergency cleanup for critical situations
|
|
252
|
+
ctx.emergency_cleanup()
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### MemoryContext Features
|
|
256
|
+
|
|
257
|
+
- **Automatic Cleanup**: Memory freed automatically when exiting context
|
|
258
|
+
- **Memory Monitoring**: Real-time tracking of GPU memory usage
|
|
259
|
+
- **Pressure Detection**: Automatic cleanup when memory usage is high
|
|
260
|
+
- **Aggressive Cleanup**: Force garbage collection and cache clearing
|
|
261
|
+
- **Emergency Cleanup**: Nuclear option for out-of-memory situations
|
|
262
|
+
- **Object Tracking**: Track GPU objects for proper cleanup
|
|
263
|
+
- **Memory History**: Keep history of memory usage over time
|
|
264
|
+
|
|
265
|
+
Run the memory management demo:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
python memory_demo.py
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Examples
|
|
272
|
+
|
|
273
|
+
Run the comprehensive examples script to see XuPy in action:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
python examples.py
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
This script demonstrates:
|
|
280
|
+
|
|
281
|
+
- GPU detection and information
|
|
282
|
+
- Basic masked array operations
|
|
283
|
+
- GPU-accelerated computations
|
|
284
|
+
- Mathematical functions
|
|
285
|
+
- Memory management
|
|
286
|
+
- Scientific computing use cases
|
|
287
|
+
- Performance comparisons
|
|
288
|
+
|
|
289
|
+
## Documentation
|
|
290
|
+
|
|
291
|
+
For detailed documentation, including comprehensive API reference and advanced usage examples, see [docs.md](docs.md).
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
|
|
295
|
+
See [LICENSE](LICENSE).
|
|
296
|
+
|
|
297
|
+
## Citation
|
|
298
|
+
|
|
299
|
+
If you use XuPy in your research, please cite:
|
|
300
|
+
|
|
301
|
+
```bibtex
|
|
302
|
+
@software{xupy2025,
|
|
303
|
+
title={XuPy: GPU-Accelerated Masked Arrays for Scientific Computing},
|
|
304
|
+
author={Ferraiuolo, Pietro},
|
|
305
|
+
year={2024},
|
|
306
|
+
url={https://github.com/pietroferraiuolo/XuPy}
|
|
307
|
+
}
|
|
308
|
+
```
|