Skip to content

Commit 7fd5c8e

Browse files
authored
Use tablegen Python bindings for trace events instead of separate generation (#3038)
1 parent fe9db53 commit 7fd5c8e

7 files changed

Lines changed: 87 additions & 208 deletions

File tree

include/aie/Dialect/AIE/IR/CMakeLists.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,29 @@ set(GENERATED_EVENTS_TD_FILES
6060
"${CMAKE_BINARY_DIR}/include/AIEEventsAIE2P.td.inc"
6161
)
6262

63+
set(GENERATED_EVENTS_JSON "${CMAKE_BINARY_DIR}/lib/regdb/events_database.json")
64+
6365
add_custom_command(
64-
OUTPUT ${GENERATED_EVENTS_TD_FILES}
66+
OUTPUT ${GENERATED_EVENTS_TD_FILES} ${GENERATED_EVENTS_JSON}
6567
COMMAND ${Python3_EXECUTABLE}
6668
${AIE_SOURCE_DIR}/utils/generate_events_tablegen.py
6769
-i ${EVENTS_HEADER_FILES}
6870
-o ${CMAKE_BINARY_DIR}/include
71+
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/lib/regdb
72+
COMMAND ${Python3_EXECUTABLE}
73+
${AIE_SOURCE_DIR}/utils/generate_events_json.py
74+
-i ${EVENTS_HEADER_FILES}
75+
-o ${CMAKE_BINARY_DIR}/lib/regdb
6976
DEPENDS
7077
${AIE_SOURCE_DIR}/utils/generate_events_tablegen.py
78+
${AIE_SOURCE_DIR}/utils/generate_events_json.py
7179
${EVENTS_HEADER_FILES}
72-
COMMENT "Generating AIE event enum tablegen files from aie-rt headers"
80+
COMMENT "Generating AIE event tablegen and JSON database from aie-rt headers"
7381
VERBATIM
7482
)
7583

7684
add_custom_target(GenerateAIEEventsTD
77-
DEPENDS ${GENERATED_EVENTS_TD_FILES}
85+
DEPENDS ${GENERATED_EVENTS_TD_FILES} ${GENERATED_EVENTS_JSON}
7886
)
7987

8088
# Add AIE attributes

lib/Dialect/AIE/Util/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ add_mlir_dialect_library(MLIRAIEUtil
3636
MLIRSupport
3737
)
3838

39-
add_dependencies(MLIRAIEUtil MLIRAIERegDBResources GenerateTraceEventsEnum)
39+
add_dependencies(MLIRAIEUtil MLIRAIERegDBResources GenerateAIEEventsTD)
4040

4141
install(FILES
4242
${AIE_BINARY_DIR}/lib/regdb/aie_registers_aie2.json
43+
${AIE_BINARY_DIR}/lib/regdb/events_database.json
4344
DESTINATION lib${LLVM_LIBDIR_SUFFIX}/regdb)

python/CMakeLists.txt

Lines changed: 4 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -387,85 +387,10 @@ else ()
387387
COMPONENT aie-python
388388
)
389389

