Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate multiple iterations of the stress test code block as a loop #5

Closed
rgokulsm opened this issue Sep 25, 2019 · 4 comments
Closed
Assignees

Comments

@rgokulsm
Copy link

rgokulsm commented Sep 25, 2019

Hello,

I am generating micro-benchmarks for risc-v (based on risv_ipc) with the parameter --loop-size L which, in my understanding, sets the size of the building block (with SimpleBuildingBlockPass). After this the various passes act on this block.

I am interested in having the final generated code to loop over this instruction block multiple (i.e. a configurable N-times outer loop) times, so that the total instructions I would execute would be N*L i.e. so that I can have a longer stress test to run on the simulator.

Not sure if I can just add/edit a simple pass to enable this.

The current code I use:
passes = [
structure.SimpleBuildingBlockPass(self.args.loop_size),
initialization.InitializeRegistersPass(),
initialization.InitializeRegistersPass(v_value=(1.000000000000001, 64)),
instruction.SetInstructionTypeByProfilePass(thisdict),
address.UpdateInstructionAddressesPass(),
branch.BranchNextPass(),
register.DefaultRegisterAllocationPass(dd=GOK_REG_DIST),
address.UpdateInstructionAddressesPass()
]
for p in passes:
synth.add_pass(p)

            bench = synth.synthesize()

Thanks,
Gokul

@rbertran rbertran self-assigned this Sep 27, 2019
@rbertran rbertran added enhancement New feature or request and removed enhancement New feature or request labels Sep 27, 2019
@rbertran
Copy link
Collaborator

Hi Gokul,

This use case is not supported yet since we typically use endless wrappers and control the number of instructions executed/measure externally (e.g. killing the process or stopping the simulation after N cycles or instructions committed).

Not sure what is your output format, if you are using a C and the compiling you can use the following wrappers:

  • CInfGen --> puts the generated code within an endless loop
  • CLoopGen --> puts the generated code within a loop of N iterations

You might need to double check register usage since the compilation process mess up things. If you are using another format wrapper (e.g. assembly or riscvtestp), then we need to implement that functionality. That can be done in two different ways:

  • Add a new pass:
    • adds initialization instructions in the preamble code if needed
    • adds a branch instruction at the finalization code if needed
    • reserves any used registers so that other passes will not use it
  • Add a new wrapper that puts all synthesized code directly within a loop (endless wrapper) using your format

Which format/wrapper are you using? Let me know, and I'll implement the necessary support.

Thanks,

@rgokulsm
Copy link
Author

Hi Ramon,

Thanks for your response. An endless wrapper would work fine as well. I am using the RiscvTestsP wrapper and it would be great if it had the functionality. I have not tried the C format - maybe I can give that a shot too.

Thinking ahead, I think it might be a useful feature if each loop iteration had some configurability. For example, if the memory addresses could be changed from one iteration to another (say, as some function of the iteration number), this might be useful in stressing the prefetcher. If you think this would be a useful usecase then maybe adding a pass to enable this might be a better option than directly doing so from the wrapper?

Please let me know if I can provide any help from my end. Thanks!

@rbertran
Copy link
Collaborator

@rgokulsm, if you are using the RiscvTestsP wrapper, then you can just pass a named parameter to get the endless behavior.

Instead of creating the object like this:

wrapper_class = get_wrapper("RiscvTestsP")
wrapper_obj = wrapper_class()

do this:

wrapper_class = get_wrapper("RiscvTestsP")
wrapper_obj = wrapper_class(endless=True)

Also there is a reset parameter. If you use only endless, the initialization code is executed once and then, the loop code is endlessly executed. If you use endless + reset, then both the initialization code + the loop code are endlessly executed.

wrapper_class = get_wrapper("RiscvTestsP")
wrapper_obj = wrapper_class(endless=True, reset=True)

Unfortunately, due to lack of documentation/examples all these details are hidden in the code. When time permits, we'll try to fix that, but in the meantime, feel free to ask anything.

Regarding the memory pattern use case, I'll open a separate issue to discuss that.

@rgokulsm
Copy link
Author

rgokulsm commented Oct 3, 2019

Thanks Ramon. I'm able to create an endless loop now. The code I use is:

cwrapper = get_wrapper('RiscvTestsP')
synth = Synthesizer(
self.target,
cwrapper(endless=True),
value=0b01010101,
)

@rgokulsm rgokulsm closed this as completed Oct 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants