MCPcopy Create free account
hub / github.com/pytorch/executorch / apply_algo

Function apply_algo

exir/memory_planning.py:1411–1544  ·  view source on GitHub ↗

Recursively apply algo to graph_module and its submodules for control flow. Partitions specs by device type and device idx, and runs the memory planning algorithm independently per device, then merges results into separate buffers. This ensures device memory and CPU memory are neve

(
    algo: Callable[..., list[int]],
    graph_module: torch.fx.GraphModule,
    alignment: int,
    graph_signature: Optional[ExportGraphSignature] = None,
    alloc_graph_input: bool = True,
    alloc_graph_output: bool = True,
    alloc_mutable_buffers: bool = True,
    enable_non_cpu_memory_planning: bool = False,
)

Source from the content-addressed store, hash-verified

1409
1410
1411def apply_algo(
1412 algo: Callable[..., list[int]],
1413 graph_module: torch.fx.GraphModule,
1414 alignment: int,
1415 graph_signature: Optional[ExportGraphSignature] = None,
1416 alloc_graph_input: bool = True,
1417 alloc_graph_output: bool = True,
1418 alloc_mutable_buffers: bool = True,
1419 enable_non_cpu_memory_planning: bool = False,
1420) -> list[int]:
1421 """
1422 Recursively apply algo to graph_module and its submodules for control flow.
1423
1424 Partitions specs by device type and device idx, and runs the memory planning
1425 algorithm independently per device, then merges results into separate buffers.
1426 This ensures device memory and CPU memory are never mixed.
1427
1428 When enable_non_cpu_memory_planning is False (default), all specs are planned
1429 into a single CPU memory pool regardless of their device attribute. This
1430 preserves the legacy behavior. Set to True to enable per-device partitioning.
1431
1432 Algo implementation should handle one of two meta entries for submodules:
1433 1. input_mem_buffer_sizes: List of int offset bytes. Memory allocated by
1434 `algo` should start at the offset specified by this list;
1435 OR
1436 2. non_const_buffer_sizes: List of bufsizes for planned memory in submodule.
1437 `algo` should reserve the space specified by this list for the lifetime
1438 of the submodule node (e.g. cond, while, map).
1439
1440 TODO: Missing optimizations:
1441 1. To handle maps, we set `alloc_graph_input=True`, which allocates
1442 appropriate space for mapped arg but ends up allocating extra space for
1443 `operand` arg. The memory for operands is unused.
1444 """
1445 # Extract the nodes and their lifespans from the graph_module
1446 _ = update_all_tensors_lifetime(graph_module, graph_signature)
1447
1448 # Collect specs into an ordered list so we can iterate multiple times and
1449 # partition by device. Order matters: order-sensitive algorithms (e.g.
1450 # greedy with bisect.insort) rely on insertion order for stable tie-breaking,
1451 # and `collect_specs_from_nodes` already deduplicates via its `dedup` flag.
1452 all_specs: list[TensorSpec] = list(
1453 collect_specs_from_nodes(
1454 graph_module.graph.nodes,
1455 graph_signature,
1456 do_assertion=False,
1457 ignore_graph_input=not alloc_graph_input,
1458 ignore_graph_output=not alloc_graph_output,
1459 ignore_mutable_buffers=not alloc_mutable_buffers,
1460 )
1461 )
1462
1463 # Get temporary specs for submodules to set aside space during execution
1464 # of submodules.
1465 # NOTE: submodule_bufsizes are currently applied only to the CPU partition.
1466 # This assumes all control-flow submodule tensors (cond/while/map) live in
1467 # CPU memory. Today this is safe because on-device tensors only appear as
1468 # delegate blob I/O, which never lives inside control-flow submodules.

Calls 9

collect_specs_from_nodesFunction · 0.85
insert_calls_to_freeFunction · 0.85
keysMethod · 0.80
appendMethod · 0.45