CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
156 lines
4.6 KiB
Python
156 lines
4.6 KiB
Python
# Copyright (c) Advanced Micro Devices, Inc.
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import common
|
|
|
|
from pc_sampling.code_object_analysis import (
|
|
CodeObjectDisassembly,
|
|
CodeObjectInstruction,
|
|
load_code_object_disassemblies,
|
|
parse_code_object_info,
|
|
)
|
|
|
|
|
|
def make_instruction(virtual_address, name="s_nop", comment=""):
|
|
"""Build one code_obj_info instruction dict."""
|
|
return {
|
|
"code_obj_offset": virtual_address - 0x1000,
|
|
"comment": comment,
|
|
"name": name,
|
|
"size": 4,
|
|
"virtual_address": virtual_address,
|
|
}
|
|
|
|
|
|
def make_symbol(name, instructions):
|
|
"""Build one code_obj_info symbol dict owning the given instructions."""
|
|
return {
|
|
"code_object_offset": 0,
|
|
"instructions": instructions,
|
|
"name": name,
|
|
"size": sum(inst["size"] for inst in instructions),
|
|
"virtual_address": instructions[0]["virtual_address"] if instructions else 0,
|
|
}
|
|
|
|
|
|
def make_code_object(code_object_id, symbols):
|
|
"""Build one code_obj_info code object dict."""
|
|
return {"id": code_object_id, "symbols": symbols}
|
|
|
|
|
|
def make_code_obj_info(code_objects):
|
|
"""Build a full code_obj_info.json payload."""
|
|
return {"code_objects": code_objects}
|
|
|
|
|
|
def test_parse_returns_one_entry_per_code_object():
|
|
data = make_code_obj_info([
|
|
make_code_object(1, [make_symbol("a", [make_instruction(0x1000)])]),
|
|
make_code_object(2, [make_symbol("b", [make_instruction(0x2000)])]),
|
|
])
|
|
|
|
disassemblies = parse_code_object_info(data)
|
|
|
|
assert [d.code_object_id for d in disassemblies] == [1, 2]
|
|
|
|
|
|
def test_parse_flattens_all_symbol_instructions():
|
|
data = make_code_obj_info([
|
|
make_code_object(
|
|
1,
|
|
[
|
|
make_symbol("a", [make_instruction(0x1000), make_instruction(0x1004)]),
|
|
make_symbol("b", [make_instruction(0x1008)]),
|
|
],
|
|
)
|
|
])
|
|
|
|
disassemblies = parse_code_object_info(data)
|
|
|
|
# Both symbols' instructions are flattened into one per-object list.
|
|
assert len(disassemblies[0].instructions) == 3
|
|
|
|
|
|
def test_parse_captures_virtual_address_instruction_and_comment():
|
|
data = make_code_obj_info([
|
|
make_code_object(
|
|
7,
|
|
[
|
|
make_symbol(
|
|
"kern",
|
|
[make_instruction(0x2040, name="v_mov_b32", comment="src.cpp:5")],
|
|
)
|
|
],
|
|
)
|
|
])
|
|
|
|
disassemblies = parse_code_object_info(data)
|
|
|
|
assert disassemblies[0].instructions[0] == CodeObjectInstruction(
|
|
virtual_address=0x2040,
|
|
instruction="v_mov_b32",
|
|
comment="src.cpp:5",
|
|
kernel_name="kern",
|
|
)
|
|
|
|
|
|
def test_parse_empty_dict_returns_empty_list():
|
|
assert parse_code_object_info({}) == []
|
|
|
|
|
|
def test_parse_code_object_without_symbols_yields_no_instructions():
|
|
data = make_code_obj_info([{"id": 7}])
|
|
assert parse_code_object_info(data) == [
|
|
CodeObjectDisassembly(code_object_id=7, instructions=[])
|
|
]
|
|
|
|
|
|
def test_load_discovers_files_and_parses_pid():
|
|
workload_dir = Path(common.get_output_dir())
|
|
workload_dir.mkdir(parents=True, exist_ok=True)
|
|
try:
|
|
(workload_dir / "123_code_obj_info.json").write_text(
|
|
json.dumps(make_code_obj_info([make_code_object(1, [])])), encoding="utf-8"
|
|
)
|
|
(workload_dir / "sub").mkdir()
|
|
(workload_dir / "sub" / "456_code_obj_info.json").write_text(
|
|
json.dumps(make_code_obj_info([make_code_object(2, [])])), encoding="utf-8"
|
|
)
|
|
|
|
result = load_code_object_disassemblies(str(workload_dir))
|
|
|
|
assert set(result) == {123, 456}
|
|
assert result[123][0].code_object_id == 1
|
|
assert result[456][0].code_object_id == 2
|
|
finally:
|
|
common.clean_output_dir(True, str(workload_dir))
|
|
|
|
|
|
def test_load_skips_file_without_pid_prefix():
|
|
workload_dir = Path(common.get_output_dir())
|
|
workload_dir.mkdir(parents=True, exist_ok=True)
|
|
try:
|
|
(workload_dir / "code_obj_info.json").write_text(
|
|
json.dumps(make_code_obj_info([make_code_object(1, [])])), encoding="utf-8"
|
|
)
|
|
|
|
assert load_code_object_disassemblies(str(workload_dir)) == {}
|
|
finally:
|
|
common.clean_output_dir(True, str(workload_dir))
|
|
|
|
|
|
def test_load_skips_malformed_json():
|
|
workload_dir = Path(common.get_output_dir())
|
|
workload_dir.mkdir(parents=True, exist_ok=True)
|
|
try:
|
|
(workload_dir / "123_code_obj_info.json").write_text(
|
|
"{not json", encoding="utf-8"
|
|
)
|
|
|
|
assert load_code_object_disassemblies(str(workload_dir)) == {}
|
|
finally:
|
|
common.clean_output_dir(True, str(workload_dir))
|