microprobe.code.Synthesizer
- class Synthesizer(target: Target, wrapper: Wrapper | List[Wrapper], no_scratch: bool = False, extra_raw: Dict[str, str] = {}, value='random', threads: int = 1)[source]
Bases:
object
Benchmark synthesizer.
The Synthesizer objects are in charge of creating
Benchmark
objects based on a set of passes that have been previously defined.The typical workflow will be as follow. User instantiates the synthesizer, specifying also the
Target
and theWrapper
, which are required to know the target properties as well as how the code should be translated to the final representation. Then a set ofPass
are registered using theadd_pass()
method. This passes will be applied in the provided order on a emptyBenchmark
object when thesynthesize()
method is called. Finally, the generated benchmark can be saved to disk by using thesave()
method. A snippet of code of this process would be like:synthesizer = Synthesizer(...) # Instantiate object synthesizer.add_pass(...) # Add transformation passes ... synthesizer.add_pass(...) synthesizer.synthesize(...) # Apply the passes and generate a # benchmark synthesizer.save(...) # Save the benchmark
The default structure of the benchmarks being synthesized is as follows:
extra_raw['FILE_HEADER']
contentswrapper.headers()
contents<global variable declarations>
wrapper.start_main()
contentsextra_raw['CODE_HEADER']
contents<global variable initializations>
wrapper.post_var()
contents<benchmark initialization code>
wrapper.start_loop()
contents<benchmark building blocks>
<benchmark finalization code>
wrapper.end_loop()
contentsextra_raw['CODE_FOOTER']
contentswrapper.end_main()
contentswrapper.footer()
contentsextra_raw['FILE_FOOTER']
contents
where:
extra_raw
contents are provided at initialization (see below)wrapper object methods provide the decoupling between output format and the benchmark synthesizer
variables and building block contents are populated by the passes being applied
Note
This default code layout can be changed by sub-classing this class.
The
synthesize()
method and thesave()
method can be called multiple times to generate and save multiple benchmarks in case that some of the passes have some random behavior. Otherwise, it does not make sense ;).
- __init__(target: Target, wrapper: Wrapper | List[Wrapper], no_scratch: bool = False, extra_raw: Dict[str, str] = {}, value='random', threads: int = 1)[source]
Create a Synthesizer object.
- Parameters:
target (
Target
) – Benchmark targetwrapper (
Wrapper
) – Wrapper object defining the output formatvalue (
int
) – Default immediate value used for non-initialized immediates (Default: random)no_scratch (
bool
) – Disable automatic declaration of scratch variables required for code generation support (Default: False)extra_raw (
list
of elements containing aname
and avalue
attributes (Default: [])) – List of extra raw strings to be embedded in the final output
- Returns:
A Synthesizer instance
- Return type:
Methods
__init__
(target, wrapper[, no_scratch, ...])Create a Synthesizer object.
add_pass
(synth_pass[, thread_idx])Add a pass to the benchmark synthesizer.
save
(name[, bench, pad])Save a benchmark to disk.
set_current_thread
(idx)Synthesize a benchmark.
Attributes
Target attribute (
Target
).Wrapper attribute (
Wrapper
).
- add_pass(synth_pass: Pass, thread_idx: int | None = None)[source]
Add a pass to the benchmark synthesizer.
- Parameters:
synth_pass (
Pass
) – New pass to add.
- save(name: str, bench: Benchmark | None = None, pad: int | None = None)[source]
Save a benchmark to disk.
Save a synthesized benchmark to disk. If bench is not specified a benchmark is automatically synthesized using the
synthesize()
method.
- synthesize()[source]
Synthesize a benchmark.
Synthesize a benchmark based on the set of passes that have been added using the
add_pass()
method.- Returns:
A new synthesized benchmark
- Return type: