From f32193e4ba44860552352288d80810ce4cd08a6e Mon Sep 17 00:00:00 2001 From: Amr Akmal Moustafa Abouelmagd Date: Wed, 11 Jun 2025 13:24:02 -0700 Subject: [PATCH 1/5] Modifications for standard configs json --- modifiers/hwloc/modifier.py | 38 +++++- modifiers/hwloc/parse_hwloc_output.py | 171 +++++++++++++++++++++++++- 2 files changed, 204 insertions(+), 5 deletions(-) diff --git a/modifiers/hwloc/modifier.py b/modifiers/hwloc/modifier.py index 9afdac731..41eec8c06 100644 --- a/modifiers/hwloc/modifier.py +++ b/modifiers/hwloc/modifier.py @@ -21,6 +21,30 @@ class Hwloc(BasicModifier): executable_modifier("hwloc") + def get_os_reserved_data(self, app_inst): + import json + + system_metadata = [ + "sys_cores_per_node", # required + "scheduler", # required + "rocm_arch", + "cuda_arch", + "sys_cores_os_reserved_per_node", + "sys_cores_os_reserved_per_node_list", + "sys_gpus_per_node", + "sys_mem_per_node", + "system_site", + ] + os_reserved_metadata = {} + print("app_inst.variables:", app_inst.variables.keys()) + for key in system_metadata: + # Certain keys not required or may not be present + if key in app_inst.variables.keys(): + os_reserved_metadata[key] = app_inst.variables[key] + + return f"'{json.dumps(os_reserved_metadata)}'" + + def hwloc(self, executable_name, executable, app_inst=None): import os from ramble.util.executable import CommandExecutable @@ -43,21 +67,31 @@ def hwloc(self, executable_name, executable, app_inst=None): CommandExecutable( "lstopo-to-get-underlying-infrastructure", template=[ - f"lstopo --of xml --whole-system --whole-io --verbose {hwloc_output_xml_file} 2> /dev/null" + f"(lstopo --of xml --whole-system --whole-io --verbose > {hwloc_output_xml_file} 2> /dev/null)" ], ) ) + # pre_exec.append( + # CommandExecutable( + # "lstopo-to-get-underlying-infrastructure", + # template=[ + # f"lstopo --of xml --whole-system --whole-io --verbose {hwloc_output_xml_file} 2> /dev/null" + # ], + # ) + # ) caliper_modifier = any( [modifier["name"] == "caliper" for modifier in app_inst.modifiers] ) if caliper_modifier: + os_reserved_metadata = self.get_os_reserved_data(app_inst) + print("os_reserved_metadata:", os_reserved_metadata) # Convert the .xml file from hwloc output to equivalent .json format pre_exec.append( CommandExecutable( "parse-lstopo-output", template=[ - f"python {hwloc_parser_dir}/parse_hwloc_output.py {hwloc_output_xml_file} {hwloc_output_json_file} {self._usage_mode}" + f"python {hwloc_parser_dir}/parse_hwloc_output.py {hwloc_output_xml_file} {hwloc_output_json_file} {self._usage_mode} {os_reserved_metadata}" ], ) ) diff --git a/modifiers/hwloc/parse_hwloc_output.py b/modifiers/hwloc/parse_hwloc_output.py index 0aea745bd..4790e4578 100644 --- a/modifiers/hwloc/parse_hwloc_output.py +++ b/modifiers/hwloc/parse_hwloc_output.py @@ -68,8 +68,163 @@ def clean_keys(d): else: return d +def extract_commons(shortened_dict): + result = {} -def parse_lstopo_summary(hwloc_xml_file_path, hwloc_output_json_file_path): + resource_fields = { + "L1Cache": ["cache_size", "cache_linesize", "cache_associativity", "cache_type"], + "L2Cache": ["cache_size", "cache_linesize", "cache_associativity", "cache_type"], + "L3Cache": ["cache_size", "cache_linesize", "cache_associativity", "cache_type"], + "NUMANode": ["local_memory"], + "Package": [], + "Core": [], + "Machine": ["OSName", "OSRelease", "OSVersion", "HostName", "Architecture"], + "OSDev": ["GPUVendor", "GPUModel", "RSMIVRAMSize", "RSMIVisibleVRAMSize", "subtype", "Backend"] + } + + # Fields that should be renamed to per_resource + per_resource_fields = {"local_memory", "cache_size", "cache_linesize", "RSMIVRAMSize", "RSMIVisibleVRAMSize"} + + def is_numeric(value): + """Check if a value can be converted to a number""" + if value is None: + return False + try: + float(str(value)) + return True + except (ValueError, TypeError): + return False + + def handle_inconsistent_values(values): + """Handle inconsistent values by providing min/max for numeric, list for strings""" + # Filter out None values + valid_values = [v for v in values if v is not None] + + if not valid_values: + return None + + if len(valid_values) == 1: + return valid_values[0] + + # Check if all values are numeric + numeric_values = [] + for val in valid_values: + if is_numeric(val): + # Convert to appropriate numeric type + try: + # Try int first, then float + if '.' not in str(val): + numeric_values.append(int(val)) + else: + numeric_values.append(float(val)) + except (ValueError, TypeError): + pass + + # If all values are numeric, return min/max + if len(numeric_values) == len(valid_values): + return { + "min": min(numeric_values), + "max": max(numeric_values) + } + + # For non-numeric or mixed values, return unique values as a list + unique_values = sorted(list(set(str(v) for v in valid_values))) + return unique_values + + def get_general_path(path): + """Convert specific path to general pattern""" + if not path: + return "" + + # Split path and remove instance numbers + parts = path.split("/") + general_parts = [] + + for part in parts: + if part: + # Remove instance numbers in brackets: "Machine[0]" -> "Machine" + general_part = part.split("[")[0] + general_parts.append(general_part) + + return "/".join(general_parts) + + for rtype, fields_to_check in resource_fields.items(): + if rtype == "OSDev": + # For OSDev, only include entries that have GPUVendor attribute + entries = [v for k, v in shortened_dict.items() + if v.get("type") == rtype and "GPUVendor" in v] + else: + entries = [v for k, v in shortened_dict.items() if v.get("type") == rtype] + + if not entries: + continue + + result[rtype] = {"count": len(entries)} + + # Add general path if available + if entries: + sample_path = entries[0].get("path", "") + general_path = get_general_path(sample_path) + if general_path: + result[rtype]["general_path"] = general_path + + for key in fields_to_check: + values = [entry.get(key) for entry in entries if key in entry] + + if not values: + continue + + # Get unique values + unique_values = set(values) + + # Determine the key name + if key in per_resource_fields: + result_key = f"{key}_per_resource" + else: + result_key = key + + if len(unique_values) == 1: + # All values are the same + result[rtype][result_key] = values[0] + else: + # Values are inconsistent - handle with min/max or list + result[rtype][result_key] = handle_inconsistent_values(unique_values) + + return result + + +# def extract_commons(shortened_dict): +# result = {} + +# resource_fields = { +# "L1Cache": ["cache_size", "cache_linesize"], +# "L2Cache": ["cache_size", "cache_linesize"], +# "L3Cache": ["cache_size", "cache_linesize"], +# "NUMANode": ["local_memory"], +# "Package": [], +# "Core": [], +# "Machine": ["OSName", "OSRelease", "OSVersion", "HostName", "Architecture"], +# "GPU": ["GPUVendor", "GPUModel", "RSMIVRAMSize", "RSMIVisibleVRAMSize"] +# } + +# for rtype, fields_to_check in resource_fields.items(): +# entries = [v for k, v in shortened_dict.items() if v.get("type") == rtype] +# if not entries: +# continue + +# result[rtype] = {"count": len(entries)} + +# for key in fields_to_check: +# values = {entry.get(key) for entry in entries if key in entry} +# if len(values) == 1: +# result[rtype][key] = values.pop() +# else: +# result[rtype][key] = "error" + +# return result + + +def parse_lstopo_summary(hwloc_xml_file_path, hwloc_output_json_file_path, os_reserved_metadata): try: with open(hwloc_xml_file_path, "r") as xml_file: lines = xml_file.readlines() @@ -99,7 +254,14 @@ def parse_lstopo_summary(hwloc_xml_file_path, hwloc_output_json_file_path): metadata_with_path["path"] = "/".join(prefix) shortened_dict[final_key] = metadata_with_path - # 4) Persist the json + # 4) Add resource summaries directly at top level + resource_summaries = extract_commons(shortened_dict) + shortened_dict.update(resource_summaries) + + # 5) Add os-reserved key_value pairs + shortened_dict.update(os_reserved_metadata) + + # 6) Persist the json with open(hwloc_output_json_file_path, "w") as f: json.dump(shortened_dict, f, indent=2) @@ -116,7 +278,10 @@ def parse_lstopo_summary(hwloc_xml_file_path, hwloc_output_json_file_path): "hwloc_json_log_file", type=str, help="hwloc output in json format" ) parser.add_argument("mode", type=str, help="hwloc mode(text)") + parser.add_argument("os_reserved", type=str, help="hwloc mode(text)") args = parser.parse_args() - parse_lstopo_summary(args.hwloc_xml_log_file, args.hwloc_json_log_file) + print("os_reserved:", ) + + parse_lstopo_summary(args.hwloc_xml_log_file, args.hwloc_json_log_file, json.loads(args.os_reserved)) From 53f12d06547111b651e5a0b77e47b39b07b8233b Mon Sep 17 00:00:00 2001 From: Amr Akmal Moustafa Abouelmagd Date: Mon, 28 Jul 2025 15:57:31 -0700 Subject: [PATCH 2/5] Code cleaning --- modifiers/hwloc/modifier.py | 10 -------- modifiers/hwloc/parse_hwloc_output.py | 35 +-------------------------- 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/modifiers/hwloc/modifier.py b/modifiers/hwloc/modifier.py index a4b28e285..fa9b75090 100644 --- a/modifiers/hwloc/modifier.py +++ b/modifiers/hwloc/modifier.py @@ -71,22 +71,12 @@ def hwloc(self, executable_name, executable, app_inst=None): ], ) ) - # pre_exec.append( - # CommandExecutable( - # "lstopo-to-get-underlying-infrastructure", - # template=[ - # f"lstopo --of xml --whole-system --whole-io --verbose {hwloc_output_xml_file} 2> /dev/null" - # ], - # ) - # ) caliper_modifier = any( [modifier["name"] == "caliper" for modifier in app_inst.modifiers] ) if caliper_modifier: os_reserved_metadata = self.get_os_reserved_data(app_inst) - # print("os_reserved_metadata:", os_reserved_metadata) - # Convert the .xml file from hwloc output to equivalent .json format pre_exec.append( CommandExecutable( "parse-lstopo-output", diff --git a/modifiers/hwloc/parse_hwloc_output.py b/modifiers/hwloc/parse_hwloc_output.py index 4790e4578..d44519901 100644 --- a/modifiers/hwloc/parse_hwloc_output.py +++ b/modifiers/hwloc/parse_hwloc_output.py @@ -193,37 +193,6 @@ def get_general_path(path): return result -# def extract_commons(shortened_dict): -# result = {} - -# resource_fields = { -# "L1Cache": ["cache_size", "cache_linesize"], -# "L2Cache": ["cache_size", "cache_linesize"], -# "L3Cache": ["cache_size", "cache_linesize"], -# "NUMANode": ["local_memory"], -# "Package": [], -# "Core": [], -# "Machine": ["OSName", "OSRelease", "OSVersion", "HostName", "Architecture"], -# "GPU": ["GPUVendor", "GPUModel", "RSMIVRAMSize", "RSMIVisibleVRAMSize"] -# } - -# for rtype, fields_to_check in resource_fields.items(): -# entries = [v for k, v in shortened_dict.items() if v.get("type") == rtype] -# if not entries: -# continue - -# result[rtype] = {"count": len(entries)} - -# for key in fields_to_check: -# values = {entry.get(key) for entry in entries if key in entry} -# if len(values) == 1: -# result[rtype][key] = values.pop() -# else: -# result[rtype][key] = "error" - -# return result - - def parse_lstopo_summary(hwloc_xml_file_path, hwloc_output_json_file_path, os_reserved_metadata): try: with open(hwloc_xml_file_path, "r") as xml_file: @@ -278,10 +247,8 @@ def parse_lstopo_summary(hwloc_xml_file_path, hwloc_output_json_file_path, os_re "hwloc_json_log_file", type=str, help="hwloc output in json format" ) parser.add_argument("mode", type=str, help="hwloc mode(text)") - parser.add_argument("os_reserved", type=str, help="hwloc mode(text)") + parser.add_argument("os_reserved", type=str, help="machine os_reserved information") args = parser.parse_args() - print("os_reserved:", ) - parse_lstopo_summary(args.hwloc_xml_log_file, args.hwloc_json_log_file, json.loads(args.os_reserved)) From b3c9ff77116c6ac62ab0755f4f1b5f028d963f83 Mon Sep 17 00:00:00 2001 From: Amr Akmal Moustafa Abouelmagd Date: Wed, 30 Jul 2025 07:02:00 -0700 Subject: [PATCH 3/5] Code cleaning --- lib/benchpark/experiment.py | 27 ++++++++++++--------------- modifiers/hwloc/modifier.py | 6 +++--- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/benchpark/experiment.py b/lib/benchpark/experiment.py index c44621cf4..b69010d1e 100644 --- a/lib/benchpark/experiment.py +++ b/lib/benchpark/experiment.py @@ -143,32 +143,29 @@ def compute_package_section(self): "environments": {"affinity": {"packages": list(package_specs.keys())}}, } - -class HwlocVariantValues(str, Enum): - NONE = "none" - ON = "on" - - class Hwloc: variant( "hwloc", - default=HwlocVariantValues.NONE.value, - values=tuple(v.value for v in HwlocVariantValues), + default="none", + values=( + "none", + "on", + ), multi=False, description="Get underlying infrastructure topology", ) class Helper(ExperimentHelper): def compute_modifiers_section(self): - modifier_list = [] + hwloc_modifier_list = [] - if not self.spec.satisfies(f"hwloc={HwlocVariantValues.NONE.value}"): - affinity_modifier_modes = {} - affinity_modifier_modes["name"] = "hwloc" - affinity_modifier_modes["mode"] = self.spec.variants["hwloc"][0] - modifier_list.append(affinity_modifier_modes) + if not self.spec.satisfies(f"hwloc=none"): + hwloc_modifier_modes = {} + hwloc_modifier_modes["name"] = "hwloc" + hwloc_modifier_modes["mode"] = self.spec.variants["hwloc"][0] + hwloc_modifier_list.append(hwloc_modifier_modes) - return modifier_list + return hwloc_modifier_list class Experiment(ExperimentSystemBase, SingleNode, Affinity, Hwloc): diff --git a/modifiers/hwloc/modifier.py b/modifiers/hwloc/modifier.py index fa9b75090..3ae27e8dc 100644 --- a/modifiers/hwloc/modifier.py +++ b/modifiers/hwloc/modifier.py @@ -8,7 +8,7 @@ class Hwloc(BasicModifier): - """Define a modifier for showing the underlying infrastructure topology""" + """Define a modifier for showing the hardware architecture""" name = "hwloc" @@ -36,7 +36,7 @@ def get_os_reserved_data(self, app_inst): "system_site", ] os_reserved_metadata = {} - # print("app_inst.variables:", app_inst.variables.keys()) + for key in system_metadata: # Certain keys not required or may not be present if key in app_inst.variables.keys(): @@ -65,7 +65,7 @@ def hwloc(self, executable_name, executable, app_inst=None): # Run the hwloc tool and save its output in XML format to a file pre_exec.append( CommandExecutable( - "lstopo-to-get-underlying-infrastructure", + "lstopo-to-get-hardware-architecture", template=[ f"(lstopo --of xml --whole-system --whole-io --verbose > {hwloc_output_xml_file} 2> /dev/null)" ], From e36eca861dec1655b67a2966bf9c21efe982b7fe Mon Sep 17 00:00:00 2001 From: Amr Akmal Moustafa Abouelmagd Date: Wed, 30 Jul 2025 16:53:13 -0700 Subject: [PATCH 4/5] Fix linting --- lib/benchpark/experiment.py | 4 +- modifiers/hwloc/modifier.py | 3 +- modifiers/hwloc/parse_hwloc_output.py | 89 ++++++++++++++++++--------- 3 files changed, 64 insertions(+), 32 deletions(-) diff --git a/lib/benchpark/experiment.py b/lib/benchpark/experiment.py index b69010d1e..66d9ec7a6 100644 --- a/lib/benchpark/experiment.py +++ b/lib/benchpark/experiment.py @@ -6,7 +6,6 @@ from typing import Dict import yaml # TODO: some way to ensure yaml available import sys -from enum import Enum from benchpark.error import BenchparkError from benchpark.directives import ExperimentSystemBase @@ -143,6 +142,7 @@ def compute_package_section(self): "environments": {"affinity": {"packages": list(package_specs.keys())}}, } + class Hwloc: variant( "hwloc", @@ -159,7 +159,7 @@ class Helper(ExperimentHelper): def compute_modifiers_section(self): hwloc_modifier_list = [] - if not self.spec.satisfies(f"hwloc=none"): + if not self.spec.satisfies("hwloc=none"): hwloc_modifier_modes = {} hwloc_modifier_modes["name"] = "hwloc" hwloc_modifier_modes["mode"] = self.spec.variants["hwloc"][0] diff --git a/modifiers/hwloc/modifier.py b/modifiers/hwloc/modifier.py index 3ae27e8dc..afaa05598 100644 --- a/modifiers/hwloc/modifier.py +++ b/modifiers/hwloc/modifier.py @@ -41,9 +41,8 @@ def get_os_reserved_data(self, app_inst): # Certain keys not required or may not be present if key in app_inst.variables.keys(): os_reserved_metadata[key] = app_inst.variables[key] - - return f"'{json.dumps(os_reserved_metadata)}'" + return f"'{json.dumps(os_reserved_metadata)}'" def hwloc(self, executable_name, executable, app_inst=None): import os diff --git a/modifiers/hwloc/parse_hwloc_output.py b/modifiers/hwloc/parse_hwloc_output.py index d44519901..29b9befb4 100644 --- a/modifiers/hwloc/parse_hwloc_output.py +++ b/modifiers/hwloc/parse_hwloc_output.py @@ -68,22 +68,51 @@ def clean_keys(d): else: return d + def extract_commons(shortened_dict): result = {} resource_fields = { - "L1Cache": ["cache_size", "cache_linesize", "cache_associativity", "cache_type"], - "L2Cache": ["cache_size", "cache_linesize", "cache_associativity", "cache_type"], - "L3Cache": ["cache_size", "cache_linesize", "cache_associativity", "cache_type"], + "L1Cache": [ + "cache_size", + "cache_linesize", + "cache_associativity", + "cache_type", + ], + "L2Cache": [ + "cache_size", + "cache_linesize", + "cache_associativity", + "cache_type", + ], + "L3Cache": [ + "cache_size", + "cache_linesize", + "cache_associativity", + "cache_type", + ], "NUMANode": ["local_memory"], "Package": [], "Core": [], "Machine": ["OSName", "OSRelease", "OSVersion", "HostName", "Architecture"], - "OSDev": ["GPUVendor", "GPUModel", "RSMIVRAMSize", "RSMIVisibleVRAMSize", "subtype", "Backend"] + "OSDev": [ + "GPUVendor", + "GPUModel", + "RSMIVRAMSize", + "RSMIVisibleVRAMSize", + "subtype", + "Backend", + ], } # Fields that should be renamed to per_resource - per_resource_fields = {"local_memory", "cache_size", "cache_linesize", "RSMIVRAMSize", "RSMIVisibleVRAMSize"} + per_resource_fields = { + "local_memory", + "cache_size", + "cache_linesize", + "RSMIVRAMSize", + "RSMIVisibleVRAMSize", + } def is_numeric(value): """Check if a value can be converted to a number""" @@ -99,13 +128,13 @@ def handle_inconsistent_values(values): """Handle inconsistent values by providing min/max for numeric, list for strings""" # Filter out None values valid_values = [v for v in values if v is not None] - + if not valid_values: return None - + if len(valid_values) == 1: return valid_values[0] - + # Check if all values are numeric numeric_values = [] for val in valid_values: @@ -113,20 +142,17 @@ def handle_inconsistent_values(values): # Convert to appropriate numeric type try: # Try int first, then float - if '.' not in str(val): + if "." not in str(val): numeric_values.append(int(val)) else: numeric_values.append(float(val)) except (ValueError, TypeError): pass - + # If all values are numeric, return min/max if len(numeric_values) == len(valid_values): - return { - "min": min(numeric_values), - "max": max(numeric_values) - } - + return {"min": min(numeric_values), "max": max(numeric_values)} + # For non-numeric or mixed values, return unique values as a list unique_values = sorted(list(set(str(v) for v in valid_values))) return unique_values @@ -135,32 +161,35 @@ def get_general_path(path): """Convert specific path to general pattern""" if not path: return "" - + # Split path and remove instance numbers parts = path.split("/") general_parts = [] - + for part in parts: if part: # Remove instance numbers in brackets: "Machine[0]" -> "Machine" general_part = part.split("[")[0] general_parts.append(general_part) - + return "/".join(general_parts) for rtype, fields_to_check in resource_fields.items(): if rtype == "OSDev": # For OSDev, only include entries that have GPUVendor attribute - entries = [v for k, v in shortened_dict.items() - if v.get("type") == rtype and "GPUVendor" in v] + entries = [ + v + for k, v in shortened_dict.items() + if v.get("type") == rtype and "GPUVendor" in v + ] else: entries = [v for k, v in shortened_dict.items() if v.get("type") == rtype] - + if not entries: continue result[rtype] = {"count": len(entries)} - + # Add general path if available if entries: sample_path = entries[0].get("path", "") @@ -170,19 +199,19 @@ def get_general_path(path): for key in fields_to_check: values = [entry.get(key) for entry in entries if key in entry] - + if not values: continue - + # Get unique values unique_values = set(values) - + # Determine the key name if key in per_resource_fields: result_key = f"{key}_per_resource" else: result_key = key - + if len(unique_values) == 1: # All values are the same result[rtype][result_key] = values[0] @@ -193,7 +222,9 @@ def get_general_path(path): return result -def parse_lstopo_summary(hwloc_xml_file_path, hwloc_output_json_file_path, os_reserved_metadata): +def parse_lstopo_summary( + hwloc_xml_file_path, hwloc_output_json_file_path, os_reserved_metadata +): try: with open(hwloc_xml_file_path, "r") as xml_file: lines = xml_file.readlines() @@ -251,4 +282,6 @@ def parse_lstopo_summary(hwloc_xml_file_path, hwloc_output_json_file_path, os_re args = parser.parse_args() - parse_lstopo_summary(args.hwloc_xml_log_file, args.hwloc_json_log_file, json.loads(args.os_reserved)) + parse_lstopo_summary( + args.hwloc_xml_log_file, args.hwloc_json_log_file, json.loads(args.os_reserved) + ) From b5a1d30be52e5be647d47d39400be10e9c324d58 Mon Sep 17 00:00:00 2001 From: Amr Akmal Moustafa Abouelmagd Date: Mon, 4 Aug 2025 06:52:02 -0700 Subject: [PATCH 5/5] SELF --- experiments/raja-perf/experiment.py | 12 ++++++++++-- repo/raja-perf/application.py | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/experiments/raja-perf/experiment.py b/experiments/raja-perf/experiment.py index ea7b373a3..1c1088004 100644 --- a/experiments/raja-perf/experiment.py +++ b/experiments/raja-perf/experiment.py @@ -53,8 +53,16 @@ def compute_applications_section(self): f"Only one type of scaling per experiment is allowed for application package {self.name}" ) - n_resources = {"n_ranks": 1} - problem_sizes = {"size": 1048576} + # n_resources = {"n_ranks": 1} + # problem_sizes = {"size": 1048576} + + ###### + factor = 6 + scale = 4 * factor + init_problem_size = 536870912 + n_resources = {"n_ranks": scale} + problem_sizes = {"size": init_problem_size // scale} + ###### if self.spec.satisfies("+single_node"): for pk, pv in n_resources.items(): diff --git a/repo/raja-perf/application.py b/repo/raja-perf/application.py index 5869088af..656ac94a7 100644 --- a/repo/raja-perf/application.py +++ b/repo/raja-perf/application.py @@ -18,7 +18,7 @@ class RajaPerf(ExecutableApplication): 'mpi','network-point-to-point','network-latency-bound', 'c++','raja','sycl','builtin-caliper'] - executable('run', 'raja-perf.exe --size {size} -atsc ${CALI_CONFIG_MODE} -atcc ${OTHER_CALI_CONFIG}', use_mpi=True) + executable('run', 'raja-perf.exe --size {size} -v RAJA_HIP -t block_256 --kernels Polybench_JACOBI_1D --disable-warmup --npasses 5 -atsc ${CALI_CONFIG_MODE} -atcc ${OTHER_CALI_CONFIG}', use_mpi=True) workload('suite', executables=['run'])