Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 178 additions & 0 deletions thicket/compiler_static_info_reader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Copyright 2022 Lawrence Livermore National Security, LLC and other
# Thicket Project Developers. See the top-level LICENSE file for details.
#
# SPDX-License-Identifier: MIT
import os
import json
import math
from functools import lru_cache
from collections import defaultdict


class CompilerStaticInfoReader:
MAX_IR_METRICS = {"maxLiveSSAValues", "maxLoopDepth"}
SUM_KRU_METRICS = {"SGPRs Spill", "VGPRs Spill"}

def __init__(self, extraction_plugin_out_dir, trace_log_file):
self.extraction_plugin_out_dir = extraction_plugin_out_dir
self.trace_log_file = trace_log_file

def read_trace_log(self):
with open(self.trace_log_file, "r") as f:
for line in f:
line = line.strip()
if not line:
continue
try:
yield json.loads(line)
except json.JSONDecodeError:
continue

def build_path_to_node(self, graph):
path_to_node = {}

def dfs(node, path_parts, visited):
if node in visited:
return
visited.add(node)

name = node.frame["name"]
curr_path = path_parts + [name]
path_to_node["/".join(curr_path)] = node

for child in node.children:
dfs(child, curr_path, visited)

visited = set()
for root in graph.roots:
dfs(root, [], visited)

return path_to_node

@staticmethod
@lru_cache(maxsize=None)
def _load_module_functions_cached(extraction_plugin_out_dir, module_relative_path):
module_relative_path = module_relative_path.lstrip("/")
path = os.path.join(extraction_plugin_out_dir, module_relative_path)

if not os.path.isfile(path):
return {}

try:
with open(path, "r") as f:
return json.load(f).get("Functions", {})
except Exception:
return {}

def load_module_functions(self, module_relative_path):
return self._load_module_functions_cached(
self.extraction_plugin_out_dir,
module_relative_path,
)

def walk_call_tree(
self,
func_name,
module_relative_path,
ir_accum,
opt_accum,
visited,
):
key = (func_name, module_relative_path)
if key in visited:
return
visited.add(key)

entry = self.load_module_functions(module_relative_path).get(func_name)
if not entry:
return

for metric, value in entry.get("IRStatistics", {}).items():
if value is None:
continue
if metric in self.MAX_IR_METRICS:
ir_accum[metric] = max(ir_accum[metric], value)
else:
ir_accum[metric] += value

for metric, value in (
entry.get("RemarkInformation", {}).get("RemarkStatistics", {}).items()
):
if value is not None:
opt_accum[metric] += value

for callee in entry.get("CalledFunctions", []):
self.walk_call_tree(
callee,
module_relative_path,
ir_accum,
opt_accum,
visited,
)

def add_to_thicket(self, thicket):
region_index = self.build_path_to_node(thicket.graph)

region_roots = defaultdict(set)

for entry in self.read_trace_log():
region_path = entry.get("RegionPath")
func_name = entry.get("Function")
module_relative_path = entry.get("ModulePath")

if not region_path or not func_name or not module_relative_path:
continue

region_roots[region_path].add((func_name, module_relative_path))

for region_path, roots in region_roots.items():
th_node = region_index.get(region_path)
if th_node is None:
print(
f"CompilerStaticInfoReader: Missing region path in thicket: {region_path}"
)
continue

ir_accum = defaultdict(int)
opt_accum = defaultdict(int)
kru_sum = defaultdict(int)
kru_min = defaultdict(lambda: math.inf)
kru_max = defaultdict(lambda: -math.inf)

for func_name, module_relative_path in roots:
entry = self.load_module_functions(module_relative_path).get(func_name)
if not entry:
continue

# KRU: aggregate only root functions for this region
for metric, value in entry.get("KRUInformation", {}).items():
if value is None:
continue
if metric in self.SUM_KRU_METRICS:
kru_sum[f"{metric} (sum)"] += value
else:
kru_min[metric] = min(kru_min[metric], value)
kru_max[metric] = max(kru_max[metric], value)

# IR + OPT: aggregate over full reachable call tree
self.walk_call_tree(
func_name,
module_relative_path,
ir_accum,
opt_accum,
visited=set(),
)

