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

Add targets running OpenROAD GUI with Docker image #27

Merged
merged 4 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/build_local_target.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ target_name=${TARGET:-"tag_array_64x184"}
flow=${FLOW:-"local_make"}
if [[ -z "$STAGES" ]]; then
if [[ "$target_name" == L1MetadataArray_* ]]; then
STAGES=("synth_sdc" "synth" "floorplan" "place" "cts" "grt" "generate_abstract")
STAGES=("synth_sdc" "synth" "floorplan" "place" "generate_abstract")
else
STAGES=("synth_sdc" "synth" "memory" "floorplan" "generate_abstract")
fi
Expand Down
18 changes: 16 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
STAGE_TARGET:
- "tag_array_64x184_generate_abstract_make"
- "L1MetadataArray_test_generate_abstract_make"
- "L1MetadataArray_full_generate_abstract_make"
- "L1MetadataArray_full_final_gui"
- "L1MetadataArray_test_gds_final_make"
- "tag_array_64x184_memory_make"
env:
Expand Down Expand Up @@ -67,6 +67,13 @@ jobs:
- name: build target
run: |
bazel build --subcommands --verbose_failures --sandbox_debug ${{ matrix.STAGE_TARGET }}
- name: open target
if: matrix.STAGE_TARGET == 'L1MetadataArray_full_final_gui'
run: |
for stage in "synth" "floorplan" "place" "cts" "route" "final"; do
bazel build --subcommands --verbose_failures --sandbox_debug L1MetadataArray_full_${stage}_scripts
echo | ./bazel-bin/L1MetadataArray_full_${stage}_docker open_${stage}
done

test-scripts-target-docker:
name: Docker flow - test _scripts targets
Expand Down Expand Up @@ -99,6 +106,7 @@ jobs:
- name: build docker stage targets - L1MetadataArray_test
env:
TARGET: L1MetadataArray_test
STAGES: synth_sdc synth floorplan place cts grt generate_abstract
run: .github/scripts/build_local_target.sh

test-scripts-target-local:
Expand Down Expand Up @@ -142,8 +150,14 @@ jobs:
run: .github/scripts/build_local_target.sh
- name: build local stage targets - L1MetadataArray_test
env:
TARGET: L1MetadataArray_test
TARGET: L1MetadataArray_test_gds
STAGES: synth_sdc synth floorplan place cts grt route final generate_abstract
run: .github/scripts/build_local_target.sh
- name: open target
run: |
for stage in "synth" "floorplan" "place" "cts" "route" "final"; do
echo | bazel-bin/L1MetadataArray_test_gds_${stage}_local_make open_${stage}
done

test-docker-local-targets:
name: Run ORFS using docker and local flow
Expand Down
2 changes: 1 addition & 1 deletion BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ build_openroad(
"MACRO_PLACE_HALO=10 10",
],
"place": [
"PLACE_DENSITY=0.20",
"PLACE_DENSITY=0.10",
"PLACE_PINS_ARGS=-annealing",
],
}, ['SKIP_REPORT_METRICS=1']),
Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ Make targets:
//:L1MetadataArray_test_generate_abstract_make
//:L1MetadataArray_test_memory_make

GUI targets:
//:L1MetadataArray_test_synth_gui
//:L1MetadataArray_test_floorplan_gui
//:L1MetadataArray_test_place_gui
//:L1MetadataArray_test_cts_gui

Config generation targets:

Design config:
Expand Down Expand Up @@ -142,6 +148,7 @@ These are the genrules spawned in this macro:
* Make targets (named: `target_name + “_” + stage + “_make”`)
* Builds all dependencies required for the stage and generates scripts
* Special mock flow: Mock Area targets (named: `target_name + “_” + stage + “_mock_area”`)
* GUI targets (named: `target_name + “_” + stage + “_gui”`)

#### Docker flow

Expand Down Expand Up @@ -214,6 +221,30 @@ Used for estimating sizes of macros with long build times and checking if they w

These targets print RAM summaries for a given module.

#### GUI Targets

Those targets are used to prepare environment for running OpenROAD CLI or GUI with Docker flow. E.g. `bazel build L1MetadataArray_full_final_gui` builds all dependencies required for running `open_final` and `gui_final` targets.

CLI and GUI is not available for all stages, consequently these targets are created only for:
* synthesis
* floorplan
* place
* clock tree synthesis
* route
* final

