vollo-torch 27.0.0__py3-none-any.whl

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.
@@ -0,0 +1,105 @@
1
+ from contextvars import ContextVar
2
+ import vollo_torch.fx as fx
3
+ import vollo_torch.nn as nn
4
+ from typing import Sequence
5
+
6
+
7
+ class Fp8Weights:
8
+ """
9
+ Weights used inside this context will be quantized to an 8-bit format, which may be useful
10
+ for getting a model to fit on the board.
11
+
12
+ Note that this only applies to constant weight matrix multiplications. To ensure predictable
13
+ behaviour, all MatMuls and Linears that would use dynamic weights are rejected inside this context.
14
+ """
15
+
16
+ _depth: ContextVar[int] = ContextVar("depth", default=0)
17
+
18
+ def __enter__(self):
19
+ self._token = type(self)._depth.set(type(self)._depth.get() + 1)
20
+ return self
21
+
22
+ def __exit__(self, *args):
23
+ type(self)._depth.reset(self._token)
24
+
25
+ @classmethod
26
+ def is_active(cls) -> bool:
27
+ return cls._depth.get() > 0
28
+
29
+
30
+ class Fp32Activations:
31
+ """
32
+ Activations/computations inside this context will be in 32-bit precision. See
33
+ https://vollo.myrtle.ai/latest/supported-models.html for which operations support this.
34
+ """
35
+
36
+ _depth: ContextVar[int] = ContextVar("depth", default=0)
37
+
38
+ def __enter__(self):
39
+ self._token = type(self)._depth.set(type(self)._depth.get() + 1)
40
+ return self
41
+
42
+ def __exit__(self, *args):
43
+ type(self)._depth.reset(self._token)
44
+
45
+ @classmethod
46
+ def is_active(cls) -> bool:
47
+ return cls._depth.get() > 0
48
+
49
+
50
+ class CorePartition:
51
+ """
52
+ Computations inside this context will be limited to the cores specified in the context's constructor.
53
+
54
+ If override=False (default), the CorePartition must specify a subset of the enclosing partition's
55
+ cores; a ValueError is raised at context entry if this is violated.
56
+
57
+ If override=True, the partition overrides the enclosing partition.
58
+
59
+ Warning:
60
+ This class is experimental and is subject to change in future versions.
61
+ """
62
+
63
+ _current_cores: ContextVar[set] = ContextVar("_current_cores", default=None)
64
+ _current_outer_scan_partition_override: ContextVar[bool] = ContextVar(
65
+ "_current_outer_scan_partition_override", default=False
66
+ )
67
+
68
+ def __init__(self, cores: Sequence[int], override=False):
69
+ self.cores = set(cores)
70
+ if not self.cores:
71
+ raise ValueError("CorePartition cores must not be empty.")
72
+ self.override = override
73
+ self._token = None
74
+ self._token_outer_scan_partition_override = None
75
+
76
+ def __enter__(self):
77
+ outer_cores = type(self)._current_cores.get()
78
+ if not self.override and outer_cores is not None:
79
+ if not self.cores.issubset(outer_cores):
80
+ raise ValueError(
81
+ f"CorePartition cores {self.cores} are not a subset of the enclosing "
82
+ f"partition's cores {outer_cores}. "
83
+ "Use override=True to override the outer partition."
84
+ )
85
+ self._token = type(self)._current_cores.set(self.cores)
86
+ self._token_outer_scan_partition_override = type(
87
+ self
88
+ )._current_outer_scan_partition_override.set(
89
+ self.override or type(self)._current_outer_scan_partition_override.get()
90
+ )
91
+ return self
92
+
93
+ def __exit__(self, *args):
94
+ type(self)._current_cores.reset(self._token)
95
+ type(self)._current_outer_scan_partition_override.reset(
96
+ self._token_outer_scan_partition_override
97
+ )
98
+
99
+ @classmethod
100
+ def current_cores(cls):
101
+ return cls._current_cores.get()
102
+
103
+ @classmethod
104
+ def current_outer_scan_partition_override(cls):
105
+ return cls._current_outer_scan_partition_override.get()
@@ -0,0 +1,49 @@
1
+ from contextvars import ContextVar
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.fx
5
+ import torch.fx.passes.shape_prop
6
+
7
+ import vollo_torch.fx.tracer as tracer
8
+ import vollo_torch.fx.util as util
9
+ import vollo_torch.fx.nnir as nnir
10
+ from typing import List, Sequence, Tuple, Union
11
+
12
+
13
+ # Use Union in the type hint instead of | because our wheels are for Python 3.7+
14
+ # but | was added in Python 3.10 (Union was added in Python 3.5)
15
+ def prepare_shape(
16
+ model: nn.Module, *inputs: torch.Tensor
17
+ ) -> Tuple[torch.fx.GraphModule, Union[torch.Tensor, Tuple[torch.Tensor, ...]]]:
18
+ """
19
+ Trace the model's execution to annotate it with activation shapes. Necessary before converting a model
20
+ to NNIR.
21
+ """
22
+ return _prepare_shape_internal(model, *inputs)
23
+
24
+
25
+ def _prepare_shape_internal(
26
+ model: nn.Module, *inputs: Union[torch.Tensor, Sequence[torch.Tensor]]
27
+ ) -> Tuple[
28
+ torch.fx.GraphModule,
29
+ Union[torch.Tensor, Tuple[Union[torch.Tensor, Sequence[torch.Tensor]], ...]],
30
+ ]:
31
+ """
32
+ Same as prepare_shape, but allows more input/output types (such as lists, which aren't allowed as inputs/outputs
33
+ in normal models, but are allowed as inputs/outputs in a Scan step function)
34
+ """
35
+ with torch.no_grad():
36
+ t = tracer.Tracer()
37
+ graph = t.trace(model)
38
+ graph_model = torch.fx.GraphModule(model, graph)
39
+ outputs = torch.fx.passes.shape_prop.ShapeProp(graph_model).run(*inputs)
40
+ return (graph_model, outputs)
41
+
42
+
43
+ # Re-export
44
+ from vollo_torch.fx.serialization import save, load
45
+
46
+ is_vollo_tracing: ContextVar[bool] = ContextVar("is_vollo_tracing", default=False)
47
+ """
48
+ Describes whether the Vollo tracer is currently active. Make sure to use ``.get()`` to read the value.
49
+ """