for metric, value in ir_accum.items():
thicket.dataframe.loc[th_node, metric] = value

for metric, value in opt_accum.items():
thicket.dataframe.loc[th_node, metric] = value

for metric, value in kru_sum.items():
thicket.dataframe.loc[th_node, metric] = value

for metric in kru_min:
if kru_min[metric] != math.inf:
thicket.dataframe.loc[th_node, f"{metric} (min)"] = kru_min[metric]
thicket.dataframe.loc[th_node, f"{metric} (max)"] = kru_max[metric]
35 changes: 35 additions & 0 deletions thicket/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,41 @@ def rajaperf_unique_tunings(data_dir, tmpdir):
return [os.path.join(str(tmpdir), f) for f in cali_files]


@pytest.fixture
def rajaperf_hip_O2_512M_cali(data_dir, tmpdir):
"""All trials of for RAJA HIP optimization level O2 and total node problem size 536870912."""
cali_files = sorted(
glob(
f"{data_dir}/rajaperf-comp-static-data/tuolumne/runtime/O2/**/RAJA_HIP-block_256.cali",
recursive=True,
)
)
for cf in cali_files:
shutil.copy(cf, str(tmpdir))
return [os.path.join(str(tmpdir), f) for f in cali_files]


@pytest.fixture
def rajaperf_hip_O2_512M_compiler_static_info(data_dir, tmpdir):
"""Trace log and extraction plugin output for RAJA HIP at optimization level O2 and problem size 512M"""
trace_log_file = os.path.join(
data_dir,
"rajaperf-comp-static-data/tuolumne/llvm_pass_plugins/association/trace_log.jsonl",
)
extraction_out_path = os.path.join(
data_dir,
"rajaperf-comp-static-data/tuolumne/llvm_pass_plugins/extraction/extraction_plugin_output",
)

dest_log = os.path.join(str(tmpdir), os.path.basename(trace_log_file))
dest_dir = os.path.join(str(tmpdir), "extraction_plugin_output")

shutil.copy(trace_log_file, dest_log)
shutil.copytree(extraction_out_path, dest_dir)

return [dest_log, dest_dir]


