Abstract base class that stores data as well as any extra metadata. This allows for subclassing `torch.Tensor` and `np.ndarray` through multiple inheritance. Metadata is stored in the form of a dictionary. Behavior should be the same as extended class (e.g., `torch.Tensor` or `np
| 61 | |
| 62 | |
| 63 | class MetaObj: |
| 64 | """ |
| 65 | Abstract base class that stores data as well as any extra metadata. |
| 66 | |
| 67 | This allows for subclassing `torch.Tensor` and `np.ndarray` through multiple inheritance. |
| 68 | |
| 69 | Metadata is stored in the form of a dictionary. |
| 70 | |
| 71 | Behavior should be the same as extended class (e.g., `torch.Tensor` or `np.ndarray`) |
| 72 | aside from the extended meta functionality. |
| 73 | |
| 74 | Copying of information: |
| 75 | |
| 76 | * For `c = a + b`, then auxiliary data (e.g., metadata) will be copied from the |
| 77 | first instance of `MetaObj` if `a.is_batch` is False |
| 78 | (For batched data, the metadata will be shallow copied for efficiency purposes). |
| 79 | |
| 80 | """ |
| 81 | |
| 82 | def __init__(self) -> None: |
| 83 | self._meta: dict = MetaObj.get_default_meta() |
| 84 | self._applied_operations: list = MetaObj.get_default_applied_operations() |
| 85 | self._pending_operations: list = MetaObj.get_default_applied_operations() # the same default as applied_ops |
| 86 | self._is_batch: bool = False |
| 87 | |
| 88 | @staticmethod |
| 89 | def flatten_meta_objs(*args: Iterable): |
| 90 | """ |
| 91 | Recursively flatten input and yield all instances of `MetaObj`. |
| 92 | This means that for both `torch.add(a, b)`, `torch.stack([a, b])` (and |
| 93 | their numpy equivalents), we return `[a, b]` if both `a` and `b` are of type |
| 94 | `MetaObj`. |
| 95 | |
| 96 | Args: |
| 97 | args: Iterables of inputs to be flattened. |
| 98 | Returns: |
| 99 | list of nested `MetaObj` from input. |
| 100 | """ |
| 101 | for a in itertools.chain(*args): |
| 102 | if isinstance(a, (list, tuple)): |
| 103 | yield from MetaObj.flatten_meta_objs(a) |
| 104 | elif isinstance(a, MetaObj): |
| 105 | yield a |
| 106 | |
| 107 | @staticmethod |
| 108 | def copy_items(data): |
| 109 | """returns a copy of the data. list and dict are shallow copied for efficiency purposes.""" |
| 110 | if is_immutable(data): |
| 111 | return data |
| 112 | if isinstance(data, (list, dict, np.ndarray)): |
| 113 | return data.copy() |
| 114 | if isinstance(data, torch.Tensor): |
| 115 | return data.detach().clone() |
| 116 | return deepcopy(data) |
| 117 | |
| 118 | def copy_meta_from(self, input_objs, copy_attr=True, keys=None): |
| 119 | """ |
| 120 | Copy metadata from a `MetaObj` or an iterable of `MetaObj` instances. |
no outgoing calls
no test coverage detected
searching dependent graphs…