Skip to content

Commit 7312966

Browse files
committed
Deterministic mode and improvements for match.py
Some improvements for match.py: * Added a {{NONDETERMINISTIC}} tag, which indicates that the match file results need not be in order. * When printing output, line numbers and the "interesting line" are provided. * Fix incorrect index being used when no lines matching a "match" line are found. In addition, all the conformance test match files are marked as "{{NONDETERMINISTIC}}", as they may be ran in different orders depending on compile flags.
1 parent 3cd6eae commit 7312966

File tree

62 files changed

+169
-40
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+169
-40
lines changed

cmake/match.py

Lines changed: 108 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22

33
# Copyright (C) 2023 Intel Corporation
44
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +12,8 @@
1212
# List of available special tags:
1313
# {{OPT}} - makes content in the same line as the tag optional
1414
# {{IGNORE}} - ignores all content until the next successfully matched line or the end of the input
15+
# {{NONDETERMINISTIC}} - order of match rules isn't important - each (non OPT) input line is paired with a match line
16+
# in any order
1517
# Special tags are mutually exclusive and are expected to be located at the start of a line.
1618
#
1719

@@ -20,15 +22,25 @@
2022
import re
2123
from enum import Enum
2224

25+
## @brief print a sequence of lines
26+
def print_lines(lines, hint = None):
27+
counter = 1
28+
for l in lines:
29+
hint_char = " "
30+
if hint == counter - 1:
31+
hint_char = ">"
32+
print("{}{:4d}| {}".format(hint_char, counter, l.strip()))
33+
counter += 1
34+
2335

2436
## @brief print the whole content of input and match files
25-
def print_content(input_lines, match_lines, ignored_lines):
26-
print("--- Input Lines " + "-" * 64)
27-
print("".join(input_lines).strip())
28-
print("--- Match Lines " + "-" * 64)
29-
print("".join(match_lines).strip())
30-
print("--- Ignored Lines " + "-" * 62)
31-
print("".join(ignored_lines).strip())
37+
def print_content(input_lines, match_lines, ignored_lines, hint_input = None, hint_match = None):
38+
print("------ Input Lines " + "-" * 61)
39+
print_lines(input_lines, hint_input)
40+
print("------ Match Lines " + "-" * 61)
41+
print_lines(match_lines, hint_match)
42+
print("------ Ignored Lines " + "-" * 59)
43+
print_lines(ignored_lines)
3244
print("-" * 80)
3345

3446

@@ -39,6 +51,24 @@ def print_incorrect_match(match_line, present, expected):
3951
print("expected: " + expected)
4052

4153

54+
## @brief print missing match line
55+
def print_input_not_found(input_line, input):
56+
print("Input line " + str(input_line) + " has no match line")
57+
print("is: " + input)
58+
59+
60+
## @brief print missing input line
61+
def print_match_not_found(match_line, input):
62+
print("Match line " + str(match_line) + " has no input line")
63+
print("is: " + input)
64+
65+
66+
## @brief print general syntax error
67+
def print_error(text, match_line):
68+
print("Line " + str(match_line) + " encountered an error")
69+
print(text)
70+
71+
4272
## @brief pattern matching script status values
4373
class Status(Enum):
4474
INPUT_END = 1
@@ -63,6 +93,7 @@ def check_status(input_lines, match_lines):
6393
class Tag(Enum):
6494
OPT = "{{OPT}}" # makes the line optional
6595
IGNORE = "{{IGNORE}}" # ignores all input until next match or end of input file
96+
NONDETERMINISTIC = "{{NONDETERMINISTIC}}" # switches on "deterministic mode"
6697
COMMENT = "#" # comment - line ignored
6798

6899

@@ -88,32 +119,53 @@ def main():
88119
)
89120

90121
ignored_lines = []
122+
matched_lines = set()
91123