@pytest.fixture
def caliper_ordered(data_dir, tmpdir):
"""Builds a temporary directory containing the lulesh cali file."""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{"Function":"void RAJA::policy::hip::impl::forallp_hip_kernel<RAJA::policy::hip::hip_exec<RAJA::iteration_mapping::Direct, RAJA::hip::IndexGlobal<(RAJA::named_dim)0, 256, 0>, RAJA::hip::AvoidDeviceMaxThreadOccupancyConcretizer<RAJA::hip::FractionOffsetOccupancyConcretizer<RAJA::Fraction<unsigned long, 1ul, 1ul>, -1l>>, true>, RAJA::Iterators::numeric_iterator<long, long, long*>, void rajaperf::stream::TRIAD::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(long), long, RAJA::expt::ForallParamPack<>, RAJA::iteration_mapping::Direct, RAJA::hip::IndexGlobal<(RAJA::named_dim)0, 256, 0>, 256ul>(void rajaperf::stream::TRIAD::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(long), RAJA::Iterators::numeric_iterator<long, long, long*>, long, RAJA::expt::ForallParamPack<>)","ModulePath":"/src/stream/TRIAD-Hip.cpp.device.json","RegionPath":"RAJAPerf/Stream/Stream_TRIAD"}
{"Function":"void RAJA::launch_new_reduce_global_fcn_fixed<void rajaperf::basic::MAT_MAT_SHARED::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(RAJA::LaunchContext), 256, RAJA::expt::ForallParamPack<>>(void rajaperf::basic::MAT_MAT_SHARED::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(RAJA::LaunchContext), RAJA::expt::ForallParamPack<>)","ModulePath":"/src/basic/MAT_MAT_SHARED-Hip.cpp.device.json","RegionPath":"RAJAPerf/Basic/Basic_MAT_MAT_SHARED"}
{"Function":"void RAJA::internal::HipKernelLauncherFixed<256, RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(long, long, double&)>, RAJA::internal::HipStatementListExecutor<RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(long, long, double&)>, camp::list<RAJA::statement::For<0l, RAJA::policy::hip::hip_indexer<RAJA::iteration_mapping::Direct, (RAJA::kernel_sync_requirement)0, RAJA::hip::IndexGlobal<(RAJA::named_dim)1, 8, 0>>, RAJA::statement::For<1l, RAJA::policy::hip::hip_indexer<RAJA::iteration_mapping::Direct, (RAJA::kernel_sync_requirement)0, RAJA::hip::IndexGlobal<(RAJA::named_dim)0, 32, 0>>, RAJA::statement::Lambda<0l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>, RAJA::statement::For<2l, RAJA::policy::sequential::seq_exec, RAJA::statement::Lambda<1l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 0l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 1l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 2l>>, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>>, RAJA::statement::Lambda<2l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 0l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 1l>>, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>>>>, RAJA::internal::LoopTypes<camp::list<void, void, void>, camp::list<void, void, void>>>>(RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda'(long, long, double&)>)","ModulePath":"/src/polybench/POLYBENCH_3MM-Hip.cpp.device.json","RegionPath":"RAJAPerf/Polybench/Polybench_3MM"}
{"Function":"void RAJA::internal::HipKernelLauncherFixed<256, RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(long, long, double&)>, RAJA::internal::HipStatementListExecutor<RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(long, long, double&)>, camp::list<RAJA::statement::For<0l, RAJA::policy::hip::hip_indexer<RAJA::iteration_mapping::Direct, (RAJA::kernel_sync_requirement)0, RAJA::hip::IndexGlobal<(RAJA::named_dim)1, 8, 0>>, RAJA::statement::For<1l, RAJA::policy::hip::hip_indexer<RAJA::iteration_mapping::Direct, (RAJA::kernel_sync_requirement)0, RAJA::hip::IndexGlobal<(RAJA::named_dim)0, 32, 0>>, RAJA::statement::Lambda<0l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>, RAJA::statement::For<2l, RAJA::policy::sequential::seq_exec, RAJA::statement::Lambda<1l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 0l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 1l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 2l>>, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>>, RAJA::statement::Lambda<2l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 0l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 1l>>, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>>>>, RAJA::internal::LoopTypes<camp::list<void, void, void>, camp::list<void, void, void>>>>(RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda0'(long, long, double&)>)","ModulePath":"/src/polybench/POLYBENCH_3MM-Hip.cpp.device.json","RegionPath":"RAJAPerf/Polybench/Polybench_3MM"}
{"Function":"void RAJA::internal::HipKernelLauncherFixed<256, RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(long, long, double&)>, RAJA::internal::HipStatementListExecutor<RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(long, long, double&)>, camp::list<RAJA::statement::For<0l, RAJA::policy::hip::hip_indexer<RAJA::iteration_mapping::Direct, (RAJA::kernel_sync_requirement)0, RAJA::hip::IndexGlobal<(RAJA::named_dim)1, 8, 0>>, RAJA::statement::For<1l, RAJA::policy::hip::hip_indexer<RAJA::iteration_mapping::Direct, (RAJA::kernel_sync_requirement)0, RAJA::hip::IndexGlobal<(RAJA::named_dim)0, 32, 0>>, RAJA::statement::Lambda<0l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>, RAJA::statement::For<2l, RAJA::policy::sequential::seq_exec, RAJA::statement::Lambda<1l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 0l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 1l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 2l>>, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>>, RAJA::statement::Lambda<2l, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 0l>, RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_seg_t, 1l>>, camp::list<RAJA::internal::LambdaArg<RAJA::internal::lambda_arg_param_t, 0l>>>>>>, RAJA::internal::LoopTypes<camp::list<void, void, void>, camp::list<void, void, void>>>>(RAJA::internal::LoopData<camp::tuple<RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>, RAJA::Span<RAJA::Iterators::numeric_iterator<long, long, long*>, long>>, camp::tuple<double>, camp::resources::v1::Hip, void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(long, long, long, double&), void rajaperf::polybench::POLYBENCH_3MM::runHipVariantImpl<256ul>(rajaperf::VariantID)::'lambda1'(long, long, double&)>)","ModulePath":"/src/polybench/POLYBENCH_3MM-Hip.cpp.device.json","RegionPath":"RAJAPerf/Polybench/Polybench_3MM"}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Loading
Loading