390-
################################################################################
391-
# Generated trace events enum files and copy to Python package directories
392-
################################################################################
393-
394-
# Input header files from aie-rt
395-
set(AIE_RT_EVENTS_DIR "${AIE_SOURCE_DIR}/third_party/aie-rt/driver/src/events")
396-
set(EVENTS_HEADER_FILES
397-
"${AIE_RT_EVENTS_DIR}/xaie_events_aie.h"
398-
"${AIE_RT_EVENTS_DIR}/xaie_events_aieml.h"
399-
"${AIE_RT_EVENTS_DIR}/xaie_events_aie2p.h"
400-
)
401-
402-
# Output directory for generated files in build directory
403-
set(GENERATED_EVENTS_DIR "${CMAKE_BINARY_DIR}/lib/regdb")
404-
405-
# Generated Python enum files in the build directory
406-
set(GENERATED_EVENTS_ENUM_FILES
407-
"${GENERATED_EVENTS_DIR}/aie.py"
408-
"${GENERATED_EVENTS_DIR}/aie2.py"
409-
"${GENERATED_EVENTS_DIR}/aie2p.py"
410-
)
411-
412-
# Generated JSON database in the build directory
413-
set(GENERATED_EVENTS_JSON_FILENAME "events_database.json")
414-
set(GENERATED_EVENTS_JSON "${GENERATED_EVENTS_DIR}/${GENERATED_EVENTS_JSON_FILENAME}")
415-
416-
# Add custom command to generate the event enum files
417-
add_custom_command(
418-
OUTPUT ${GENERATED_EVENTS_ENUM_FILES} ${GENERATED_EVENTS_JSON}
419-
COMMAND ${CMAKE_COMMAND} -E make_directory ${GENERATED_EVENTS_DIR}
420-
COMMAND ${Python3_EXECUTABLE}
421-
${AIE_SOURCE_DIR}/utils/generate_events_enum.py
422-
-i ${EVENTS_HEADER_FILES}
423-
-o ${GENERATED_EVENTS_DIR}
424-
--json ${GENERATED_EVENTS_JSON_FILENAME}
425-
--python-prefix ""
426-
DEPENDS
427-
${AIE_SOURCE_DIR}/utils/generate_events_enum.py
428-
${EVENTS_HEADER_FILES}
429-
COMMENT "Generating trace events enum files from aie-rt headers"
430-
VERBATIM
431-
)
432-
433-
# Install the generated json to the lib dir
434-
install(
435-
FILES
436-
${GENERATED_EVENTS_JSON}
437-
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/regdb
438-
COMPONENT aie-python
439-
)
440-
441-
# Create a custom target for the generated files
442-
add_custom_target(GenerateTraceEventsEnum ALL
443-
DEPENDS ${GENERATED_EVENTS_ENUM_FILES} ${GENERATED_EVENTS_JSON}
444-
)
445-
446-
# Ensure AIEPythonModules depends on GenerateTraceEventsEnum
447-
add_dependencies(AIEPythonModules GenerateTraceEventsEnum)
448-
449-
# Copy generated event enum files to Python package build directory
450-
foreach(_file ${GENERATED_EVENTS_ENUM_FILES})
451-
get_filename_component(_filename ${_file} NAME)
452-
add_custom_command(
453-
TARGET AIEPythonModules POST_BUILD
454-
COMMAND ${CMAKE_COMMAND} -E make_directory ${AIE_PYTHON_PACKAGES_DIR}/aie/utils/trace/events
455-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
456-
${_file}
457-
${AIE_PYTHON_PACKAGES_DIR}/aie/utils/trace/events/${_filename}
458-
COMMENT "Copying ${_filename} to build Python package"
459-
)
460-
endforeach()
461-
462-
# Install generated event enum files
463-
install(
464-
FILES
465-
${GENERATED_EVENTS_ENUM_FILES}
466-
DESTINATION ${AIE_PYTHON_INSTALL_DIR}/aie/utils/trace/events
467-
COMPONENT aie-python
468-
)
390+
# Note: events_database.json is generated at build time by the
391+
# GenerateAIEEventsTD target (include/aie/Dialect/AIE/IR/CMakeLists.txt).
392+
# Python trace event enums are sourced from the TableGen-generated
393+
# _aie_enum_gen.py bindings (no separate generation step needed).
469394

470395

471396
endif ()

python/utils/trace/events/__init__.py

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,41 @@
66
#
77
"""Trace events enumerations for AIE architectures.
88
9-
Available modules:
10-
- aie: AIE1 architecture events
11-
- aie2: AIE2/AIEML architecture events
12-
- aie2p: AIE2P architecture events
9+
Event enums are sourced from the TableGen-generated Python bindings
10+
(aie.dialects._aie_enum_gen), which are produced from the same aie-rt
11+
headers that define the hardware event numbers.
12+
13+
Architecture-specific enums (CoreEventAIE2, etc.) are re-exported here
14+
under architecture-agnostic names (CoreEvent, etc.) for convenience.
15+
Use get_events_for_device() to select the correct architecture.
1316
"""
17+
1418
from enum import IntEnum
19+
from types import SimpleNamespace
1520
import typing
1621

