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
このコミットが含まれているのは:
@@ -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
|
||||
|
||||
|
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする