Skip to content
Open
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
51 changes: 40 additions & 11 deletions mlir/utils/performance/perfRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,31 @@ def inverse_filter_layouts(filter_layout):
return "".join(map[char] for char in filter_layout)


# Map rocMLIR-specific layout names to MIOpenDriver layout names (NCHW, NHWC).
# MIOpenDriver does not accept rocMLIR layout names (e.g. GNC01, NGC01).
ROCMLIR_TO_MIOPEN_LAYOUT = {
'GNC01': 'NCHW',
'NGC01': 'NCHW',
'NC0G1': 'NCHW',
'G0NC1': 'NCHW',
'01NGC': 'NHWC',
'N01GC': 'NHWC',
'N01GK': 'NHWC',
'NCHW': 'NCHW',
'NHWC': 'NHWC',
}
Comment on lines +100 to +110
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be worth adding a comment (or an assert / logging.warning) for the fall-through case. Right now .get(layout, layout) silently passes through any unrecognised layout unchanged — which means a new rocMLIR layout name that's missing from this table will produce an 'Invalid Layout' error in MIOpenDriver that is hard to trace back here.

A lightweight safeguard:

def conv_commandline_to_miopen_layouts(commandline):
    ...
    if result[i] in layout_flags:
        layout = result[i + 1]
        translated = ROCMLIR_TO_MIOPEN_LAYOUT.get(layout)
        if translated is None:
            print(f"Warning: unknown rocMLIR layout '{layout}' passed through untranslated")
            translated = layout
        result[i + 1] = translated

Alternatively, document that ROCMLIR_TO_MIOPEN_LAYOUT is expected to be exhaustive and add a regression test covering any new layout names that arise.



def conv_commandline_to_miopen_layouts(commandline):
"""Return a copy of commandline with -f, -I, -O layout values translated to MIOpen names."""
result = list(commandline)
for i in range(len(result)):
if result[i] in ('-f', '-I', '-O') and i + 1 < len(result):
layout = result[i + 1]
result[i + 1] = ROCMLIR_TO_MIOPEN_LAYOUT.get(layout, layout)
Comment on lines +116 to +119
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three if/elif branches are identical except for the flag name. You can collapse them into a single check with a set, which also makes it easy to add more layout flags in the future:

def conv_commandline_to_miopen_layouts(commandline):
    """Return a copy of commandline with -f, -I, -O layout values translated to MIOpen names."""
    result = list(commandline)
    layout_flags = {'-f', '-I', '-O'}
    for i in range(len(result) - 1):
        if result[i] in layout_flags:
            result[i + 1] = ROCMLIR_TO_MIOPEN_LAYOUT.get(result[i + 1], result[i + 1])
    return result

Also note that iterating range(len(result) - 1) removes the need for the repeated i + 1 < len(result) guard.

return result


@dataclass
class MLIRPaths:
rocmlir_gen_path: str
Expand Down Expand Up @@ -694,20 +719,24 @@ def benchmark_external(cls, commandline, paths: Paths, arch, num_cu, num_chiplet
if os.path.exists(get_profiler_output_path(arch, BENCHMARKING_METRICS_FILE_NAME)):
os.remove(get_profiler_output_path(arch, BENCHMARKING_METRICS_FILE_NAME))
config = cls.from_command_line(commandline, arch, num_cu, num_chiplets)
miopen_driver_cmd = [MIOPENDRIVER, *commandline, '-V', '0', '-t', '1']
# Configs use rocMLIR layout names; MIOpenDriver expects NCHW/NHWC.
miopen_commandline = conv_commandline_to_miopen_layouts(commandline)
miopen_driver_cmd = [MIOPENDRIVER, *miopen_commandline, '-V', '0', '-t', '1']
print("Running MIOpen Benchmark: ", ' '.join(commandline))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The print still shows commandline (the original rocMLIR layout names) while the actual MIOpenDriver call uses miopen_commandline (with translated names). If a benchmark fails and someone tries to reproduce it by copy-pasting this line, they'll get the untranslated command and hit the same 'Invalid Layout' error all over again. Consider printing miopen_commandline instead, or at least the full miopen_driver_cmd:

print("Running MIOpen Benchmark: ", ' '.join(miopen_driver_cmd))

# invoke MIOpenDriver.
outs, noerr = run_pipeline([miopen_driver_cmd])
nanoseconds = np.nan
if noerr:
# convert bytes to str
outs = outs.decode('utf-8')
# Extract Elapsed time in ms from the output of MIOpenDriver
# Use regular expression to match the contents between
# "Elasped: " (note the space at the end) and "ms"
elapsed_time_in_ms = ELAPSED_TIME_RE.search(outs).group(1)
nanoseconds = float(elapsed_time_in_ms) * 1.0e6

if not noerr:
err_msg = outs.decode('utf-8') if isinstance(outs, bytes) else str(outs)
raise RuntimeError("MIOpen benchmark failed. CI must fail on MIOpen errors.\n"
"Failing command: " + ' '.join(miopen_driver_cmd) + "\n"
"Error: " + err_msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The yapf formatter requires this raise RuntimeError(...) to have the first argument on the same line as the opening parenthesis, with continuation lines aligned beneath it. The original multi-line style (opening paren on its own line) fails the yapf --diff check in CI.

Fixed format:

raise RuntimeError("MIOpen benchmark failed. CI must fail on MIOpen errors.
"
                   "Failing command: " + ' '.join(miopen_driver_cmd) + "
"
                   "Error: " + err_msg)

# convert bytes to str
outs = outs.decode('utf-8')
# Extract Elapsed time in ms from the output of MIOpenDriver
# Use regular expression to match the contents between
# "Elasped: " (note the space at the end) and "ms"
elapsed_time_in_ms = ELAPSED_TIME_RE.search(outs).group(1)
nanoseconds = float(elapsed_time_in_ms) * 1.0e6
return config.table_entry(nanoseconds)


Expand Down
Loading