Revert memory allocation CSV output file header and update tests (#532)

* Reverted header and field location for csv memory allocation and updated tests

* Updated example csv file and made small update
このコミットが含まれているのは:
Trowbridge, Ian
2025-08-04 13:22:27 -05:00
committed by GitHub
コミット 533a8329d8
6個のファイルの変更202行の追加36行の削除
+4 -6
ファイルの表示
@@ -1,7 +1,5 @@
"Kind","Operation","Agent_Id","Allocation_Size","Address","Correlation_Id","Start_Timestamp","End_Timestamp"
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_ALLOCATE",Agent 0,1024,0x7fb2d0005000,11,3721742710532634,3721742710584854
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_FREE",Agent 0,0,0x7fb2d0005000,12,3721742710596404,3721742710933366
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_ALLOCATE",Agent 0,1024,0x7fb2d0005000,13,3721742710941416,3721742710960916
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_FREE",Agent 0,0,0x7fb2d0005000,14,3721742710967236,3721742711197647
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_ALLOCATE",Agent 0,1024,0x7fb2d0005000,15,3721742711204077,3721742711219717
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_FREE",Agent 0,0,0x7fb2d0005000,16,3721742711225857,3721742711466018
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_ALLOCATE","Agent 0",1024,"0x00007ffb26354000",1,816098791282238,816098791339655
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_ALLOCATE","Agent 0",1024,"0x00007ffb168d6000",2,816098791350331,816098791386746
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_FREE","",0,"0x00007ffb26354000",7,816098791533678,816098791678768
"MEMORY_ALLOCATION","MEMORY_ALLOCATION_FREE","",0,"0x00007ffb168d6000",8,816098791681482,816098791873422
1 Kind Operation Agent_Id Allocation_Size Address Correlation_Id Start_Timestamp End_Timestamp
2 MEMORY_ALLOCATION MEMORY_ALLOCATION_ALLOCATE Agent 0 1024 0x7fb2d0005000 0x00007ffb26354000 11 1 3721742710532634 816098791282238 3721742710584854 816098791339655
3 MEMORY_ALLOCATION MEMORY_ALLOCATION_FREE MEMORY_ALLOCATION_ALLOCATE Agent 0 0 1024 0x7fb2d0005000 0x00007ffb168d6000 12 2 3721742710596404 816098791350331 3721742710933366 816098791386746
4 MEMORY_ALLOCATION MEMORY_ALLOCATION_ALLOCATE MEMORY_ALLOCATION_FREE Agent 0 1024 0 0x7fb2d0005000 0x00007ffb26354000 13 7 3721742710941416 816098791533678 3721742710960916 816098791678768
5 MEMORY_ALLOCATION MEMORY_ALLOCATION_FREE Agent 0 0 0x7fb2d0005000 0x00007ffb168d6000 14 8 3721742710967236 816098791681482 3721742711197647 816098791873422
MEMORY_ALLOCATION MEMORY_ALLOCATION_ALLOCATE Agent 0 1024 0x7fb2d0005000 15 3721742711204077 3721742711219717
MEMORY_ALLOCATION MEMORY_ALLOCATION_FREE Agent 0 0 0x7fb2d0005000 16 3721742711225857 3721742711466018
+4 -4
ファイルの表示
@@ -472,11 +472,11 @@ generate_csv(const output_config&
{"Kind",
"Operation",
"Agent_Id",
"Allocation_Size",
"Address",
"Correlation_Id",
"Start_Timestamp",
"End_Timestamp",
"Allocation_Size"}};
"End_Timestamp"}};
for(auto ditr : data)
{
for(auto record : data.get(ditr))
@@ -498,11 +498,11 @@ generate_csv(const output_config&
tool_metadata.get_kind_name(record.kind),
api_name,
agent_info,
record.allocation_size,
rocprofiler::sdk::utility::as_hex(record.address.handle, 16),
record.correlation_id.internal,
record.start_timestamp,
record.end_timestamp,
record.allocation_size);
record.end_timestamp);
ofs << row_ss.str();
}
+31 -20
ファイルの表示
@@ -195,11 +195,16 @@ def test_memory_alloc_sizes(input_data):
sdk_data = data["rocprofiler-sdk-json-tool"]
# Op values:
# 0 == ??? (unknown)
# 1 == hsa_memory_allocate
# 2 == hsa_amd_vmem_handle_create
# 3 == hsa_memory_free
# 4 == hsa_amd_vmem_handle_release
UNKNOWN_OP = 0
HSA_MEMORY_ALLOCATE_OP = 1
HSA_AMD_VMEM_HANDLE_CREATE_OP = 2
HSA_MEMORY_FREE_OP = 3
HSA_AMD_VMEM_HANDLE_RELEASE = 4
TOTAL_MEM_OPS = 5
ALLOCATE_OPS = (HSA_MEMORY_ALLOCATE_OP, HSA_AMD_VMEM_HANDLE_CREATE_OP)
FREE_OPS = (HSA_MEMORY_FREE_OP, HSA_AMD_VMEM_HANDLE_RELEASE)
memory_alloc_cnt = dict(
[
(idx, {"agent": set(), "starting_addr": set(), "size": set(), "count": 0})
@@ -208,7 +213,7 @@ def test_memory_alloc_sizes(input_data):
)
for itr in sdk_data["buffer_records"]["memory_allocations"]:
op_id = itr["operation"]
assert op_id > 0 and op_id <= 5, f"{itr}"
assert op_id > UNKNOWN_OP and op_id < TOTAL_MEM_OPS, f"{itr}"
memory_alloc_cnt[op_id]["count"] += 1
memory_alloc_cnt[op_id]["starting_addr"].add(itr.address)
memory_alloc_cnt[op_id]["size"].add(itr.allocation_size)
@@ -216,7 +221,7 @@ def test_memory_alloc_sizes(input_data):
for itr in sdk_data["callback_records"]["memory_copies"]:
op_id = itr.operation
assert op_id > 0 and op_id <= 5, f"{itr}"
assert op_id > UNKNOWN_OP and op_id < TOTAL_MEM_OPS, f"{itr}"
memory_alloc_cnt[op_id]["count"] += 1
phase = itr.phase
@@ -243,20 +248,26 @@ def test_memory_alloc_sizes(input_data):
# 6 hsa_memory_allocation calls with 1024 bytes were called
# and 9 hsa_amd_memory_pool_allocations with 2048 bytes
# were called
assert memory_alloc_cnt[1]["count"] == 15
assert memory_alloc_cnt[3]["count"] == 15
# assert memory_alloc_cnt[3]["count"] == 3
assert len(memory_alloc_cnt[1]["starting_addr"]) == len(
memory_alloc_cnt[3]["starting_addr"]
)
assert memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["count"] == 15
assert memory_alloc_cnt[HSA_MEMORY_FREE_OP]["count"] == 15
# assert len(memory_alloc_cnt[3]["starting_addr"]) == 3
assert len(memory_alloc_cnt[1]["size"]) == 2
# assert len(memory_alloc_cnt[3]["size"]) == 1
assert 1024 in memory_alloc_cnt[1]["size"]
assert 2048 in memory_alloc_cnt[1]["size"]
assert len(memory_alloc_cnt[1]["agent"]) == 2
# assert len(memory_alloc_cnt[3]["agent"]) == 1
# Check that allocation operations have corresponding free operations
assert len(memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["starting_addr"]) == len(
memory_alloc_cnt[HSA_MEMORY_FREE_OP]["starting_addr"]
)
for starting_addr in memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["starting_addr"]:
assert starting_addr in memory_alloc_cnt[HSA_MEMORY_FREE_OP]["starting_addr"]
# Confirm validation sizes are valid
assert len(memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["size"]) == 2
assert (
len(memory_alloc_cnt[HSA_MEMORY_FREE_OP]["size"]) == 1
) # size for free ops are 0
assert 1024 in memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["size"]
assert 2048 in memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["size"]
# Confirm that two agents were used
assert len(memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["agent"]) == 2
def test_retired_correlation_ids(input_data):
+5 -2
ファイルの表示
@@ -21,7 +21,7 @@ add_test(
NAME rocprofv3-test-memory-allocation-tracing-execute
COMMAND
$<TARGET_FILE:rocprofiler-sdk::rocprofv3> --memory-allocation-trace -d
${CMAKE_CURRENT_BINARY_DIR}/%tag%-trace -o out --output-format json otf2
${CMAKE_CURRENT_BINARY_DIR}/%tag%-trace -o out --output-format json otf2 csv
--log-level env -- $<TARGET_FILE:hsa-memory-allocation>)
set_tests_properties(
@@ -36,7 +36,10 @@ add_test(
${Python3_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/validate.py --json-input
${CMAKE_CURRENT_BINARY_DIR}/hsa-memory-allocation-trace/out_results.json
--otf2-input
${CMAKE_CURRENT_BINARY_DIR}/hsa-memory-allocation-trace/out_results.otf2)
${CMAKE_CURRENT_BINARY_DIR}/hsa-memory-allocation-trace/out_results.otf2
--csv-input
${CMAKE_CURRENT_BINARY_DIR}/hsa-memory-allocation-trace/out_memory_allocation_trace.csv
)
set_tests_properties(
rocprofv3-test-memory-allocation-tracing-validate
+21 -1
ファイルの表示
@@ -22,6 +22,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import csv
import json
import os
import pytest
@@ -43,7 +44,13 @@ def pytest_addoption(parser):
"--otf2-input",
action="store",
default="memory-allocation-tracing/out_results.otf2",
help="Input JSON",
help="Input OTF2",
)
parser.addoption(
"--csv-input",
action="store",
default="memory-allocation-tracing/out_memory_allocation_trace.csv",
help="Input CSV",
)
@@ -60,3 +67,16 @@ def otf2_data(request):
if not os.path.exists(filename):
raise FileExistsError(f"{filename} does not exist")
return OTF2Reader(filename).read()[0]
@pytest.fixture
def csv_data(request):
filename = request.config.getoption("--csv-input")
data = []
if not os.path.isfile(filename):
raise FileExistsError(f"{filename} does not exist")
with open(filename, "r") as inp:
reader = csv.DictReader(inp)
for row in reader:
data.append(row)
return data
+137 -3
ファイルの表示
@@ -65,12 +65,23 @@ def test_memory_allocation(json_data):
HSA_AMD_VMEM_HANDLE_CREATE_OP = 2
HSA_MEMORY_FREE_OP = 3
HSA_AMD_VMEM_HANDLE_RELEASE = 4
TOTAL_MEM_OPS = 5
ALLOCATE_OPS = (HSA_MEMORY_ALLOCATE_OP, HSA_AMD_VMEM_HANDLE_CREATE_OP)
FREE_OPS = (HSA_MEMORY_FREE_OP, HSA_AMD_VMEM_HANDLE_RELEASE)
valid_agent_ids = set()
for row in data["agents"]:
if "id" in row and "handle" in row.id:
valid_agent_ids.add(row.id.handle)
memory_alloc_cnt = dict(
[
(idx, {"agent": set(), "starting_addr": set(), "size": set(), "count": 0})
for idx in range(1, TOTAL_MEM_OPS)
]
)
# check buffering data
for node in memory_allocation_data:
assert "size" in node
@@ -86,13 +97,20 @@ def test_memory_allocation(json_data):
assert "allocation_size" in node
assert node.size > 0
assert node.allocation_size >= 0
assert len(node.address) > 0
assert node.thread_id > 0
# Check that op ID is valid
op_id = node.operation
assert op_id != UNKNOWN_OP
if op_id == HSA_MEMORY_ALLOCATE_OP or op_id == HSA_AMD_VMEM_HANDLE_CREATE_OP:
assert op_id > UNKNOWN_OP and op_id < TOTAL_MEM_OPS
# Summarize info in dict
memory_alloc_cnt[op_id]["count"] += 1
memory_alloc_cnt[op_id]["starting_addr"].add(node.address)
memory_alloc_cnt[op_id]["size"].add(node.allocation_size)
memory_alloc_cnt[op_id]["agent"].add(node.agent_id.handle)
# Check if agent is valid
if op_id in ALLOCATE_OPS:
assert node.agent_id.handle in valid_agent_ids
else:
assert node.agent_id.handle == 0 # free ops record agent id as null
@@ -107,6 +125,31 @@ def test_memory_allocation(json_data):
in bf_op_names
)
# In the memory allocation test which generates this file
# 6 hsa_memory_allocation calls with 1024 bytes were called
# and 9 hsa_amd_memory_pool_allocations with 2048 bytes
# were called
assert memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["count"] == 15
assert memory_alloc_cnt[HSA_MEMORY_FREE_OP]["count"] == 15
# Check that allocation operations have corresponding free operations
assert len(memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["starting_addr"]) == len(
memory_alloc_cnt[HSA_MEMORY_FREE_OP]["starting_addr"]
)
for starting_addr in memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["starting_addr"]:
assert starting_addr in memory_alloc_cnt[HSA_MEMORY_FREE_OP]["starting_addr"]
# Confirm validation sizes are valid
assert len(memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["size"]) == 2
assert (
len(memory_alloc_cnt[HSA_MEMORY_FREE_OP]["size"]) == 1
) # size for free ops are 0
assert 1024 in memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["size"]
assert 2048 in memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["size"]
# Confirm that two agents were used
assert len(memory_alloc_cnt[HSA_MEMORY_ALLOCATE_OP]["agent"]) == 2
def test_otf2_data(otf2_data, json_data):
import rocprofiler_sdk.tests.rocprofv3 as rocprofv3
@@ -114,6 +157,97 @@ def test_otf2_data(otf2_data, json_data):
rocprofv3.test_otf2_data(otf2_data, json_data, ("memory_allocation",))
def test_csv_data(csv_data):
assert len(csv_data) > 0, "Expected non-empty csv data"
ALLOCATION_OPS = (
"MEMORY_ALLOCATION_ALLOCATE",
"ROCPROFILER_MEMORY_ALLOCATION_VMEM_ALLOCATE",
)
FREE_OPS = (
"ROCPROFILER_MEMORY_ALLOCATION_FREE",
"ROCPROFILER_MEMORY_ALLOCATION_VMEM_FREE",
)
memory_allocation_info = dict(
{
"agents": set(),
"allocation_size": defaultdict(int),
"address": defaultdict(lambda: defaultdict(int)),
}
)
for row in csv_data:
assert (
"Kind" in row
), "'Kind' was not present in csv data for memory-allocation-trace"
assert (
"Operation" in row
), "'Operation' was not present in csv data for memory-allocation-trace"
assert (
"Agent_Id" in row
), "'Agent_Id' was not present in csv data for memory-allocation-trace"
assert (
"Allocation_Size" in row
), "'Allocation_Size' was not present in csv data for memory-allocation-trace"
assert (
"Address" in row
), "'Address' was not present in csv data for memory-allocation-trace"
assert (
"Correlation_Id" in row
), "'Correlation_Id' was not present in csv data for memory-allocation-trace"
assert (
"Start_Timestamp" in row
), "'Start_Timestamp' was not present in csv data for memory-allocation-trace"
assert (
"End_Timestamp" in row
), "'End_Timestamp' was not present in csv data for memory-allocation-trace"
assert row["Kind"] == "MEMORY_ALLOCATION"
assert row["Operation"] in (
"MEMORY_ALLOCATION_ALLOCATE",
"MEMORY_ALLOCATION_FREE",
)
assert int(row["Correlation_Id"]) > 0
# Check if agent ID is assigned to correct row
if row["Operation"] in ALLOCATION_OPS:
assert row["Agent_Id"].split(" ")[0] == "Agent"
memory_allocation_info["agents"].add(row["Agent_Id"])
else:
assert row["Agent_Id"] == "" # free ops have no agent
# Confirm allocation size is valid
if row["Operation"] in ALLOCATION_OPS:
assert int(row["Allocation_Size"]) in (
1024,
2048,
) # Test allocates 1024 and 2048 bytes only
memory_allocation_info["allocation_size"][int(row["Allocation_Size"])] += 1
else:
row["Allocation_Size"] == 0 # Free ops record allocation size as 0
# Confirm address is valid
assert row["Address"][:2] == "0x"
address = int(row["Address"], 16)
if row["Operation"] in ALLOCATION_OPS:
memory_allocation_info["address"][address]["allocation"] += 1
else:
memory_allocation_info["address"][address]["free"] += 1
# Timestamp sanity check
assert int(row["Start_Timestamp"]) > 0
assert int(row["End_Timestamp"]) > 0
assert int(row["Start_Timestamp"]) < int(row["End_Timestamp"])
# Test uses 2 agents with 6 allocations of 1024 bytes and 9 allocations of 2048 bytes
assert len(memory_allocation_info["agents"]) == 2
assert memory_allocation_info["allocation_size"][1024] == 6
assert memory_allocation_info["allocation_size"][2048] == 9
for address in memory_allocation_info["address"].values():
assert (
address["allocation"] == address["free"]
) # Free should have corresponding allocate
if __name__ == "__main__":
exit_code = pytest.main(["-x", __file__] + sys.argv[1:])
sys.exit(exit_code)