The expected shape and dtype of a tensor
| 48 | |
| 49 | @dataclasses.dataclass |
| 50 | class TensorSpec: |
| 51 | """The expected shape and dtype of a tensor""" |
| 52 | shape: Tuple[int] |
| 53 | dtype: np.dtype |
| 54 | |
| 55 | def __post_init__(self): |
| 56 | assert all(x >= 0 for x in self.shape if x is not None) |
| 57 | |
| 58 | def extend(self, n, dim=0): |
| 59 | shape = list(self.shape) |
| 60 | shape[dim] += n |
| 61 | return TensorSpec(tuple(shape), self.dtype) |
| 62 | |
| 63 | def __mul__(self, other): |
| 64 | assert isinstance(other, int) |
| 65 | return TensorSpec(tuple(s*other for s in self.shape), dtype=self.dtype) |
| 66 | |
| 67 | @classmethod |
| 68 | def build(cls, data): |
| 69 | if data is None: |
| 70 | return None |
| 71 | return TensorSpec(data.shape, data.dtype) |
| 72 | |
| 73 | @classmethod |
| 74 | def get_spec(cls, src: TokenizedVisionData) -> Dict[str, 'TensorSpec']: |
| 75 | spec = {} if src.other_data is None else src.other_data |
| 76 | for k in ["tokens", "images", "image_masks", "token_pooling", "low_res_token_pooling"]: |
| 77 | v = getattr(src, k) |
| 78 | if v is not None: |
| 79 | spec[k] = TensorSpec.build(getattr(src, k)) |
| 80 | return spec |
| 81 | |
| 82 | @staticmethod |
| 83 | def max(*other: 'TensorSpec'): |
| 84 | other = [o for o in other if o is not None] |
| 85 | if not other: |
| 86 | return None |
| 87 | rank = len(other[0].shape) |
| 88 | dtype = other[0].dtype |
| 89 | assert all(rank == len(o.shape) for o in other) |
| 90 | assert all(dtype == o.dtype for o in other) |
| 91 | return TensorSpec( |
| 92 | [max([o.shape[i] for o in other]) for i in range(rank)], |
| 93 | dtype |
| 94 | ) |
| 95 | |
| 96 | def max_dictionaries(*other: Dict[str, 'TensorSpec']): |
| 97 | return {k: TensorSpec.max(*(o[k] for o in other if k in o)) for k in get_all_keys(other)} |
| 98 | |
| 99 | |
| 100 | @dataclasses.dataclass |
no outgoing calls
no test coverage detected