Skip to content

Commit c2f68ef

Browse files
authored
Merge d1f46da into 0d542c3
2 parents 0d542c3 + d1f46da commit c2f68ef

File tree

10 files changed

+947
-37
lines changed

10 files changed

+947
-37
lines changed

aie_kernels/aie2p/softmax.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <aie_api/aie.hpp>
55
#include <stdint.h>
6+
#include <math.h>
67

78
#define SM_VEC_LEN 64 // 32
89
#define log2e 1.4453125 // 1.44269504089
@@ -30,7 +31,7 @@ void softmax_simple_bf16(bfloat16 *restrict input_vector, bfloat16 *restrict out
3031
aie::vector<bfloat16, SM_VEC_LEN> in_elems, exp_val, input_bf16, log2e_vec, max_val_vec;
3132
aie::accum<accfloat, SM_VEC_LEN> out_vals, exp_val_accum, scaled_accum, exp_in_accum;
3233

33-
float max_val = 0;
34+
float max_val = -INFINITY;
3435
float accum_exp_val = 0;
3536
float running_max = 0;
3637
bfloat16 col_sum_inv;

conftest.py

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ def __init__(self, csv_path):
5959
self.commit = get_git_commit()
6060
self.date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
6161
self.test_metrics = {} # test_name -> {metric_name -> [values]}
62+
self._initialize_csv()
63+
64+
def _initialize_csv(self):
65+
"""Initialize CSV file - will be written incrementally as tests complete"""
66+
self.csv_path.parent.mkdir(parents=True, exist_ok=True)
67+
# Clear the file at the start of a new test run
68+
with open(self.csv_path, "w", newline="") as f:
69+
pass # Create empty file, header will be written with first result
6270

6371
def add_result(self, test_name, passed, captured_output, metric_patterns):
6472
self.test_metrics.setdefault(test_name, {}).setdefault("passed", []).append(
@@ -72,40 +80,70 @@ def add_result(self, test_name, passed, captured_output, metric_patterns):
7280
value = float(match.group("value"))
7381
self.test_metrics[test_name].setdefault(metric_name, []).append(value)
7482

75-
def finalize_results(self):
76-
"""Compute statistics for all collected metrics"""
77-
for test_name, data in self.test_metrics.items():
78-
row = {
79-
"Commit": self.commit,
80-
"Date": self.date,
81-
"Test": test_name,
82-
"Checks": f"{sum(data['passed'])}/{len(data['passed'])}",
83-
}
84-
for metric_name, values in data.items():
85-
if metric_name == "passed":
86-
continue
87-
if values:
88-
row[f"{metric_name} (mean)"] = statistics.mean(values)
89-
row[f"{metric_name} (median)"] = statistics.median(values)
90-
row[f"{metric_name} (min)"] = min(values)
91-
row[f"{metric_name} (max)"] = max(values)
92-
row[f"{metric_name} (stddev)"] = (
93-
statistics.stdev(values) if len(values) > 1 else 0.0
94-
)
83+
def _compute_row(self, test_name, data):
84+
"""Compute statistics row for a single test"""
85+
row = {
86+
"Commit": self.commit,
87+
"Date": self.date,
88+
"Test": test_name,
89+
"Checks": f"{sum(data['passed'])}/{len(data['passed'])}",
90+
}
91+
for metric_name, values in data.items():
92+
if metric_name == "passed":
93+
continue
94+
if values:
95+
row[f"{metric_name} (mean)"] = statistics.mean(values)
96+
row[f"{metric_name} (median)"] = statistics.median(values)
97+
row[f"{metric_name} (min)"] = min(values)
98+
row[f"{metric_name} (max)"] = max(values)
99+
row[f"{metric_name} (stddev)"] = (
100+
statistics.stdev(values) if len(values) > 1 else 0.0
101+
)
102+
return row
103+
104+
def write_test_result(self, test_name):
105+
"""Write or update result for a specific test incrementally"""
106+
if test_name not in self.test_metrics:
107+
return
108+
109+
data = self.test_metrics[test_name]
110+
row = self._compute_row(test_name, data)
111+
112+
# Update or add to results
113+
existing_idx = None
114+
for idx, existing_row in enumerate(self.results):
115+
if existing_row["Test"] == test_name:
116+
existing_idx = idx
117+
break
118+
119+
if existing_idx is not None:
120+
self.results[existing_idx] = row
121+
else:
95122
self.results.append(row)
96123

97-
def write_csv(self):
98-
self.results.sort(key=lambda x: (x["Test"], x["Date"]))
124+
# Rewrite entire CSV to handle column changes and updates
125+
self._write_csv_internal()
126+
127+
def _write_csv_internal(self):
128+
"""Internal method to write CSV file"""
129+
if not self.results:
130+
return
131+
132+
sorted_results = sorted(self.results, key=lambda x: (x["Test"], x["Date"]))
99133

100134
cols = {}
101-
for row in self.results:
135+
for row in sorted_results:
102136
cols.update({k: None for k in row.keys()})
103137

104138
self.csv_path.parent.mkdir(parents=True, exist_ok=True)
105139
with open(self.csv_path, "w", newline="") as f:
106140
writer = csv.DictWriter(f, cols.keys())
107141
writer.writeheader()
108-
writer.writerows(self.results)
142+
writer.writerows(sorted_results)
143+
144+
def write_csv(self):
145+
"""Final write at session end - ensures all results are flushed"""
146+
self._write_csv_internal()
109147

110148

111149
# Initialize the CSV writer once at test session setup
@@ -147,6 +185,9 @@ def pytest_runtest_makereport(item, call):
147185

148186
csv_reporter.add_result(test_name, passed, captured, metric_patterns)
149187

188+
# Write results incrementally after each test
189+
csv_reporter.write_test_result(test_name)
190+
150191

151192
def pytest_configure(config):
152193
csv_path = config.getoption("--csv-output")
@@ -170,7 +211,6 @@ def pytest_collection_modifyitems(config, items):
170211

171212
def pytest_sessionfinish(session, exitstatus):
172213
if hasattr(session.config, "_csv_reporter"):
173-
session.config._csv_reporter.finalize_results()
174214
session.config._csv_reporter.write_csv()
175215

176216

iron/common/compilation/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ def compile(self, graph):
502502
str(self.aiecc_path),
503503
"-v",
504504
"-j1",
505+
"--dynamic-objFifos",
505506
"--no-compile-host",
506507
"--no-xchesscc",
507508
"--no-xbridge",

iron/common/fusion.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import ml_dtypes
66
import pyxrt
77
import ctypes
8+
import time
89
from . import compilation as comp
910
from .base import AIEOperatorBase, MLIROperator
1011
from .utils import XRTSubBuffer
@@ -42,8 +43,7 @@ def get_kernel_artifacts(self):
4243
"""Collect all kernel artifacts from child operators.
4344
4445
Returns:
45-
List of KernelObjectArtifact instances from all unique child operators,
46-
with filenames and symbol prefixes disambiguated per operator index.
46+
List of KernelObjectArtifact instances from all unique child operators.
4747
"""
4848
kernel_artifacts = []
4949
seen: dict[int, object] = {}
@@ -52,9 +52,6 @@ def get_kernel_artifacts(self):
5252
]
5353
for idx, op in enumerate(unique_operators):
5454
objs = op.get_kernel_artifacts()
55-
for obj in objs:
56-
obj.filename = f"op{idx}_{obj.filename}"
57-
obj.prefix_symbols = f"op{idx}_"
5855
kernel_artifacts.extend(objs)
5956
return kernel_artifacts
6057

@@ -82,8 +79,6 @@ def get_mlir_artifact(self):
8279
]
8380
for idx, op in enumerate(unique_operators):
8481
mlir_artifact = op.get_mlir_artifact()
85-
if len(op.get_kernel_artifacts()) > 0:
86-
mlir_artifact.generator.kwargs["func_prefix"] = f"op{idx}_"
8782
op_name = f"op{idx}_{op.__class__.__name__}"
8883
op_names[id(op)] = op_name
8984
operator_mlir_map[op_name] = mlir_artifact
@@ -290,8 +285,10 @@ def __call__(self, *args):
290285
for i, arg in enumerate(args):
291286
assert isinstance(arg, pyxrt.bo), f"Argument {i} is not a pyxrt.bo"
292287
run.set_arg(i, arg)
288+
t0 = time.perf_counter()
293289
run.start()
294290
ret_code = run.wait()
291+
self.last_elapsed = time.perf_counter() - t0
295292
if ret_code != pyxrt.ert_cmd_state.ERT_CMD_STATE_COMPLETED:
296293
raise RuntimeError(f"Kernel execution failed with return code {ret_code}")
297294