92124
input_idx = 0
93125
match_idx = 0
94126
tags_in_effect = []
127+
deterministic_mode = False
95128
while True:
96129
# check file status
97130
status = check_status(input_lines[input_idx:], match_lines[match_idx:])
98-
if (status == Status.INPUT_AND_MATCH_END) or (status == Status.MATCH_END and Tag.IGNORE in tags_in_effect):
99-
# all lines matched or the last line in match file is an ignore tag
100-
sys.exit(0)
101-
elif status == Status.MATCH_END:
102-
print_incorrect_match(match_idx + 1, input_lines[input_idx].strip(), "");
103-
print_content(input_lines, match_lines, ignored_lines)
104-
sys.exit(1)
105-
elif status == Status.INPUT_END:
106-
# If we get to the end of the input, but still have pending matches,
107-
# then that's a failure unless all pending matches are optional -
108-
# otherwise we're done
109-
while match_idx < len(match_lines):
110-
if not (match_lines[match_idx].startswith(Tag.OPT.value) or
111-
match_lines[match_idx].startswith(Tag.IGNORE.value)):
112-
print_incorrect_match(match_idx + 1, "", match_lines[match_idx]);
113-
print_content(input_lines, match_lines, ignored_lines)
131+
if deterministic_mode:
132+
if status == Status.INPUT_END:
133+
# Convert the list of seen matches to the list of unseen matches
134+
remaining_matches = set(range(len(match_lines))) - matched_lines
135+
for m in remaining_matches:
136+
line = match_lines[m]
137+
if line.startswith(Tag.OPT.value) or line.startswith(Tag.NONDETERMINISTIC.value):
138+
continue
139+
print_match_not_found(m + 1, match_lines[m])
140+
print_content(input_lines, match_lines, ignored_lines, hint_match=m)
114141
sys.exit(1)
115-
match_idx += 1
116-
sys.exit(0)
142+
143+
sys.exit(0)
144+
elif status == Status.MATCH_END:
145+
print_input_not_found(input_idx + 1, input_lines[input_idx])
146+
print_content(input_lines, match_lines, ignored_lines, hint_input=input_idx)
147+
sys.exit(1)
148+
else:
149+
if (status == Status.INPUT_AND_MATCH_END) or (status == Status.MATCH_END and Tag.IGNORE in tags_in_effect):
150+
# all lines matched or the last line in match file is an ignore tag
151+
sys.exit(0)
152+
elif status == Status.MATCH_END:
153+
print_incorrect_match(input_idx + 1, input_lines[input_idx].strip(), "")
154+
print_content(input_lines, match_lines, ignored_lines, hint_input=input_idx)
155+
sys.exit(1)
156+
elif status == Status.INPUT_END:
157+
# If we get to the end of the input, but still have pending matches,
158+
# then that's a failure unless all pending matches are optional -
159+
# otherwise we're done
160+
while match_idx < len(match_lines):
161+
if not (match_lines[match_idx].startswith(Tag.OPT.value) or
162+
match_lines[match_idx].startswith(Tag.IGNORE.value) or
163+
match_lines[match_idx].startswith(Tag.NONDETERMINISTIC.value)):
164+
print_incorrect_match(match_idx + 1, "", match_lines[match_idx])
165+
print_content(input_lines, match_lines, ignored_lines, hint_match=match_idx)
166+
sys.exit(1)
167+
match_idx += 1
168+
sys.exit(0)
117169

118170
input_line = input_lines[input_idx].strip() if input_idx < len(input_lines) else ""
119171
match_line = match_lines[match_idx]
@@ -122,7 +174,15 @@ def main():
122174
if match_line.startswith(Tag.OPT.value):
123175
tags_in_effect.append(Tag.OPT)
124176
match_line = match_line[len(Tag.OPT.value):]
177+
elif match_line.startswith(Tag.NONDETERMINISTIC.value) and not deterministic_mode:
178+
deterministic_mode = True
179+
match_idx = 0
180+
input_idx = 0
181+
continue
125182
elif match_line.startswith(Tag.IGNORE.value):
183+
if deterministic_mode:
184+
print_error(r"Can't use \{{IGNORE\}} in deterministic mode")
185+
sys.exit(2)
126186
tags_in_effect.append(Tag.IGNORE)
127187
match_idx += 1
128188
continue # line with ignore tag should be skipped
@@ -137,20 +197,29 @@ def main():
137197
pattern += part
138198