To use them with local flow it is enough to call generated script with `open_{stage}` or gui_{stage}` make target:

```
# Build dependencies
bazel build L1MetadataArray_full_final_gui

# Run GUI with local flow
./bazel-bin/L1MetadataArray_full_final_local_make gui_final
# or docker flow
./bazel-bin/L1MetadataArray_full_final_docker gui_final
```

### Constraints handling

Constraint files are passed down to `build_openroad()` macro through attributes:
Expand Down
102 changes: 59 additions & 43 deletions docker_shell.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ if [[ $DIR == */external/bazel-orfs~override ]]; then
DOCKER_ARGS="$DOCKER_ARGS -v $BAZLE_ORFS_DIR:$BAZLE_ORFS_DIR"
fi

if [[ "${1}" == "--interactive" ]]; then
if test -t 0; then
DOCKER_INTERACTIVE=-ti
else
echo "STDIN not opened in the terminal, --interactive has no effect"
fi
shift 1
fi

XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
xauth nlist :0 | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
Expand Down Expand Up @@ -74,46 +83,53 @@ chmod -R +w $WORKSPACE_EXECROOT/bazel-out/k8-fastbuild/bin

export MAKEFILES=$FLOW_HOME/Makefile

# Handle TERM signals
# this option requires `supports-graceful-termination` tag in Bazel rule
trap handle_sigterm SIGTERM

# Most of these options below has to do with allowing to
# run the OpenROAD GUI from within Docker.
docker run --name "bazel-orfs-$uuid" --rm \
-u $(id -u ${USER}):$(id -g ${USER}) \
-e LIBGL_ALWAYS_SOFTWARE=1 \
-e "QT_X11_NO_MITSHM=1" \
-e XDG_RUNTIME_DIR=/tmp/xdg-run \
-e DISPLAY=$DISPLAY \
-e QT_XKB_CONFIG_ROOT=/usr/share/X11/xkb \
-v $XSOCK:$XSOCK \
-v $XAUTH:$XAUTH \
-e XAUTHORITY=$XAUTH \
-e BUILD_DIR=$WORKSPACE_EXECROOT \
-e FLOW_HOME=$FLOW_HOME \
-e MAKEFILES=$MAKEFILES \
-e DESIGN_CONFIG=$DESIGN_CONFIG_PREFIXED \
-e STAGE_CONFIG=$STAGE_CONFIG_PREFIXED \
-e MAKE_PATTERN=$MAKE_PATTERN_PREFIXED \
-e WORK_HOME=$WORKSPACE_EXECROOT/$RULEDIR \
$MOCK_AREA_TCL_PREFIXED \
$MEMORY_DUMP_TCL_PREFIXED \
$MEMORY_DUMP_PY_PREFIXED \
-v $WORKSPACE_ROOT:$WORKSPACE_ROOT \
-v $WORKSPACE_ORIGIN:$WORKSPACE_ORIGIN \
--network host \
$DOCKER_INTERACTIVE \
$DOCKER_ARGS \
${OR_IMAGE:-openroad/flow-ubuntu22.04-builder:latest} \
bash -c \
"set -ex
. ./env.sh
cd \$BUILD_DIR
$ARGUMENTS
" &

# Wait for Docker container to finish
# Docker container has to be run in subprocess,
# otherwise signal will not be handled immediately
wait $!
function run_docker() {
# Most of these options below has to do with allowing to
# run the OpenROAD GUI from within Docker.
docker run --name "bazel-orfs-$uuid" --rm \
-u $(id -u ${USER}):$(id -g ${USER}) \
-e LIBGL_ALWAYS_SOFTWARE=1 \
-e "QT_X11_NO_MITSHM=1" \
-e XDG_RUNTIME_DIR=/tmp/xdg-run \
-e DISPLAY=$DISPLAY \
-e QT_XKB_CONFIG_ROOT=/usr/share/X11/xkb \
-v $XSOCK:$XSOCK \
-v $XAUTH:$XAUTH \
-e XAUTHORITY=$XAUTH \
-e BUILD_DIR=$WORKSPACE_EXECROOT \
-e FLOW_HOME=$FLOW_HOME \
-e MAKEFILES=$MAKEFILES \
-e DESIGN_CONFIG=$DESIGN_CONFIG_PREFIXED \
-e STAGE_CONFIG=$STAGE_CONFIG_PREFIXED \
-e MAKE_PATTERN=$MAKE_PATTERN_PREFIXED \
-e WORK_HOME=$WORKSPACE_EXECROOT/$RULEDIR \
$MOCK_AREA_TCL_PREFIXED \
$MEMORY_DUMP_TCL_PREFIXED \
$MEMORY_DUMP_PY_PREFIXED \
-v $WORKSPACE_ROOT:$WORKSPACE_ROOT \
-v $WORKSPACE_ORIGIN:$WORKSPACE_ORIGIN \
--network host \
$DOCKER_INTERACTIVE \
$DOCKER_ARGS \
${OR_IMAGE:-openroad/flow-ubuntu22.04-builder:latest} \
bash -c \
"set -ex
. ./env.sh
cd \$BUILD_DIR
$ARGUMENTS
"
}

if [[ "$DOCKER_INTERACTIVE" == "" ]]; then
# Handle TERM signals
# this option requires `supports-graceful-termination` tag in Bazel rule
trap handle_sigterm SIGTERM
run_docker &

# Wait for Docker container to finish
# Docker container has to be run in subprocess,
# otherwise signal will not be handled immediately
wait $!
else
run_docker
fi
29 changes: 27 additions & 2 deletions openroad.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ def get_entrypoint_cmd(
docker_image = None,
mock_area = False,
memory = False,
entrypoint = None):
entrypoint = None,
interactive = False):
"""
Prepare command line for running docker_shell utility

Expand All @@ -264,6 +265,7 @@ def get_entrypoint_cmd(
mock_area: flag describing whether pass additional env var for mock_area target execution
memory: flag describing whether pass additional env var for memory target execution
entrypoint: optional label pointing to file which will be used as entrypoint
interactive: flag describing whether run docker container in interactive mode

Returns:
string with command line for running ORFS flow in docker container
Expand Down Expand Up @@ -295,6 +297,8 @@ def get_entrypoint_cmd(
cmd += " MEMORY_DUMP_PY=" + get_location(Label("//scripts:mem_dump.py")) + fmt_whitespace
cmd += " RULEDIR=$(RULEDIR)" + fmt_whitespace
cmd += entrypoint
if interactive:
cmd += " --interactive"
cmd += " make "
if (make_targets != None):
cmd += make_targets
Expand Down Expand Up @@ -653,6 +657,10 @@ def build_openroad(
for stage in stages:
make_pattern = Label("//:" + stage + "-bazel.mk")
stage_config = Label("@@//:" + target_name + "_" + stage + "_config.mk")

# For synth use config with additional options required for GUI
if stage == "synth":
stage_config = Label("@@//:" + target_name + "_gui_" + stage + "_config.mk")
make_targets = get_make_targets(stage, False, mock_area)
local_entrypoint_cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, False, memory = False)
docker_entrypoint_cmd = get_entrypoint_cmd(
Expand All @@ -663,6 +671,7 @@ def build_openroad(
memory = False,
entrypoint = Label("//:docker_shell"),
docker_image = docker_image,
interactive = True,
)
target_name_stage = target_name + "_" + stage

Expand Down Expand Up @@ -727,7 +736,7 @@ def build_openroad(
stage_config = Label("@@//:" + target_name + "_memory_config.mk")
mem_scripts = [Label("//scripts:mem_dump.tcl"), Label("//scripts:mem_dump.py")]
local_entrypoint_cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, False, memory = True)
docker_entrypoint_cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, True, "memory", docker_image = docker_image, memory = True)
docker_entrypoint_cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, True, "memory", docker_image = docker_image, memory = True, interactive = True)

native.genrule(
name = target_name + "_memory_make_local_script",
Expand Down Expand Up @@ -804,3 +813,19 @@ def build_openroad(
([target_name + "_generate_abstract_mock_area"] if mock_area != None and stage == "generate_abstract" else []) +
[target_name + "_" + stage + "_scripts"],
)

# Prepare GUI targets
if stage in ("synth", "floorplan", "place", "cts", "route", "final"):
base_targets = [target_name + "_" + stage]
if stage == "synth":
write_stage_config(
name = target_name + "_gui_" + stage + "_config",
stage = stage,
srcs = stage_cfg_srcs,
stage_args = stage_args["synth"] + stage_args["synth_sdc"] + lefs_args,
)
base_targets.append(target_name + "_synth_sdc")
native.filegroup(
name = target_name + "_" + stage + "_gui",
srcs = base_targets + [target_name + "_" + stage + "_scripts"],
)