File size: 4,035 Bytes
d14fd4d f3b99fb d14fd4d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
import logging
import numpy as np
import plotly.graph_objects as go
import pytest
from .kernels.test_poly_norm_perf import PERF_RESULTS, PerfResult
logger = logging.getLogger(__name__)
DO_PLOT = False
def plot(perf_results: list[PerfResult]):
x_labels = [f"{r.type}, {r.shape}, {r.dtype}" for r in perf_results]
kernel_speedup = [r.speedup for r in perf_results]
torch_speedup = [1 for _ in perf_results]
geo_mean = float(np.exp(np.mean(np.log(kernel_speedup))))
x_labels.append("Geometric Mean")
kernel_speedup.append(geo_mean)
torch_speedup.append(1.0)
fig = go.Figure()
bar_width = 0.2
fig.add_trace(
go.Bar(
x=x_labels,
y=kernel_speedup,
name="Activation",
marker_color="rgb(100, 100, 100)",
text=[f"x{v:.2f}" for v in kernel_speedup],
textfont=dict(size=14),
textposition="outside",
# width=[bar_width] * len(x_labels),
)
)
fig.add_trace(
go.Bar(
x=x_labels,
y=torch_speedup,
name="Torch",
marker_color="rgb(30, 30, 30)",
text=[f"x{v:.2f}" for v in torch_speedup],
textfont=dict(size=14),
textposition="outside",
# width=[bar_width] * len(x_labels),
)
)
fig.update_layout(
title=dict(
text="<b>Speedup over torch (higher is better) (MI250, torch 2.7, ROCm 6.3)</b>",
font=dict(size=24),
),
legend=dict(
x=0.01,
y=0.99,
xanchor="left",
yanchor="top",
bgcolor="rgba(0,0,0,0)",
bordercolor="black",
borderwidth=1,
),
font=dict(size=16),
yaxis_title="Speedup (torch / activation)",
barmode="group",
bargroupgap=0,
bargap=0.2,
xaxis_tickangle=-45,
template="plotly_white",
yaxis_type="log",
shapes=[
dict(
type="rect",
xref="x",
yref="paper", # y축 전체 범위 (0~1)
x0=-0.5,
x1=len(x_labels) - 0.5,
y0=0,
y1=1,
line=dict(
color="black",
width=1.5,
),
fillcolor="rgba(0,0,0,0)", # 투명 배경
layer="above", # bar 아래에 그리기
)
],
)
output_file = "perf_result.html"
fig.write_html(output_file)
logger.info(f"Plotting performance results to {output_file}")
def pytest_addoption(parser):
parser.addoption(
"--run-perf", action="store_true", default=False, help="Run perf tests"
)
parser.addoption(
"--do-plot", action="store_true", default=False, help="Plot performance results"
)
@pytest.fixture
def do_plot(request):
return request.config.getoption("--do-plot")
def pytest_configure(config):
global DO_PLOT
DO_PLOT = config.getoption("--do-plot")
run_perf = config.getoption("--run-perf")
if DO_PLOT and not run_perf:
raise ValueError(
"Cannot plot performance results without running performance tests. "
"Please use --run-perf option."
)
config.addinivalue_line("markers", "perf: mark test as performance-related")
def pytest_collection_modifyitems(config, items):
run_perf = config.getoption("--run-perf")
skip_perf = pytest.mark.skip(reason="need --run-perf option to run")
skip_normal = pytest.mark.skip(
reason="normal tests skipped when --run-perf is used"
)
for item in items:
if "perf" in item.keywords and not run_perf:
item.add_marker(skip_perf)
elif "perf" not in item.keywords and run_perf:
item.add_marker(skip_normal)
def pytest_sessionfinish(session, exitstatus) -> None:
if DO_PLOT:
plot(PERF_RESULTS)
else:
logger.info(PERF_RESULTS)
|