139199
# match or process tags
140-
if re.fullmatch(pattern, input_line):
141-
input_idx += 1
142-
match_idx += 1
143-
tags_in_effect = []
144-
elif Tag.OPT in tags_in_effect:
145-
match_idx += 1
146-
tags_in_effect.remove(Tag.OPT)
147-
elif Tag.IGNORE in tags_in_effect:
148-
ignored_lines.append(input_line + os.linesep)
149-
input_idx += 1
200+
if deterministic_mode:
201+
if re.fullmatch(pattern, input_line) and match_idx not in matched_lines:
202+
input_idx += 1
203+
matched_lines.add(match_idx)
204+
match_idx = 0
205+
tags_in_effect = []
206+
else:
207+
match_idx += 1
150208
else:
151-
print_incorrect_match(match_idx + 1, input_line, match_line.strip())
152-
print_content(input_lines, match_lines, ignored_lines)
153-
sys.exit(1)
209+
if re.fullmatch(pattern, input_line):
210+
input_idx += 1
211+
match_idx += 1
212+
tags_in_effect = []
213+
elif Tag.OPT in tags_in_effect:
214+
match_idx += 1
215+
tags_in_effect.remove(Tag.OPT)
216+
elif Tag.IGNORE in tags_in_effect:
217+
ignored_lines.append(input_line + os.linesep)
218+
input_idx += 1
219+
else:
220+
print_incorrect_match(match_idx + 1, input_line, match_line.strip())
221+
print_content(input_lines, match_lines, ignored_lines, hint_match=match_idx, hint_input=input_idx)
222+
sys.exit(1)
154223

155224

156225
if __name__ == "__main__":

test/conformance/adapter/adapter_adapter_native_cpu.match

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{NONDETERMINISTIC}}
12
urAdapterGetLastErrorTest.Success
23
urAdapterGetLastErrorTest.InvalidHandle
34
urAdapterGetLastErrorTest.InvalidMessagePtr
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
{{NONDETERMINISTIC}}
12
urContextCreateWithNativeHandleTest.SuccessWithUnOwnedNativeHandle/Intel_R__oneAPI_Unified_Runtime_over_Level_Zero___{{.*}}_
23
urContextSetExtendedDeleterTest.Success/Intel_R__oneAPI_Unified_Runtime_over_Level_Zero___{{.*}}_
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{NONDETERMINISTIC}}
12
urContextCreateWithNativeHandleTest.InvalidNullHandleAdapter/Intel_R__oneAPI_Unified_Runtime_over_Level_Zero___{{.*}}__
23
urContextCreateWithNativeHandleTest.InvalidNullPointerContext/Intel_R__oneAPI_Unified_Runtime_over_Level_Zero___{{.*}}__
34
urContextSetExtendedDeleterTest.Success/Intel_R__oneAPI_Unified_Runtime_over_Level_Zero___{{.*}}__
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{NONDETERMINISTIC}}
12
urContextCreateWithNativeHandleTest.InvalidNullHandleAdapter/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
23
urContextCreateWithNativeHandleTest.InvalidNullPointerContext/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
34
urContextSetExtendedDeleterTest.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
{{NONDETERMINISTIC}}
12
urDeviceCreateWithNativeHandleTest.SuccessWithUnOwnedNativeHandle
23
{{OPT}}urDeviceGetGlobalTimestampTest.SuccessSynchronizedTime
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
{{NONDETERMINISTIC}}
12
urDeviceCreateWithNativeHandleTest.SuccessWithUnOwnedNativeHandle
23
{{OPT}}urDeviceGetGlobalTimestampTest.SuccessSynchronizedTime
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{NONDETERMINISTIC}}
12
urDeviceCreateWithNativeHandleTest.SuccessWithUnOwnedNativeHandle
23
{{OPT}}urDeviceGetGlobalTimestampTest.SuccessSynchronizedTime
34
{{OPT}}urDeviceGetInfoTest.Success/UR_DEVICE_INFO_GLOBAL_MEM_FREE
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{NONDETERMINISTIC}}
12
urDeviceCreateWithNativeHandleTest.SuccessWithUnOwnedNativeHandle
23
{{OPT}}urDeviceGetGlobalTimestampTest.SuccessSynchronizedTime
34
{{OPT}}urDeviceGetInfoTest.Success/UR_DEVICE_INFO_GLOBAL_MEM_FREE

test/conformance/device/device_adapter_native_cpu.match

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{NONDETERMINISTIC}}
12
urDeviceCreateWithNativeHandleTest.InvalidNullHandlePlatform
23
urDeviceCreateWithNativeHandleTest.InvalidNullPointerDevice
34
{{OPT}}urDeviceGetGlobalTimestampTest.SuccessSynchronizedTime

0 commit comments

Comments
 (0)