Skip to content

Commit e2e957d

Browse files
committed
Added type hint stuff and some small things from helmholtz-analytics#938
1 parent 8adfb30 commit e2e957d

1 file changed

Lines changed: 43 additions & 38 deletions

File tree

heat/core/dndarray.py

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Provides HeAT's core data structure, the DNDarray, a distributed n-dimensional array"""
1+
"""Provides Heat's core data structure, the DNDarray, a distributed n-dimensional array"""
22

33
from __future__ import annotations
44

@@ -10,7 +10,7 @@
1010
from inspect import stack
1111
from mpi4py import MPI
1212
from pathlib import Path
13-
from typing import List, Union, Tuple, TypeVar, Optional
13+
from typing import Union, TypeVar
1414

1515
warnings.simplefilter("always", ResourceWarning)
1616

@@ -38,14 +38,14 @@ def __setitem__(self, key, value):
3838

3939
class DNDarray:
4040
"""
41-
Distributed N-Dimensional array. The core element of HeAT. It is composed of
41+
Distributed N-Dimensional array. The core element of Heat. It is composed of
4242
PyTorch tensors local to each process.
4343
4444
Parameters
4545
----------
4646
array : torch.Tensor
4747
Local array elements
48-
gshape : Tuple[int,...]
48+
gshape : tuple[int,...]
4949
The global shape of the array
5050
dtype : datatype
5151
The datatype of the array
@@ -64,9 +64,9 @@ class DNDarray:
6464
def __init__(
6565
self,
6666
array: torch.Tensor,
67-
gshape: Tuple[int, ...],
67+
gshape: tuple[int, ...],
6868
dtype: datatype,
69-
split: Union[int, None],
69+
split: int | None,
7070
device: Device,
7171
comm: Communication,
7272
balanced: bool,
@@ -77,10 +77,10 @@ def __init__(
7777
self.__split = split
7878
self.__device = device
7979
self.__comm = comm
80-
self.__balanced = balanced
80+
self.__balanced: bool = balanced
8181
self.__ishalo = False
82-
self.__halo_next = None
83-
self.__halo_prev = None
82+
self.__halo_next: torch.Tensor | None = None
83+
self.__halo_prev: torch.Tensor | None = None
8484
self.__partitions_dict__ = None
8585
self.__lshape_map = None
8686

@@ -116,7 +116,7 @@ def dtype(self) -> datatype:
116116
return self.__dtype
117117

118118
@property
119-
def gshape(self) -> Tuple:
119+
def gshape(self) -> tuple:
120120
"""
121121
Returns the global shape of the ``DNDarray`` across all processes
122122
"""
@@ -263,7 +263,7 @@ def lnumel(self) -> int:
263263
return np.prod(self.__array.shape)
264264

265265
@property
266-
def lloc(self) -> Union[DNDarray, None]:
266+
def lloc(self) -> "DNDarray" | None:
267267
"""
268268
Local item setter and getter. i.e. this function operates on a local
269269
level and only on the PyTorch tensors composing the :class:`DNDarray`.
@@ -272,7 +272,7 @@ def lloc(self) -> Union[DNDarray, None]:
272272
273273
Parameters
274274
----------
275-
key : int or slice or Tuple[int,...]
275+
key : int or slice or tuple[int,...]
276276
Indices of the desired data.
277277
value : scalar, optional
278278
All types compatible with pytorch tensors, if none given then this is a getter function
@@ -297,7 +297,7 @@ def lloc(self) -> Union[DNDarray, None]:
297297
return LocalIndex(self.__array)
298298

299299
@property
300-
def lshape(self) -> Tuple[int]:
300+
def lshape(self) -> tuple[int]:
301301
"""
302302
Returns the shape of the ``DNDarray`` on each node
303303
"""
@@ -318,28 +318,28 @@ def real(self) -> DNDarray:
318318
return complex_math.real(self)
319319

320320
@property
321-
def shape(self) -> Tuple[int]:
321+
def shape(self) -> tuple[int]:
322322
"""
323323
Returns the shape of the ``DNDarray`` as a whole
324324
"""
325325
return self.__gshape
326326

