r"""Greedy algorithm to allocate memory for tensors in the graph. Args: alignment: Memory alignment requirement specs: Set of TensorSpec objects with updated lifetimes graph_module: Graph module graph_signature: Graph signature extra_padding: Additional p
(
alignment: int,
specs: Set[TensorSpec],
graph_module: torch.fx.GraphModule,
graph_signature: ExportGraphSignature,
extra_padding: int = 0,
*,
allow_overlapping_allocations: bool = True,
)
| 933 | |
| 934 | |
| 935 | def greedy( |
| 936 | alignment: int, |
| 937 | specs: Set[TensorSpec], |
| 938 | graph_module: torch.fx.GraphModule, |
| 939 | graph_signature: ExportGraphSignature, |
| 940 | extra_padding: int = 0, |
| 941 | *, |
| 942 | allow_overlapping_allocations: bool = True, |
| 943 | ) -> MemoryAlgoResult: |
| 944 | r"""Greedy algorithm to allocate memory for tensors in the graph. |
| 945 | |
| 946 | Args: |
| 947 | alignment: Memory alignment requirement |
| 948 | specs: Set of TensorSpec objects with updated lifetimes |
| 949 | graph_module: Graph module |
| 950 | graph_signature: Graph signature |
| 951 | extra_padding: Additional padding to add to each memory buffer (in bytes) |
| 952 | allow_overlapping_allocations: If set to true, allows for allocations that overlap |
| 953 | in their lifetime but are at different offsets in the storage. By default true. |
| 954 | This flag is added to allow for Vulkan to use MemoryPlanningPass with overlapping |
| 955 | allocations disabled |
| 956 | |
| 957 | Returns: |
| 958 | MemoryAlgoResult containing the allocation decisions |
| 959 | """ |
| 960 | greedy_result = MemoryAlgoResult({}, []) |
| 961 | spec2obj = {} |
| 962 | shared_objects = defaultdict(list) |
| 963 | |
| 964 | # For each tensor, pick the available shared object with closest size to |
| 965 | # the tensor. If there are no available shared object left, create a new |
| 966 | # one. |
| 967 | import bisect |
| 968 | |
| 969 | sorted_specs = [] |
| 970 | for spec in specs: |
| 971 | bisect.insort(sorted_specs, spec, key=lambda x: x.allocated_memory) |
| 972 | |
| 973 | sorted_specs.reverse() |
| 974 | |
| 975 | for spec in sorted_specs: |
| 976 | # Create an entry for this TensorSpec in the result object that we'll be |
| 977 | # returning from this algorithm. |
| 978 | spec_alloc_result = greedy_result.spec_dict.get(spec, SpecAllocResult(0, 0, 0)) |
| 979 | if spec.mem_id is None: |
| 980 | spec_alloc_result.mem_id = 1 |
| 981 | else: |
| 982 | spec_alloc_result.mem_id = spec.mem_id |
| 983 | greedy_result.spec_dict[spec] = spec_alloc_result |
| 984 | spec.realign(alignment) |
| 985 | spec2obj[spec] = pick_shared_obj( |
| 986 | shared_objects[spec_alloc_result.mem_id], |
| 987 | spec, |
| 988 | allow_overlapping_allocations, |
| 989 | ) |
| 990 | |
| 991 | if len(shared_objects) == 0: |
| 992 | # Cannot find any tensor in the graph that needs to be allocated. |
nothing calls this directly
no test coverage detected