17-
from . import aie
18-
from . import aie2
19-
from . import aie2p
20-
21-
from .aie2 import (
22-
CoreEvent,
23-
MemEvent,
24-
ShimTileEvent,
25-
MemTileEvent,
22+
from aie.dialects._aie_enum_gen import (
23+
CoreEventAIE,
24+
MemEventAIE,
25+
ShimTileEventAIE,
26+
CoreEventAIE2,
27+
MemEventAIE2,
28+
ShimTileEventAIE2,
29+
MemTileEventAIE2,
30+
CoreEventAIE2P,
31+
MemEventAIE2P,
32+
ShimTileEventAIE2P,
33+
MemTileEventAIE2P,
2634
)
2735

2836
from aie.dialects.aie import WireBundle, DMAChannelDir
2937

38+
# Default to AIE2 for backwards compatibility
39+
CoreEvent = CoreEventAIE2
40+
MemEvent = MemEventAIE2
41+
ShimTileEvent = ShimTileEventAIE2
42+
MemTileEvent = MemTileEventAIE2
43+
3044

3145
# We use the packet type field in the packet header to help differentiate the tile
3246
# that the packet came from. Since packet types don't inherently have meaning, we
@@ -44,11 +58,26 @@ class PacketType(IntEnum):
4458

4559
def get_events_for_device(device: str):
4660
if "xcvc1902" in device:
47-
return aie
61+
return SimpleNamespace(
62+
CoreEvent=CoreEventAIE,
63+
MemEvent=MemEventAIE,
64+
ShimTileEvent=ShimTileEventAIE,
65+
MemTileEvent=None, # AIE1 has no mem tiles
66+
)
4867
elif "npu2p" in device:
49-
return aie2p
68+
return SimpleNamespace(
69+
CoreEvent=CoreEventAIE2P,
70+
MemEvent=MemEventAIE2P,
71+
ShimTileEvent=ShimTileEventAIE2P,
72+
MemTileEvent=MemTileEventAIE2P,
73+
)
5074
else:
51-
return aie2
75+
return SimpleNamespace(
76+
CoreEvent=CoreEventAIE2,
77+
MemEvent=MemEventAIE2,
78+
ShimTileEvent=ShimTileEventAIE2,
79+
MemTileEvent=MemTileEventAIE2,
80+
)
5281

5382

5483
def _get_port_events(enum_class):
@@ -68,9 +97,6 @@ class GenericEvent:
6897
def __init__(
6998
self, code: typing.Union[CoreEvent, MemEvent, ShimTileEvent, MemTileEvent]
7099
):
71-
# For backwards compatibility, allow integer as event
72-
if isinstance(code, int):
73-
code = CoreEvent(code)
74100
self.code: typing.Union[CoreEvent, MemEvent, ShimTileEvent, MemTileEvent] = code
75101

76102
def get_register_writes(self):
@@ -118,9 +144,6 @@ def __init__(
118144
enum_class=None,
119145
valid_codes=None,
120146
):
121-
# For backwards compatibility, allow integer as event
122-
if isinstance(code, int) and enum_class:
123-
code = enum_class(code)
124147
if valid_codes:
125148
assert code in valid_codes
126149

python/utils/trace/parse.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,9 @@ def lookup_event_name_by_type(trace_type, code, events_module):
551551
else:
552552
return "Unknown"
553553

554+
if enum_class is None:
555+
return "Unknown"
556+
554557
try:
555558
return enum_class(code).name
556559
except ValueError:

test/python/trace_events.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,19 @@
2626
# CHECK: Edge case: Arch-specific events
2727
# CHECK: AIE1.MemEvent has WATCHPOINT_0
2828
# CHECK: AIE2.MemEvent has WATCHPOINT_0
29-
# CHECK: AIE2 has MemTileEvent, AIE1 does not
30-
# CHECK: AIE2P has MemTileEvent, AIE1 does not
29+
# CHECK: AIE1 MemTileEvent is None (no mem tiles in AIE1)
30+
# CHECK: AIE2 has MemTileEvent
31+
# CHECK: AIE2P has MemTileEvent
3132
# CHECK: Edge case: Events not present in arch raise AttributeError
3233
# CHECK: AIE1.CoreEvent.EDGE_DETECTION_EVENT_0 does not exist
3334
# CHECK: AIE2.CoreEvent.SRS_SATURATE does not exist
3435
# CHECK: All tests passed!
3536

36-
import aie.utils.trace.events.aie as aie1
37-
import aie.utils.trace.events.aie2 as aie2
38-
import aie.utils.trace.events.aie2p as aie2p
37+
from aie.utils.trace.events import get_events_for_device
38+
39+
aie1 = get_events_for_device("xcvc1902")
40+
aie2 = get_events_for_device("npu1")
41+
aie2p = get_events_for_device("npu2p")
3942

4043

4144
def test_arch(name, core_cls, mem_cls, shim_cls, mem_tile_cls=None):
@@ -132,22 +135,18 @@ def test_edge_cases():
132135
assert hasattr(aie2.MemEvent, "WATCHPOINT_0"), "AIE2 should have WATCHPOINT_0"
133136
print("AIE2.MemEvent has WATCHPOINT_0")
134137

135-
# MemTileEvent only exists in AIE2/AIE2P
136-
assert hasattr(aie1, "MemTileEvent"), "AIE1 module has MemTileEvent class"
137-
# But AIE1's MemTileEvent has no events (just pass)
138-
aie1_memtile_events = [e for e in aie1.MemTileEvent]
139-
assert len(aie1_memtile_events) == 0, "AIE1 MemTileEvent should be empty"
140-
print("AIE2 has MemTileEvent, AIE1 does not")
138+
# AIE1 has no mem tiles
139+
assert aie1.MemTileEvent is None, "AIE1 should not have MemTileEvent"
140+
print("AIE1 MemTileEvent is None (no mem tiles in AIE1)")
141141

142142
# AIE2/AIE2P have actual MemTileEvent events
143-
assert hasattr(aie2, "MemTileEvent"), "AIE2 should have MemTileEvent"
144143
aie2_memtile_events = [e for e in aie2.MemTileEvent]
145144
assert len(aie2_memtile_events) > 0, "AIE2 MemTileEvent should have events"
145+
print("AIE2 has MemTileEvent")
146146

147-
assert hasattr(aie2p, "MemTileEvent"), "AIE2P should have MemTileEvent"
148147
aie2p_memtile_events = [e for e in aie2p.MemTileEvent]
149148
assert len(aie2p_memtile_events) > 0, "AIE2P MemTileEvent should have events"
150-
print("AIE2P has MemTileEvent, AIE1 does not")
149+
print("AIE2P has MemTileEvent")
151150

152151
print("Edge case: Events not present in arch raise AttributeError")
153152

0 commit comments

Comments
 (0)