327327
@property
328-
def split(self) -> int:
328+
def split(self) -> int | None:
329329
"""
330330
Returns the axis on which the ``DNDarray`` is split
331331
"""
332332
return self.__split
333333

334334
@property
335-
def stride(self) -> Tuple[int]:
335+
def stride(self) -> tuple[int]:
336336
"""
337337
Returns the steps in each dimension when traversing a ``DNDarray``. torch-like usage: ``self.stride()``
338338
"""
339339
return self.__array.stride
340340

341341
@property
342-
def strides(self) -> Tuple[int]:
342+
def strides(self) -> tuple[int]:
343343
"""
344344
Returns bytes to step in each dimension when traversing a ``DNDarray``. numpy-like usage: ``self.strides()``
345345
"""
@@ -551,7 +551,7 @@ def astype(self, dtype, copy=True) -> DNDarray:
551551

552552
return self
553553

554-
def balance_(self) -> DNDarray:
554+
def balance_(self) -> None:
555555
"""
556556
Function for balancing a :class:`DNDarray` between all nodes. To determine if this is needed use the :func:`is_balanced()` function.
557557
If the ``DNDarray`` is already balanced this function will do nothing. This function modifies the ``DNDarray``
@@ -597,7 +597,7 @@ def __bool__(self) -> bool:
597597
"""
598598
return self.__cast(bool)
599599

600-
def __cast(self, cast_function) -> Union[float, int]:
600+
def __cast(self, cast_function) -> float | int:
601601
"""
602602
Implements a generic cast function for ``DNDarray`` objects.
603603
@@ -623,7 +623,7 @@ def __cast(self, cast_function) -> Union[float, int]:
623623

624624
raise TypeError("only size-1 arrays can be converted to Python scalars")
625625

626-
def collect_(self, target_rank: Optional[int] = 0) -> None:
626+
def collect_(self, target_rank: int | None = 0) -> None:
627627
"""
628628
A method collecting a distributed DNDarray to one MPI rank, chosen by the `target_rank` variable.
629629
It is a specific case of the ``redistribute_`` method.
@@ -676,7 +676,7 @@ def __complex__(self) -> DNDarray:
676676
"""
677677
return self.__cast(complex)
678678

679-
def counts_displs(self) -> Tuple[Tuple[int], Tuple[int]]:
679+
def counts_displs(self) -> tuple[tuple[int], tuple[int]]:
680680
"""
681681
Returns actual counts (number of items per process) and displacements (offsets) of the DNDarray.
682682
Does not assume load balance.
@@ -714,10 +714,11 @@ def create_lshape_map(self, force_check: bool = False) -> torch.Tensor:
714714
lshape_map = torch.zeros(
715715
(self.comm.size, self.ndim), dtype=torch.int64, device=self.device.torch_device
716716
)
717-
if not self.is_distributed:
717+
if not self.is_distributed():
718718
lshape_map[:] = torch.tensor(self.gshape, device=self.device.torch_device)
719-
return lshape_map
720-
if self.is_balanced(force_check=True):
719+
self.__lshape_map = lshape_map
720+
return lshape_map.clone()
721+
elif self.is_balanced(force_check=True):
721722
for i in range(self.comm.size):
722723
_, lshape, _ = self.comm.chunk(self.gshape, self.split, rank=i)
723724
lshape_map[i, :] = torch.tensor(lshape, device=self.device.torch_device)
@@ -878,7 +879,7 @@ def fill_diagonal(self, value: float) -> DNDarray:
878879

879880
return self
880881

881-
def __getitem__(self, key: Union[int, Tuple[int, ...], List[int, ...]]) -> DNDarray:
882+
def __getitem__(self, key: Union[int, tuple[int, ...], list[int, ...]]) -> DNDarray:
882883
"""
883884
Global getter function for DNDarrays.
884885
Returns a new DNDarray composed of the elements of the original tensor selected by the indices
@@ -888,7 +889,7 @@ def __getitem__(self, key: Union[int, Tuple[int, ...], List[int, ...]]) -> DNDar
888889
889890
Parameters
890891
----------
891-
key : int, slice, Tuple[int,...], List[int,...]
892+
key : int, slice, tuple[int,...], list[int,...]
892893
Indices to get from the tensor.
893894
894895
Examples
@@ -1166,6 +1167,10 @@ def is_balanced(self, force_check: bool = False) -> bool:
11661167
If True, the balanced status of the ``DNDarray`` will be assessed via
11671168
collective communication in any case.
11681169
"""
1170+
if not self.is_distributed():
1171+
self.__balanced = True
1172+
return self.balanced
1173+
11691174
if not force_check and self.balanced is not None:
11701175
return self.balanced
11711176

