@@ -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