@@ -371,10 +368,10 @@ def get_buffer(self, buffer_name):
371368
return sub_buffer
372369

373370
def __call__(self):
374-
self.input_buffer.to("npu")
371+
self.input_buffer._sync_to_device()
375372
super().__call__(
376373
self.input_buffer.buffer_object(),
377374
self.output_buffer.buffer_object(),
378375
self.scratch_buffer.buffer_object(),
379376
)
380-
self.output_buffer.to("cpu")
377+
self.output_buffer._sync_from_device()

iron/operators/gemm/design.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ def my_matmul(
299299
gemm_object,
300300
[C_l1_ty_internal],
301301
)
302-
matmul_func_name = f"matmul{scalar_suffix}_{dtype_in_str}_f32"
302+
matmul_func_name = f"{func_prefix}matmul{scalar_suffix}_{dtype_in_str}_f32"
303303
matmul_kernel = Kernel(
304304
matmul_func_name,
305305
gemm_object,
@@ -314,7 +314,9 @@ def my_matmul(
314314
gemm_object,
315315
[C_l1_ty],
316316
)
317-
matmul_func_name = f"matmul{scalar_suffix}_{dtype_in_str}_{dtype_out_str}"
317+
matmul_func_name = (
318+
f"{func_prefix}matmul{scalar_suffix}_{dtype_in_str}_{dtype_out_str}"
319+
)
318320
matmul_kernel = Kernel(
319321
matmul_func_name,
320322
gemm_object,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-FileCopyrightText: Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0

0 commit comments

Comments
 (0)