@@ -1250,7 +1255,7 @@ def __repr__(self) -> str:
12501255
"""
12511256
return printing.__repr__(self)
12521257

1253-
def ravel(self):
1258+
def ravel(self) -> "DNDarray":
12541259
"""
12551260
Flattens the ``DNDarray``.
12561261
@@ -1269,8 +1274,8 @@ def ravel(self):
12691274
return manipulations.ravel(self)
12701275

12711276
def redistribute_(
1272-
self, lshape_map: Optional[torch.Tensor] = None, target_map: Optional[torch.Tensor] = None
1273-
):
1277+
self, lshape_map: torch.Tensor | None = None, target_map: torch.Tensor | None = None
1278+
) -> None:
12741279
"""
12751280
Redistributes the data of the :class:`DNDarray` *along the split axis* to match the given target map.
12761281
This function does not modify the non-split dimensions of the ``DNDarray``.
@@ -1422,9 +1427,9 @@ def redistribute_(
14221427

14231428
def __redistribute_shuffle(
14241429
self,
1425-
snd_pr: Union[int, torch.Tensor],
1426-
send_amt: Union[int, torch.Tensor],
1427-
rcv_pr: Union[int, torch.Tensor],
1430+
snd_pr: int | torch.Tensor,
1431+
send_amt: int | torch.Tensor,
1432+
rcv_pr: int | torch.Tensor,
14281433
snd_dtype: torch.dtype,
14291434
):
14301435
"""
@@ -1569,15 +1574,15 @@ def resplit_(self, axis: int = None):
15691574

15701575
def __setitem__(
15711576
self,
1572-
key: Union[int, Tuple[int, ...], List[int, ...]],
1577+
key: Union[int, tuple[int, ...], list[int, ...]],
15731578
value: Union[float, DNDarray, torch.Tensor],
15741579
):
15751580
"""
15761581
Global item setter
15771582
15781583
Parameters
15791584
----------
1580-
key : Union[int, Tuple[int,...], List[int,...]]
1585+
key : Union[int, tuple[int,...], list[int,...]]
15811586
Index/indices to be set
15821587
value: Union[float, DNDarray,torch.Tensor]
15831588
Value to be set to the specified positions in the DNDarray (self)
@@ -1858,7 +1863,7 @@ def __setitem__(
18581863

18591864
def __setter(
18601865
self,
1861-
key: Union[int, Tuple[int, ...], List[int, ...]],
1866+
key: Union[int, tuple[int, ...], list[int, ...]],
18621867
value: Union[float, DNDarray, torch.Tensor],
18631868
):
18641869
"""
@@ -1890,7 +1895,7 @@ def __str__(self) -> str:
18901895
"""
18911896
return printing.__str__(self)
18921897

1893-
def tolist(self, keepsplit: bool = False) -> List:
1898+
def tolist(self, keepsplit: bool = False) -> list:
18941899
"""
18951900
Return a copy of the local array data as a (nested) Python list. For scalars, a standard Python number is returned.
18961901
@@ -1952,7 +1957,7 @@ def __xitem_get_key_start_stop(
19521957
step: int,
19531958
ends: torch.Tensor,
19541959
og_key_st: int,
1955-
) -> Tuple[int, int]:
1960+
) -> tuple[int, int]:
19561961
# this does some basic logic for adjusting the starting and stoping of the a key for
19571962
# setitem and getitem
19581963
if step is not None and rank > actives[0]:
@@ -1968,7 +1973,7 @@ def __xitem_get_key_start_stop(
19681973
return key_st, key_sp
19691974

19701975

1971-
# HeAT imports at the end to break cyclic dependencies
1976+
# Heat imports at the end to break cyclic dependencies
19721977
from . import complex_math
19731978
from . import devices
19741979
from . import factories

0 commit comments

Comments
 (0)