OpenROAD
OpenROAD copied to clipboard
openroad should write it's commands into the log
Description
Revisiting a year old log files, it would have been very helpful to have the CMD's that were issued to be in the log file.
Suggested Solution
write CMD's into the log file
Additional Context
No response
To implement: tcl's trace can be used to call into the logger
I'd like to work on this.
Great!
This is taking me a bit longer than I expected. Commands are entered directly to the embedded TCL interpreter, so the logger would need to be invoked within the interpreter. I have considered two approaches to do this.
One way would be to create a custom alias for the TCL eval command using Tcl_CreateAlias(). This way we can assign our own C++ function to this alias for logging the command name, then call the original eval so the command is still executed. A potential problem is that eval might be called by the interpreter in more cases then with our custom commands, so we may need to check that we are only logging the commands we want. We would need to maintain a list of all commands we want to log and search this list before logging any command from our new function.
Another way would be to create a new TCL function that is called before any of our custom commands. Perhaps there is a way to prepend this function to each TCL command upon initialization. I am not sure how this would work yet, but maybe we could change sta/etc/TclEncode.tcl to include this.
I don't know how feasible either approach is, but the first one sounds simpler so I plan to try that first. If I can actually get the arguments of eval to be logged, then I will see if there is extra output that we don't need.
Just want to jump in that the other thing we could try is to add this functionality to TCL. It wouldn't immediately be available to users on standard distros, but the pre-built binaries could take advantage of it.
https://core.tcl-lang.org/tcl/wiki?name=Index
@QuantamHD the tcl_trace functionality is there. I briefly looked at this (adding a trace to utl) and it's possible to get the commands, but depending on the entry method (gui vs non-gui, cmd arg file vs command line) changes how the tracing worked so I didn't go any further. I don't think there is anything to add to Tcl, I think the solution is to fix how we interface with Tcl to make this possible.
I am too busy to work on this right now unfortunately.
I need to prioritize some other projects for a few months. If this still hasn't been resolved by then I can take another look at it.
Hello @Iyury1 @gadfort @stefanottili @QuantamHD @maliberty, I would like to work on this issue. Do you know if anyone is already working on it?
@dav77227 I don't know about the others, but I am not working on this. Good luck.
To add features to this request: every “long running” command should report how long it took to run it. The goal would be to be able to easily compare log files from different runs. E.g. vimdiff dir[12]/log or grep runtime dir2/log > dir2/runtime diff dir[12]/runtime
@stefanottili that feels like a separate feature request. Plus that would be better if it can be implemented in the C code so it is available to the python interface too.
@gadfort you're right, separate feature request https://github.com/The-OpenROAD-Project/OpenROAD/issues/5003
Hello. Currently, I have implemented the following solution, which I would like to discuss before creating a PR. @maliberty @QuantamHD @gadfort @stefanottili could you please provide your feedback on this matter?
The concept of the solution is the following:
The TCL script passed to the OpenROAD is substituted with a tracing script that adds tracing functionality and calls the source
command with the original TCL script. The script substitution is done in the OpenROAD main function.
I'm attaching the 2_2_floorplan_io.log
log files with and without my changes for your review.
2_2_floorplan_io_before.log
2_2_floorplan_io_after.log
Does your solution work if the user is simply typing commands at the interactive prompt and not executing a script?
@maliberty The current tracing functionality is called through TCL script, thus the solution works only when working with the script and not from the interactive mode.
Is it possible to setup the tracing on the interpreter so it doesn't matter what the input source is?
@maliberty yes it's possible. I think I still have the code I put together earlier, it might be possible to avoid the depth issue I ran into previously by using the commands registered in sta (similar to what we do in the GUI) to create a list of commands to echo back.
There are log_begin and log_end commands in OpenROAD used to initiate logging during an interactive session. I tried to use them, but somehow it didn't work: the file is created, but nothing is written (I have called different commands to get the result into a log file). Is there something incorrect ? Here are the command sequence that I have used:
openroad> log_begin myfile.log
openroad> read_lef path_to_OpenROAD/flow/platforms/nangate45/lef/NangateOpenCellLibrary.tech.lef
openroad> read_verilog path_to_OpenROAD/flow/results/nangate45/gcd/base/1_synth.v
openroad> report_units
openroad> write_db file.db
openroad> log_end
openroad> exit
log_begin is an sta command and won't work across all of OR. Its more relevant in the context of standalone sta.
@gadfort if I understand correctly, the solution that you are suggesting is to call Tcl_CreateObjTrace
or Tcl_CreateTrace
in the tclAppInit
function with some logging procedure ? If yes, then I'll try to cum up with a PR for it.
@dav77227 yes, that is correct.
Greetings. I've implemented a solution using the Tcl_CreateObjTrace
function. It performs trace for prompt mode and in case of script execution. However, a lot of things can be printed in the case of batch mode: a procedure can call other procedures in their body, and this can reach a certain level recursively. So I'd like to clarify which commands/procedures are best to print to have a balanced output. One option is to print only top level commands, however this will imply that if the underlying implementation of the top level command is changed over the time it will not be noticeable from the logs, on the other hand if we print all levels then, we will have pretty big logging only for a single top level command.
I think it's best to decide on a real example. So the io_placement_random.tcl
script is the following:
source $::env(SCRIPTS_DIR)/load.tcl
load_design 2_1_floorplan.odb 1_synth.sdc
if {[info exists ::env(FLOORPLAN_DEF)]} {
puts "Skipping IO placement as DEF file was used to initialize floorplan."
} else {
if {[info exists ::env(IO_CONSTRAINTS)]} {
source $::env(IO_CONSTRAINTS)
}
place_pins -hor_layer $::env(IO_PLACER_H) \
-ver_layer $::env(IO_PLACER_V) \
-random \
{*}$::env(PLACE_PINS_ARGS)
}
write_db $::env(RESULTS_DIR)/2_2_floorplan_io.odb
@maliberty @QuantamHD @gadfort @stefanottili could you please specify what should be printed for this exact script?
You could use this chunk of code : https://github.com/The-OpenROAD-Project/OpenROAD/blob/ad54bbe88b561d1c30451d8a3c85ad11c1692905/src/gui/src/tclCmdInputWidget.cpp#L392 To determine what command names are registered in openroad
I suggest logging anytime a registered command is invoked which its evaluated arguments.