Skip to content

Commit c20430b

Browse files
committed
Reorder functions
1 parent b137951 commit c20430b

File tree

1 file changed

+114
-112
lines changed

1 file changed

+114
-112
lines changed

tadashi/apps.py

Lines changed: 114 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -47,54 +47,6 @@ def __del__(self):
4747
else:
4848
print("WARNING: source file missing!")
4949

50-
def __init__(
51-
self,
52-
source: str | Path,
53-
translator: Optional[Translator] = None,
54-
compiler_options: Optional[list[str]] = None,
55-
ephemeral: bool = False,
56-
populate_scops: bool = True,
57-
):
58-
"""Construct an app object.
59-
60-
Args:
61-
62-
source: The source file.
63-
64-
translator: See `Translator`.
65-
66-
compiler_options: compiler options used for parsing the
67-
source file, code generation and compilation.
68-
69-
populate_scops: [obsolete] `False` should results in
70-
something similar to invoking this constructor with
71-
`translator` set to `None`.
72-
73-
.. todo:: There is much to be done here.
74-
75-
.. todo:: 1. populate_scops should be obsoleted and then removed.
76-
77-
.. todo:: 2. order and clarify what should be
78-
derived/overridden. Maybe even convert App to a proper ABC.
79-
80-
"""
81-
self.source = Path(source)
82-
if compiler_options is None:
83-
compiler_options = []
84-
self.user_compiler_options = compiler_options
85-
self.ephemeral = ephemeral
86-
self.populate_scops = populate_scops
87-
if translator is None and populate_scops:
88-
translator = Pet()
89-
if populate_scops and translator:
90-
options = self.app_required_options() + self.user_compiler_options
91-
self.translator = translator.set_source(source, options)
92-
else:
93-
self.translator = None
94-
95-
def app_required_options(self) -> list[str]:
96-
return []
97-
9850
def __getstate__(self):
9951
"""This was probably needed for serialisation."""
10052
state = {}
@@ -180,15 +132,6 @@ def _make_new_filename(self) -> Path:
180132
prefix = f"{filename}-{mark}-{now_str}-"
181133
return Path(tempfile.mktemp(prefix=prefix, suffix=suffix, dir="."))
182134

183-
@property
184-
@abc.abstractmethod
185-
def compile_cmd(self) -> list[str]:
186-
"""Command executed for compilation (list of strings)."""
187-
pass
188-
189-
def codegen_init_args(self) -> dict:
190-
return {}
191-
192135
@staticmethod
193136
def compiler():
194137
return [os.getenv("CC", "gcc")]
@@ -223,6 +166,65 @@ def measure(self, repeat=1, *args, **kwargs) -> float:
223166
results.append(self.extract_runtime(stdout))
224167
return min(results)
225168

169+
def __init__(
170+
self,
171+
source: str | Path,
172+
translator: Optional[Translator] = None,
173+
compiler_options: Optional[list[str]] = None,
174+
ephemeral: bool = False,
175+
populate_scops: bool = True,
176+
):
177+
"""Construct an app object.
178+
179+
Args:
180+
181+
source: The source file.
182+
183+
translator: See `Translator`.
184+
185+
compiler_options: compiler options used for parsing the
186+
source file, code generation and compilation.
187+
188+
populate_scops: [obsolete] `False` should results in
189+
something similar to invoking this constructor with
190+
`translator` set to `None`.
191+
192+
.. todo:: There is much to be done here.
193+
194+
.. todo:: 1. populate_scops should be obsoleted and then removed.
195+
196+
.. todo:: 2. order and clarify what should be
197+
derived/overridden. Maybe even convert App to a proper ABC.
198+
199+
"""
200+
self.source = Path(source)
201+
if compiler_options is None:
202+
compiler_options = []
203+
self.user_compiler_options = compiler_options
204+
self.ephemeral = ephemeral
205+
self.populate_scops = populate_scops
206+
if translator is None and populate_scops:
207+
translator = Pet()
208+
if populate_scops and translator:
209+
options = self.app_required_options() + self.user_compiler_options
210+
self.translator = translator.set_source(source, options)
211+
else:
212+
self.translator = None
213+
214+
@abc.abstractmethod
215+
def codegen_init_args(self) -> dict:
216+
return {}
217+
218+
def app_required_options(self) -> list[str]:
219+
return []
220+
221+
@property
222+
@abc.abstractmethod
223+
def compile_cmd(self) -> list[str]:
224+
"""Command executed for compilation (list of strings)."""
225+
pass
226+
227+
@abc.abstractmethod
226228
def extract_runtime(self, stdout: str) -> float:
227229
"""Extract the measured runtime from the output."""
228230
raise NotImplementedError()
@@ -250,6 +252,9 @@ def __init__(
250252
populate_scops=populate_scops,
251253
)
252254

255+
def codegen_init_args(self):
256+
return {"runtime_prefix": self.runtime_prefix}
257+
253258
@property
254259
def compile_cmd(self) -> list[str]:
255260
cmd = [
@@ -259,9 +264,6 @@ def compile_cmd(self) -> list[str]:
259264
]
260265
return cmd
261266

262-
def codegen_init_args(self):
263-
return {"runtime_prefix": self.runtime_prefix}
264-
265267
def extract_runtime(self, stdout) -> float:
266268
for line in stdout.split("\n"):
267269
if line.startswith(self.runtime_prefix):
@@ -279,6 +281,52 @@ class Polybench(App):
279281
benchmark: str # path to the benchmark dir from base
280282
base: Path # the dir where polybench was unpacked
281283

284+
def _get_benchmark(self, benchmark: str) -> str:
285+
target = Path(benchmark).with_suffix(".c").name
286+
for c_file in self.base.glob("**/*.c"):
287+
if c_file.with_suffix(".c").name == target:
288+
if c_file.parent.name == "utilities":
289+
break # go to raise ValueError!
290+
return str(c_file.relative_to(self.base).parent)
291+
raise ValueError(f"Not a polybench {benchmark=}")
292+
293+
@staticmethod
294+
def get_benchmarks(path: str = POLYBENCH_BASE):
295+
benchmarks = []
296+
for file in Path(path).glob("**/*.c"):
297+
filename = file.with_suffix("").name
298+
dirname = file.parent.name
299+
if filename == dirname:
300+
benchmarks.append(file.parent.relative_to(path))
301+
return list(sorted(benchmarks))
302+
303+
def dump_arrays(self):
304+
suffix = ".dump"
305+
self.compile(
306+
extra_compiler_options=["-DPOLYBENCH_DUMP_ARRAYS"],
307+
output_binary_suffix=suffix,
308+
)
309+
result = subprocess.run(
310+
f"{self.output_binary}{suffix}",
311+
stdout=subprocess.PIPE,
312+
stderr=subprocess.PIPE,
313+
)
314+
return result.stderr.decode()
315+
316+
def dump_scop(self):
317+
src = self.source.read_text()
318+
lines = []
319+
inside_scop = False
320+
for line in src.split("\n"):
321+
if "#pragma" in line and "endscop" in line:
322+
break
323+
if inside_scop:
324+
print(f"{line}")
325+
lines.append(line)
326+
if "#pragma" in line and "scop" in line:
327+
inside_scop = True
328+
return "\n".join(lines)
329+
282330
def __init__(
283331
self,
284332
benchmark: str,
@@ -302,37 +350,18 @@ def __init__(
302350
populate_scops=populate_scops,
303351
)
304352

305-
def app_required_options(self) -> list[str]:
306-
return [
307-
f"-I{self.base / 'utilities'}",
308-
"-DPOLYBENCH_TIME",
309-
"-DPOLYBENCH_USE_RESTRICT",
310-
]
311-
312-
def _get_benchmark(self, benchmark: str) -> str:
313-
target = Path(benchmark).with_suffix(".c").name
314-
for c_file in self.base.glob("**/*.c"):
315-
if c_file.with_suffix(".c").name == target:
316-
if c_file.parent.name == "utilities":
317-
break # go to raise ValueError!
318-
return str(c_file.relative_to(self.base).parent)
319-
raise ValueError(f"Not a polybench {benchmark=}")
320-
321353
def codegen_init_args(self):
322354
return {
323355
"benchmark": self.benchmark,
324356
"base": self.base,
325357
}
326358

327-
@staticmethod
328-
def get_benchmarks(path: str = POLYBENCH_BASE):
329-
benchmarks = []
330-
for file in Path(path).glob("**/*.c"):
331-
filename = file.with_suffix("").name
332-
dirname = file.parent.name
333-
if filename == dirname:
334-
benchmarks.append(file.parent.relative_to(path))
335-
return list(sorted(benchmarks))
359+
def app_required_options(self) -> list[str]:
360+
return [
361+
f"-I{self.base / 'utilities'}",
362+
"-DPOLYBENCH_TIME",
363+
"-DPOLYBENCH_USE_RESTRICT",
364+
]
336365

337366
@property
338367
def compile_cmd(self) -> list[str]:
@@ -352,30 +381,3 @@ def extract_runtime(self, stdout) -> float:
352381
except IndexError as e:
353382
print(f"App probaly crashed: {e}")
354383
return result
355-
356-
def dump_arrays(self):
357-
suffix = ".dump"
358-
self.compile(
359-
extra_compiler_options=["-DPOLYBENCH_DUMP_ARRAYS"],
360-
output_binary_suffix=suffix,
361-
)
362-
result = subprocess.run(
363-
f"{self.output_binary}{suffix}",
364-
stdout=subprocess.PIPE,
365-
stderr=subprocess.PIPE,
366-
)
367-
return result.stderr.decode()
368-
369-
def dump_scop(self):
370-
src = self.source.read_text()
371-
lines = []
372-
inside_scop = False
373-
for line in src.split("\n"):
374-
if "#pragma" in line and "endscop" in line:
375-
break
376-
if inside_scop:
377-
print(f"{line}")
378-
lines.append(line)
379-
if "#pragma" in line and "scop" in line:
380-
inside_scop = True
381-
return "\n".join(lines)

0 commit comments

Comments
 (0)