11import logging
2- import os
3- import pickle
42
5- import torch
63from d2go .config import CfgNode as CN
7- from detectron2 .utils .file_io import PathManager
8- from mobile_cv .torch .utils_pytorch import comm
9- from torch .cuda ._memory_viz import segment_plot , trace_plot
104
115logger : logging .Logger = logging .getLogger (__name__ )
126
@@ -29,84 +23,3 @@ def add_zoomer_default_config(_C: CN):
2923 False # Do not enable by default, since it may cause performance regression
3024 )
3125 _C .ZOOMER .ENABLE_MEMORY_PROFILING = False
32-
33-
34- def omm_logger_wrapper (output_dir ):
35- def oom_logger (
36- device : int , alloc : int , device_alloc : int , device_free : int
37- ) -> None :
38- """
39- Log memory snapshot in the event of CUDA OOM.
40- """
41- logger .info (
42- f"Saving memory snapshot device: { device } , alloc: { alloc } , device_alloc: { device_alloc } , device_free: { device_free } "
43- )
44- try :
45- log_memory_snapshot (output_dir , file_prefix = "oom" )
46- except Exception as e :
47- logger .error (f"Failed to log memory snapshot during OOM { e } " )
48-
49- return oom_logger
50-
51-
52- def log_memory_snapshot (output_dir : str , file_prefix : str = "" ) -> None :
53- """
54- Log memory snapshots to output_dir
55- """
56- if not torch .cuda .is_available ():
57- logger .info ("CUDA unavailable. Not logging snapshot" )
58- return
59-
60- try :
61- rank = comm .get_rank ()
62- save_dir = os .path .join (
63- output_dir , "memory_snapshot" , f"{ file_prefix } _rank{ rank } "
64- )
65- logger .info (f"Logging memory snapshot to { save_dir } " )
66- snapshot = torch .cuda .memory ._snapshot ()
67- dump_snapshot (save_dir , snapshot )
68- except Exception as e :
69- logger .error (f"Failed to log memory snapshot to { save_dir } : { e } " )
70-
71-
72- def dump_snapshot (save_dir : str , snapshot ):
73- """
74- Dump memory snapshot and useful plots to save_dir.
75- This is a rewrite of torch.cuda.memory._dump_snapshot() with PathManager.
76- """
77- if not PathManager .exists (save_dir ):
78- PathManager .mkdirs (save_dir )
79- with PathManager .open (os .path .join (save_dir , "snapshot.pickle" ), "wb" ) as f :
80- pickle .dump (snapshot , f )
81- with PathManager .open (os .path .join (save_dir , "trace_plot.html" ), "w" ) as f :
82- f .write (trace_plot (snapshot ))
83- with PathManager .open (os .path .join (save_dir , "segment_plot.html" ), "w" ) as f :
84- f .write (segment_plot (snapshot ))
85- logger .info (f"Saved memory snapshot to { save_dir } " )
86-
87-
88- def record_memory_history (trace_max_entries = 1000000 ) -> None :
89- """
90- Start recording memory history and stack traces.
91- """
92- if not torch .cuda .is_available ():
93- logger .info ("CUDA unavailable. Not recording memory history" )
94- return
95-
96- torch .cuda .memory ._record_memory_history (
97- enabled = "all" , max_entries = trace_max_entries
98- )
99- logger .info ("Started recording memory history" )
100-
101-
102- def attach_oom_logger (output_dir , trace_max_entries = 1000000 ) -> None :
103- """
104- Start recording memory history and attach the OOM logger.
105- """
106- if not torch .cuda .is_available ():
107- logger .info ("CUDA unavailable. Not attaching OOM logger" )
108- return
109-
110- record_memory_history (trace_max_entries )
111- torch ._C ._cuda_attach_out_of_memory_observer (omm_logger_wrapper (output_dir ))
112- logger .info ("Attached GPU OOM logger" )
0 commit comments