@@ -43,6 +43,8 @@ def set_startup_timestamps(program_start=None, main_entry=None):
4343import math
4444import os
4545import socket
46+ import shlex
47+ import subprocess
4648import sys
4749from contextlib import nullcontext
4850from pathlib import Path
@@ -344,6 +346,60 @@ def _is_global_rank_zero() -> bool:
344346 return True
345347
346348
349+ def _get_global_rank () -> int :
350+ """Return global distributed rank, defaulting to 0 before distributed init."""
351+ if torch .distributed .is_available () and torch .distributed .is_initialized ():
352+ return torch .distributed .get_rank ()
353+ return 0
354+
355+
356+ def _is_profile_rank (args ) -> bool :
357+ return len (args .profile_ranks ) == 0 or _get_global_rank () in args .profile_ranks
358+
359+
360+ def _format_command (cmd ):
361+ return " " .join (shlex .quote (str (part )) for part in cmd )
362+
363+
364+ def _hipprof_session_control (args , action ):
365+ if action not in ("start" , "stop" ):
366+ raise ValueError (f"Unsupported hipprof session action: { action } " )
367+
368+ session_id = getattr (args , "hipprof_session_id" , "" ) or os .environ .get ("HIPPROF_SESSION_ID" , "" )
369+ if not session_id :
370+ raise RuntimeError (
371+ "hipprof profiling requires train.model.hipprof_session_id "
372+ "or HIPPROF_SESSION_ID."
373+ )
374+
375+ hipprof_bin = (
376+ getattr (args , "hipprof_bin_path" , "" )
377+ or os .environ .get ("HIPPROF_BIN_PATH" , "" )
378+ or "hipprof"
379+ )
380+ cmd = [hipprof_bin , "--session" , session_id , f"--{ action } " ]
381+ try :
382+ subprocess .run (cmd , check = True , capture_output = True , text = True )
383+ except FileNotFoundError as exc :
384+ raise RuntimeError (
385+ f"hipprof executable not found: { hipprof_bin } . "
386+ "Set train.model.hipprof_bin_path or HIPPROF_BIN_PATH."
387+ ) from exc
388+ except subprocess .CalledProcessError as exc :
389+ output = []
390+ if exc .stdout :
391+ output .append (f"stdout:\n { exc .stdout .strip ()} " )
392+ if exc .stderr :
393+ output .append (f"stderr:\n { exc .stderr .strip ()} " )
394+ details = "\n " .join (output )
395+ if details :
396+ details = "\n " + details
397+ raise RuntimeError (
398+ f"hipprof session { action } failed with exit code { exc .returncode } : "
399+ f"{ _format_command (cmd )} { details } "
400+ ) from exc
401+
402+
347403from megatron .core .msc_utils import MultiStorageClientFeature , open_file
348404
349405
@@ -2821,14 +2877,15 @@ def post_training_step_callbacks(
28212877 if (
28222878 args .profile
28232879 and iteration == args .profile_step_end
2824- and (len (args .profile_ranks ) == 0 or
2825- torch .distributed .get_rank () in args .profile_ranks )
2880+ and _is_profile_rank (args )
28262881 ):
28272882 if args .use_pytorch_profiler :
28282883 assert prof is not None
28292884 prof .stop ()
28302885 if prof .execution_trace_observer is not None :
28312886 prof .execution_trace_observer .unregister_callback ()
2887+ elif getattr (args , "use_hipprof_profiler" , False ):
2888+ _hipprof_session_control (args , "stop" )
28322889 else :
28332890 torch .cuda .check_error (torch .cuda .cudart ().cudaProfilerStop ())
28342891 if nsys_nvtx_context is not None :
@@ -3204,8 +3261,13 @@ def get_e2e_base_metrics():
32043261 nsys_nvtx_context = None # reference to context for nsys profiling, so it can be cleaned up
32053262 if (
32063263 args .profile
3207- and (len (args .profile_ranks ) == 0 or
3208- torch .distributed .get_rank () in args .profile_ranks )
3264+ and args .use_pytorch_profiler
3265+ and getattr (args , "use_hipprof_profiler" , False )
3266+ ):
3267+ raise RuntimeError ("use_pytorch_profiler and use_hipprof_profiler cannot be enabled together." )
3268+ if (
3269+ args .profile
3270+ and _is_profile_rank (args )
32093271 and args .use_pytorch_profiler
32103272 ):
32113273 if args .pytorch_profiler_collect_chakra :
@@ -3264,11 +3326,12 @@ def trace_handler(p):
32643326 # Run training iterations till done.
32653327 buffered_rollouts = None
32663328 while iteration < args .train_iters :
3267- if (args .profile
3268- and (len (args .profile_ranks ) == 0 or
3269- torch .distributed .get_rank () in args .profile_ranks )):
3329+ if args .profile and _is_profile_rank (args ):
32703330 if args .use_pytorch_profiler :
32713331 prof .step ()
3332+ elif getattr (args , "use_hipprof_profiler" , False ):
3333+ if iteration == args .profile_step_start :
3334+ _hipprof_session_control (args , "start" )
32723335 elif iteration == args .profile_step_start :
32733336 torch .cuda .check_error (torch .cuda .cudart ().cudaProfilerStart ())
32743337 nsys_nvtx_context = torch .autograd .profiler .emit_nvtx (record_shapes = True )
0 commit comments