mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-20 21:14:14 +08:00
[inductor] add _get_inductor_debug_symbol_cflags for debug symbol control. (#159938)
We need to add inductor debug symbol support for crash case debug. When we turn on generate debug symbol. On Windows, it should create a [module_name].pdb file. It helps debug by WinDBG. On Linux, it should create some debug sections in binary file. I added UT for it also. It works well on Windows inductor debug. <img width="1648" height="833" alt="image" src="https://github.com/user-attachments/assets/5282a7de-cef3-4a38-9cd4-a0e63482c8b6" /> Pull Request resolved: https://github.com/pytorch/pytorch/pull/159938 Approved by: https://github.com/jansel, https://github.com/angelayi
This commit is contained in:
@ -1,6 +1,14 @@
|
||||
# Owner(s): ["module: inductor"]
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
import torch
|
||||
from torch import _dynamo as dynamo, _inductor as inductor
|
||||
from torch._inductor.codecache import write
|
||||
from torch._inductor.cpp_builder import CppBuilder, CppOptions
|
||||
from torch._inductor.test_case import run_tests, TestCase
|
||||
from torch._inductor.utils import gen_gm_and_inputs
|
||||
from torch.fx import symbolic_trace
|
||||
@ -8,6 +16,25 @@ from torch.fx.experimental.proxy_tensor import make_fx
|
||||
from torch.testing._internal.inductor_utils import HAS_CPU
|
||||
|
||||
|
||||
_IS_MACOS = sys.platform.startswith("darwin")
|
||||
_IS_WINDOWS = sys.platform == "win32"
|
||||
|
||||
|
||||
def safe_command_output(cmd, timeout=30):
|
||||
try:
|
||||
return subprocess.check_output(
|
||||
cmd,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
timeout=timeout,
|
||||
shell=isinstance(cmd, str),
|
||||
).strip()
|
||||
except subprocess.CalledProcessError as e:
|
||||
return f"run failed(error code {e.returncode}): {e.output.strip()}"
|
||||
except subprocess.TimeoutExpired:
|
||||
return "runt timeout"
|
||||
|
||||
|
||||
class MyModule(torch.nn.Module):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
@ -109,6 +136,53 @@ class TestStandaloneInductor(TestCase):
|
||||
mod_opt = inductor.compile(mod, inp)
|
||||
self.assertEqual(mod(*inp), mod_opt(*inp))
|
||||
|
||||
@mock.patch.dict(os.environ, {"TORCHINDUCTOR_DEBUG_SYMBOL": "1"})
|
||||
def test_inductor_generate_debug_symbol(self):
|
||||
cpp_code = """
|
||||
int main(){
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
|
||||
_, source_path = write(
|
||||
cpp_code,
|
||||
"cpp",
|
||||
)
|
||||
build_option = CppOptions()
|
||||
cpp_builder = CppBuilder(
|
||||
name="test_symbol",
|
||||
sources=source_path,
|
||||
output_dir=os.path.dirname(source_path),
|
||||
BuildOption=build_option,
|
||||
)
|
||||
cpp_builder.build()
|
||||
binary_path = cpp_builder.get_target_file_path()
|
||||
|
||||
"""
|
||||
When we turn on generate debug symbol.
|
||||
On Windows, it should create a [module_name].pdb file. It helps debug by WinDBG.
|
||||
On Linux, it should create some debug sections in binary file.
|
||||
"""
|
||||
|
||||
def check_linux_debug_section(module_path: str):
|
||||
check_cmd = shlex.split(f"readelf -S {module_path}")
|
||||
output = safe_command_output(check_cmd)
|
||||
has_debug_sym = ".debug_info" in output
|
||||
self.assertEqual(has_debug_sym, True)
|
||||
|
||||
def check_windows_pdb_exist(module_path: str):
|
||||
file_name_no_ext = os.path.splitext(module_path)[0]
|
||||
file_name_pdb = f"{file_name_no_ext}.pdb"
|
||||
has_pdb_file = os.path.exists(file_name_pdb)
|
||||
self.assertEqual(has_pdb_file, True)
|
||||
|
||||
if _IS_WINDOWS:
|
||||
check_windows_pdb_exist(binary_path)
|
||||
elif _IS_MACOS:
|
||||
pass # MacOS not sure that if it should be works.
|
||||
else:
|
||||
check_linux_debug_section(binary_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if HAS_CPU:
|
||||
|
@ -637,7 +637,7 @@ def _get_optimization_cflags(
|
||||
return cflags
|
||||
|
||||
|
||||
def _get_shared_cflag(do_link: bool) -> list[str]:
|
||||
def _get_shared_cflags(do_link: bool) -> list[str]:
|
||||
if _IS_WINDOWS:
|
||||
"""
|
||||
MSVC `/MD` using python `ucrtbase.dll` lib as runtime.
|
||||
@ -652,6 +652,25 @@ def _get_shared_cflag(do_link: bool) -> list[str]:
|
||||
return ["shared", "fPIC"]
|
||||
|
||||
|
||||
def _get_inductor_debug_symbol_cflags() -> tuple[list[str], list[str]]:
|
||||
"""
|
||||
When we turn on generate debug symbol.
|
||||
On Windows, it should create a [module_name].pdb file. It helps debug by WinDBG.
|
||||
On Linux, it should create some debug sections in binary file.
|
||||
"""
|
||||
cflags: list[str] = []
|
||||
ldflags: list[str] = []
|
||||
b_enable_debug_symbol = os.environ.get("TORCHINDUCTOR_DEBUG_SYMBOL", "0") == "1"
|
||||
if b_enable_debug_symbol:
|
||||
if _IS_WINDOWS:
|
||||
cflags = ["Z7", "_DEBUG", "OD"]
|
||||
ldflags = ["DEBUG", "OPT:REF", "OPT:ICF"]
|
||||
else:
|
||||
cflags.append("g")
|
||||
|
||||
return cflags, ldflags
|
||||
|
||||
|
||||
def get_cpp_options(
|
||||
cpp_compiler: str,
|
||||
do_link: bool,
|
||||
@ -667,12 +686,15 @@ def get_cpp_options(
|
||||
libraries: list[str] = []
|
||||
passthrough_args: list[str] = []
|
||||
|
||||
dbg_cflags, dbg_ldflags = _get_inductor_debug_symbol_cflags()
|
||||
|
||||
cflags = (
|
||||
_get_shared_cflag(do_link)
|
||||
_get_shared_cflags(do_link)
|
||||
+ _get_optimization_cflags(cpp_compiler, min_optimize)
|
||||
+ _get_warning_all_cflag(warning_all)
|
||||
+ _get_cpp_std_cflag()
|
||||
+ _get_os_related_cpp_cflags(cpp_compiler)
|
||||
+ dbg_cflags
|
||||
)
|
||||
|
||||
if not _IS_WINDOWS and config.aot_inductor.enable_lto and _is_clang(cpp_compiler):
|
||||
@ -685,7 +707,7 @@ def get_cpp_options(
|
||||
definitions,
|
||||
include_dirs,
|
||||
cflags,
|
||||
ldflags,
|
||||
ldflags + dbg_ldflags,
|
||||
libraries_dirs,
|
||||
libraries,
|
||||
passthrough_args,
|
||||
|
Reference in New Issue
Block a user