From 0f3c93d00eb33f0745fc938aeb3b209f5ade5f3f Mon Sep 17 00:00:00 2001 From: Eryk Szpotanski Date: Wed, 24 Apr 2024 15:05:54 +0200 Subject: [PATCH] WIP Signed-off-by: Eryk Szpotanski --- .github/scripts/build_local_target.sh | 9 +- .github/workflows/ci.yml | 63 ++++++++++--- README.md | 124 ++++++++++---------------- docker_shell.sh | 12 +-- make_script.template.sh | 39 ++++++++ openroad.bzl | 123 ++++++++++++++++++------- scripts/BUILD | 1 + 7 files changed, 239 insertions(+), 132 deletions(-) create mode 100755 make_script.template.sh diff --git a/.github/scripts/build_local_target.sh b/.github/scripts/build_local_target.sh index 9fd6f3ce..1f6381bf 100755 --- a/.github/scripts/build_local_target.sh +++ b/.github/scripts/build_local_target.sh @@ -3,6 +3,7 @@ set -e target_name=${TARGET:-"tag_array_64x184"} +flow=${FLOW:-"local"} if [[ -z "$STAGES" ]]; then if [[ "$target_name" == L1MetadataArray_* ]]; then STAGES=("synth_sdc" "synth" "floorplan" "place" "cts" "grt" "generate_abstract") @@ -18,13 +19,13 @@ for stage in ${STAGES[@]} do if [[ -z $SKIP_BUILD ]] ; then echo "query make script target" - bazel query ${target_name}_${stage}_make - bazel query ${target_name}_${stage}_make --output=build + bazel query ${target_name}_${stage}_scripts + bazel query ${target_name}_${stage}_scripts --output=build echo "build make script" - bazel build --subcommands --verbose_failures --sandbox_debug ${target_name}_${stage}_make + bazel build --subcommands --verbose_failures --sandbox_debug ${target_name}_${stage}_scripts fi if [[ -z $SKIP_RUN ]] ; then echo "run make script" - ./bazel-bin/${target_name}_${stage}_make $(if [[ "$stage" != "memory" ]] ; then echo "bazel-" ; fi)${stage} + ./bazel-bin/${target_name}_${stage}_${flow}_script $(if [[ "$stage" != "memory" ]] ; then echo "bazel-" ; fi)${stage} fi done diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4e4a3b7..f3d5567a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,8 +26,8 @@ jobs: run: | buildifier -lint warn -r . - build-stage-target: - name: Build sample stage targets + build-make-target: + name: Build sample make targets runs-on: ubuntu-22.04 defaults: run: @@ -36,11 +36,11 @@ jobs: fail-fast: false matrix: STAGE_TARGET: - - "tag_array_64x184_generate_abstract" - - "L1MetadataArray_test_generate_abstract" - - "L1MetadataArray_full_generate_abstract" - - "L1MetadataArray_test_gds_final" - - "tag_array_64x184_memory" + - "tag_array_64x184_generate_abstract_make" + - "L1MetadataArray_test_generate_abstract_make" + - "L1MetadataArray_full_generate_abstract_make" + - "L1MetadataArray_test_gds_final_make" + - "tag_array_64x184_memory_make" env: DEBIAN_FRONTEND: "noninteractive" steps: @@ -68,8 +68,41 @@ jobs: run: | bazel build --subcommands --verbose_failures --sandbox_debug ${{ matrix.STAGE_TARGET }} - test-make-script-target: - name: Execute sample _make scripts + test-scripts-target-docker: + name: Execute sample _scripts targets with docker flow + runs-on: ubuntu-22.04 + defaults: + run: + shell: bash + strategy: + fail-fast: false + env: + DEBIAN_FRONTEND: "noninteractive" + FLOW: docker + steps: + - name: Print info + run: | + echo "USER: "$(whoami) + echo "PWD: "$(pwd) + ls -la + echo "HOME: "$HOME + docker --version + - name: Checkout bazel-orfs + uses: actions/checkout@v4 + - name: load docker image + run: | + bazel run --subcommands --verbose_failures --sandbox_debug orfs_env + - name: build docker stage targets - tag_array_64x184 + env: + TARGET: tag_array_64x184 + run: .github/scripts/build_local_target.sh + - name: build docker stage targets - L1MetadataArray_test + env: + TARGET: L1MetadataArray_test + run: .github/scripts/build_local_target.sh + + test-scripts-target-local: + name: Execute sample _scripts targets with local flow runs-on: ubuntu-22.04 container: image: ghcr.io/antmicro/openroad-flow-scripts/ubuntu22.04@sha256:b13b35193bec45cb708bd9a5ee3546a7f20378e3c977a4c49f00e9c1c8a71181 @@ -112,8 +145,8 @@ jobs: TARGET: L1MetadataArray_test run: .github/scripts/build_local_target.sh - test-stage-make-targets: - name: Run ORFS using stage targets and _make scrips + test-docker-local-targets: + name: Run ORFS using docker and local flow runs-on: ubuntu-22.04 defaults: run: @@ -132,10 +165,12 @@ jobs: - name: load docker image run: | bazel run --subcommands --verbose_failures --sandbox_debug orfs_env - - name: build synth stage targets - run: | - bazel build --subcommands --verbose_failures --sandbox_debug tag_array_64x184_synth_sdc tag_array_64x184_synth - name: build make target + env: + FLOW: docker + STAGES: synth_sdc synth + run: .github/scripts/build_local_target.sh + - name: prepare scripts for local flow env: SKIP_RUN: 1 run: .github/scripts/build_local_target.sh diff --git a/README.md b/README.md index 80984c4e..7faf560d 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ This repository contains [Bazel](https://bazel.build/) rules for wrapping Physic ## Requirements * [Bazelisk](https://bazel.build/install/bazelisk) or [Bazel](https://bazel.build/install) - if using `bazel`, please refer to `.bazelversion` file for the recommended version of the tool. -* [OpenROAD-flow-scripts](https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts) - **Required only for running `Make` targets** - to use it, `env.sh` file from OpenROAD-flow-scripts has to be sourced or `FLOW_HOME` environmental variable has to be set manually to `OpenROAD-flow-scripts/flow` location. `bazel-orfs` intentionally does not treat OpenROAD-flow-scripts as a installable versioned tool, but prefers to rely on local installation such that it is easy to hack ORFS and OpenROAD. -* [Docker](https://docs.docker.com/get-docker/) - **Required only for running `Stage` targets** +* [OpenROAD-flow-scripts](https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts) - **Required only for running local scripts** - to use it, `env.sh` file from OpenROAD-flow-scripts has to be sourced or `FLOW_HOME` environmental variable has to be set manually to `OpenROAD-flow-scripts/flow` location. `bazel-orfs` intentionally does not treat OpenROAD-flow-scripts as a installable versioned tool, but prefers to rely on local installation such that it is easy to hack ORFS and OpenROAD. +* [Docker](https://docs.docker.com/get-docker/) - **Required for running `Make` targets and Docker scripts** * Docker image with ORFS installation - **Required only for running `Stage` targets** - can be obtained in two ways: * running `bazel run orfs_env` which downloads the docker image from container registry and loads it to docker runtime under name: `openroad/flow-ubuntu22.04-builder:latest` @@ -19,7 +19,7 @@ This repository contains [Bazel](https://bazel.build/) rules for wrapping Physic docker pull ghcr.io/antmicro/openroad-flow-scripts/ubuntu22.04:latest ``` In such case the `docker_image` attribute of `build_openroad` macro must be set to `ghcr.io/antmicro/openroad-flow-scripts/ubuntu22.04:latest` - * Providing different docker image and overriding default used in the flow through `doker_image` attribute of `build_openroad` macro + * Providing different docker image and overriding default used in the flow through `docker_image` attribute of `build_openroad` macro ## Usage @@ -73,38 +73,27 @@ build_openroad( Macro from the example above spawns the following bazel targets: ``` -Stage targets: - //:L1MetadataArray_test_clock_period - //:L1MetadataArray_test_synth_sdc - //:L1MetadataArray_test_synth - //:L1MetadataArray_test_floorplan - //:L1MetadataArray_test_place - //:L1MetadataArray_test_cts - //:L1MetadataArray_test_grt - //:L1MetadataArray_test_generate_abstract - -Memory targets: - //:L1MetadataArray_test_memory +Scripts targets: + //:L1MetadataArray_test_clock_period_scripts + //:L1MetadataArray_test_synth_sdc_scripts + //:L1MetadataArray_test_synth_scripts + //:L1MetadataArray_test_memory_scripts + //:L1MetadataArray_test_floorplan_scripts + //:L1MetadataArray_test_place_scripts + //:L1MetadataArray_test_cts_scripts + //:L1MetadataArray_test_grt_scripts + //:L1MetadataArray_test_generate_abstract_scripts Make targets: //:L1MetadataArray_test_clock_period_make - //:L1MetadataArray_test_clock_period_make_script //:L1MetadataArray_test_synth_sdc_make - //:L1MetadataArray_test_synth_sdc_make_script //:L1MetadataArray_test_synth_make - //:L1MetadataArray_test_synth_make_script //:L1MetadataArray_test_floorplan_make - //:L1MetadataArray_test_floorplan_make_script //:L1MetadataArray_test_place_make - //:L1MetadataArray_test_place_make_script //:L1MetadataArray_test_cts_make - //:L1MetadataArray_test_cts_make_script //:L1MetadataArray_test_grt_make - //:L1MetadataArray_test_grt_make_script //:L1MetadataArray_test_generate_abstract_make - //:L1MetadataArray_test_generate_abstract_make_script //:L1MetadataArray_test_memory_make - //:L1MetadataArray_test_memory_make_script Config generation targets: @@ -143,30 +132,20 @@ For details about targets spawned by this macro please refer to `Implementation` This file contains simple helper functions written in starlark as well as macro `build_openroad()`. The implementation of this macro spawns multiple `genrule` native rules which are responsible for preparing and running ORFS physical design flow targets during bazel build stage. -These are the genrules spawend in this macro: +These are the genrules spawned in this macro: * Config generation targets * Common for the whole design (named: `target_name + “_config”`) * ORFS stage-specific config (named: `target_name + “_” + stage + “_config”`) -* Stage targets (named: `target_name + “_” + stage`) - * Special stage: Memory targets (named: `target_name + “_memory”`) - * Special mock flow: Mock Area targets (named: `target_name + “_” + stage + “_mock_area”`) +* Scripts targets (named: `target_name + “_” + stage + “_scripts”`) + * Prepares local and Docker flow scripts which build the stage * Make targets (named: `target_name + “_” + stage + “_make”`) - -There are two kinds of flows available: -* Docker flow (Stage targets) -* Local flow (Make targets) - -Both docker and local flow does the same thing: for each stage of the physical design flow it writes config files, sets env vars pointing to those files, builds a command line to execute in ORFS environment and runs it through the `entrypoint` script. + * Builds all dependencies required for the stage and generates scripts +* Special mock flow: Mock Area targets (named: `target_name + “_” + stage + “_mock_area”`) #### Docker flow Docker flow uses containerized environment with preinstalled ORFS to run the physical design flow. -Example targets which run the docker flow include: - -* //:L1MetadataArray_test_floorplan -* //:L1MetadataArray_test_memory -* //:tag_array_64x184_synth It implicitly depends on a docker image with installed ORFS environment being present in docker runtime of the machine running bazel targets. The docker image used in the flow defaults to `ghcr.io/antmicro/openroad-flow-scripts/ubuntu22.04:latest`. @@ -176,14 +155,10 @@ Users can also build the image from ORFS sources following [the guide](https://o #### Local flow -The local flow (`_make` bazel targets) depends on the locally installed ORFS. +The local flow depends on the locally installed ORFS. Path to `OpenROAD-flow-scripts/flow` is expected to be specified in `FLOW_HOME` environmental variable. For the installation guide please refer to the [build instructions](https://openroad-flow-scripts.readthedocs.io/en/latest/user/BuildLocally.html). -The local flow relies on `_make` bazel targets which are used to generate shell scripts. -Those shell scripts, apart from facilitating quick tests of ORFS modifications, can be used to run ORFS stages straight from the bazel-orfs repository and to allow tweaking the "moving parts" of the flow, like e.g.: -* Design and stage configs -* Make targets patterns -* entrypoint command line +The local flow relies on `_scripts` bazel targets which are used to generate shell scripts. #### Config files @@ -200,29 +175,33 @@ Both of those scripts have the same responsibility of preparing and entering the `docker_shell` is very similar in that matter except it runs the flow in a docker container. The input and output files for the flow stage are passed to the running container through [bind mounts](https://docs.docker.com/storage/#bind-mounts). -#### Stage Targets +#### Scripts Targets -Main rules for executing each ORFS stage (synthesis, floorplan, clock tree synthesis, place, route, etc.). -The outputs and inputs are different for each ORFS stage and are defined by macro arguments and the implementation of the macro. -Those targets are built with the docker flow. -Before running stage targets it is required to first pull the ORFS docker image into local docker runtime. - -#### Make Targets - -Those scripts are used for local tests of ORFS stages and are built with locally installed ORFS. -Two targets are spawned for each ORFS stage. First generates a shell script, second makes it executable from `bazel-bin` directory. -The final usable script is generated under path: +These rules generate two scripts, one for local flow and other for Docker flow. +They can be found under path: ``` -bazel-bin/_make +bazel-bin/_local_script +bazel-bin/_docker_script ``` -The shell script is produced by `genrule` by concatenating shell shebang line with the entrypoint command. -The entrypoint command consists of a call to `orfs`, essential environment variables definitions (e.g. with paths to generated `config.mk` files) and physical design make targets to execute in ORFS environment. +Shell scripts are produced by `genrule` by concatenating shell shebang line with the entrypoint command. +The entrypoint command consists of a call to `orfs` or `docker_shell`, essential environment variables definitions (e.g. with paths to generated `config.mk` files) and physical design make targets to execute in ORFS environment. Attribute `srcs` of the genrule contains dependencies required for running the script (e.g.: `orfs` script, make target patterns, configs). Those dependencies don't include results of previous flow stages and because of that, it is required to build those before running the generated script. In the second rule (`sh_binary`) for the script is created so that it can be executed straight from the output directory. +Created shell scripts, apart from facilitating quick tests of ORFS modifications, can be used to run ORFS stages straight from the bazel-orfs repository and to allow tweaking the "moving parts" of the flow, like e.g.: +* Design and stage configs +* Make targets patterns +* entrypoint command line + +#### Make Targets + +Targets build all necessary dependencies for chosen stage and both scripts from scripts target. +Those dependencies are built with the docker flow. +Before running stage targets it is required to first pull the ORFS docker image into local docker runtime. + #### Mock Area Targets Those targets are used to create mocked abstracts (LEF files) for macros. @@ -288,11 +267,12 @@ A quick test-build: # Download and load docker image with ORFS bazel run @bazel-orfs//:orfs_env -# Build L1MetadataArray macro up to the CTS stage -bazel build L1MetadataArray_test_cts +# Build L1MetadataArray dependencies for the CTS stage +bazel build L1MetadataArray_test_cts_make -# View results with OpenROAD GUI -bazel run L1MetadataArray_test_cts_gui +# Build CTS stage for L1MetadataArray macro with local of Docker flow +./bazel-bin/L1MetadataArray_test_cts_local_script bazel-cts +./bazel-bin/L1MetadataArray_test_cts_docker_script bazel-cts ``` ### Using the local flow @@ -303,32 +283,22 @@ Example usage of `Make` targets can look like this: Let's assume we want to perform a `floorplan` stage for the `L1MetadataArray` design using the locally built ORFS. -1. Provide all the dependencies for running the target. -``` -bazel build $(bazel query "deps(L1MetadataArray_test_floorplan) except L1MetadataArray_test_floorplan" --noimplicit_deps) -``` - -2. Generate the shell script. +1. Provide all the dependencies for running the target and generate scripts. ``` bazel build L1MetadataArray_test_floorplan_make ``` -3. Source `env.sh` of your local ORFS installation or set the `FLOW_HOME` environment variable to the path to your local `OpenROAD-flow-scripts/flow` directory. +2. Source `env.sh` of your local ORFS installation or set the `FLOW_HOME` environment variable to the path to your local `OpenROAD-flow-scripts/flow` directory. ``` source /env.sh # or export FLOW_HOME=/flow ``` -4. Execute the shell script with ORFS make target relevant to given stage of the flow. +3. Execute the shell script with ORFS make target relevant to given stage of the flow. The script is capable of running all make targets that have the same requirements as e.g. `do-floorplan` target ``` -./bazel-bin/L1MetadataArray_test_floorplan_make do-floorplan -``` - -5. After the build is complete, it is possible to view the results in GUI. -``` -./bazel-bin/L1MetadataArray_test_floorplan_make gui_floorplan +./bazel-bin/L1MetadataArray_test_floorplan_local_script bazel-floorplan ``` ### Tweaking aspect ratio of a floorplan diff --git a/docker_shell.sh b/docker_shell.sh index c7c468bf..e26dfc83 100755 --- a/docker_shell.sh +++ b/docker_shell.sh @@ -14,8 +14,12 @@ function handle_sigterm() { DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -WORKSPACE_ROOT=$(pwd)/../.. -WORKSPACE_EXECROOT=$(pwd) +if [[ $DIR == */external/bazel-orfs~override ]]; then + WORKSPACE_ROOT=$(realpath $DIR/../../../../../../..) +else + WORKSPACE_ROOT=$(realpath $DIR/../../../../..) +fi +WORKSPACE_EXECROOT=$WORKSPACE_ROOT/execroot/_main WORKSPACE_EXTERNAL=$WORKSPACE_ROOT/external XSOCK=/tmp/.X11-unix @@ -23,10 +27,6 @@ XAUTH=/tmp/.docker.xauth xauth nlist :0 | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge - ARGUMENTS=$@ -if test -t 0; then - DOCKER_INTERACTIVE=-ti -fi - export FLOW_HOME="/OpenROAD-flow-scripts/flow/" # Get path to the bazel workspace # Take first symlink from the workspace, follow it and fetch the directory name diff --git a/make_script.template.sh b/make_script.template.sh new file mode 100755 index 00000000..52d7cfd9 --- /dev/null +++ b/make_script.template.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Export location of runfiles directory, to enable Bazel-specific functions +if [[ -z $RUNFILES_DIR ]] && [[ ! -d "$0.runfiles" ]]; then + exec_dir=$(dirname $0) + runfiles_target=`basename $0` + runfiles_target=${runfiles_target/_docker/} + runfiles_target=${runfiles_target/_local/} + if [[ -d "$exec_dir/${runfiles_target}_runfiles.runfiles" ]]; then + export RUNFILES_DIR="$exec_dir/${runfiles_target}_runfiles.runfiles" + elif [[ -d "$exec_dir/${runfiles_target}_make_runfiles.runfiles" ]]; then + export RUNFILES_DIR="$exec_dir/${runfiles_target}_make_runfiles.runfiles" + fi + # ln -sf "$runfiles_target.runfiles" "$0.runfiles" + # if [[ -f "$runfiles_target.runfiles_manifest" ]]; then + # ln -sf "$runfiles_target.runfiles_manifest" "${0}.runfiles_manifest" + # else + # ln -sf "$runfiles_target.exe.runfiles_manifest" "${0}.exe.runfiles_manifest" + # fi +fi +echo "$RUNFILES_DIR" + +# The following lines are imported from Bazel Bash runfiles library +# For more information please refer to the `Make targets` paragraph in the README +set -uo pipefail +set +e +f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || + source "$0.runfiles/$f" 2>/dev/null || + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || + { + echo>&2 "ERROR: cannot find $f" + exit 1 + } +f= +set -e + diff --git a/openroad.bzl b/openroad.bzl index 99747703..96f1a862 100644 --- a/openroad.bzl +++ b/openroad.bzl @@ -234,7 +234,8 @@ def get_entrypoint_cmd( make_targets = None, docker_image = None, mock_area = False, - memory = False): + memory = False, + entrypoint = None): """ Prepare command line for running docker_shell utility @@ -247,21 +248,25 @@ def get_entrypoint_cmd( docker_image: name of the docker image used for running ORFS flow 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 Returns: string with command line for running ORFS flow in docker container """ - entrypoint = None fmt_whitespace = "" cmd = "" if (use_docker_flow): fmt_whitespace = " \\\n" - entrypoint = " $(location " + str(Label("//:docker_shell")) + ")" + fmt_whitespace + if entrypoint == None: + entrypoint = Label("//:docker_shell") + entrypoint = " $(location " + str(entrypoint) + ")" + fmt_whitespace else: fmt_whitespace = " \\\\\n" - entrypoint = " $$(pwd)/$(location " + str(Label("//:orfs")) + ")" + fmt_whitespace + if entrypoint == None: + entrypoint = Label("//:orfs") + entrypoint = " $$(pwd)/$(location " + str(entrypoint) + ")" + fmt_whitespace if (docker_image != None): cmd += "\\\nOR_IMAGE=" + docker_image + fmt_whitespace + " " @@ -359,7 +364,7 @@ def mock_area_stages( tools = [Label("//:docker_shell")], srcs = [make_pattern, design_config, stage_config] + stage_sources[stage] + - ([name + "_" + stage, Label("//:mock_area.tcl")] if stage == "floorplan" else []) + + ([name + "_" + stage + "_build", Label("//:mock_area.tcl")] if stage == "floorplan" else []) + ([name + "_" + previous + "_mock_area"] if stage != "clock_period" else []) + ([name + "_synth_mock_area"] if stage == "floorplan" else []), cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, True, make_targets, docker_image = docker_image, mock_area = (stage == "floorplan"), memory = False), @@ -527,8 +532,8 @@ def build_openroad( macros = set(macros + list(macro_variants.keys())) all_stages = [ ("0", "clock_period"), - ("1", "synth"), ("0", "synth_sdc"), + ("1", "synth"), ("2", "floorplan"), ("3", "place"), ("4", "cts"), @@ -592,7 +597,6 @@ def build_openroad( stage_sources["clock_period"] = [sdc_constraints] stage_sources["synth"] = list(filter(stage_sources["synth"], lambda s: not s.endswith(".sdc"))) stage_sources["synth"] += set(verilog_files) - stage_sources["floorplan"].append(name + target_ext + "_synth") if io_constraints != None: stage_sources["floorplan"].append(io_constraints) stage_sources["place"].append(io_constraints) @@ -629,28 +633,58 @@ def build_openroad( skip = True stages.append(stage) - # Make (local) targets + # _scripts targets design_config = Label("@@//:" + target_name + "_config.mk") for stage in stages: make_pattern = Label("//:" + stage + "-bazel.mk") stage_config = Label("@@//:" + target_name + "_" + stage + "_config.mk") make_targets = get_make_targets(stage, False, mock_area) - entrypoint_cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, False, memory = False) + local_entrypoint_cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, False, memory = False) + docker_entrypoint_cmd = get_entrypoint_cmd( + make_pattern, + design_config, + stage_config, + False, + memory = False, + entrypoint = Label("//:docker_shell"), + docker_image = docker_image, + ) + target_name_stage = target_name + "_" + stage + # Local flow scripts native.genrule( - name = target_name + "_" + stage + "_make_script", + name = target_name_stage + "_make_local_script", tools = [Label("//:orfs")], srcs = [design_config, stage_config, make_pattern], - cmd = "cat < $@ \n#!/bin/bash\n" + entrypoint_cmd + " \\$$@", + cmd = "cat < $@ \n#!/bin/bash\n" + local_entrypoint_cmd + " \\$$@\nEOF", outs = ["logs/%s/%s/%s/make_script_%s.sh" % (platform, out_dir, variant, stage)], ) - native.sh_binary( - name = target_name + "_" + stage + "_make", - srcs = ["//:" + target_name + "_" + stage + "_make_script"], + name = target_name_stage + "_local_script", + srcs = ["//:" + target_name_stage + "_make_local_script"], data = [Label("//:orfs"), design_config, stage_config, make_pattern], ) + # Docker flow scripts + native.genrule( + name = target_name_stage + "_make_docker_script", + tools = [Label("//:docker_shell")], + srcs = [design_config, stage_config, make_pattern], + cmd = "cat < $@ \n#!/bin/bash\n" + docker_entrypoint_cmd + " \\$$@\nEOF", + outs = ["logs/%s/%s/%s/make_docker_script_%s.sh" % (platform, out_dir, variant, stage)], + ) + native.sh_binary( + name = target_name_stage + "_docker_script", + srcs = ["//:" + target_name_stage + "_make_docker_script"], + data = [Label("//:docker_shell"), design_config, stage_config, make_pattern], + ) + + # Scripts target + native.filegroup( + name = target_name_stage + "_scripts", + srcs = [target_name_stage + "_local_script", target_name_stage + "_docker_script"], + ) + # Generate general config for design stage targets write_config( name = target_name + "_config", @@ -670,29 +704,46 @@ def build_openroad( ) make_pattern = Label("//:memory-bazel.mk") stage_config = Label("@@//:" + target_name + "_memory_config.mk") - entrypoint_cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, False, memory = True) + 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) + native.genrule( - name = target_name + "_memory_make_script", + name = target_name + "_memory_make_local_script", tools = [Label("//:orfs")], - srcs = [design_config, stage_config, make_pattern, Label("//scripts:mem_dump.tcl"), Label("//scripts:mem_dump.py")], - cmd = "cat < $@ \n#!/bin/bash\n" + entrypoint_cmd + " \\$$@", - outs = ["logs/%s/%s/%s/make_script_memory.sh" % (platform, out_dir, variant)], + srcs = [design_config, stage_config, make_pattern] + mem_scripts, + cmd = "cat < $@ \n#!/bin/bash\n" + local_entrypoint_cmd + " \\$$@\nEOF", + outs = ["logs/%s/%s/%s/make_local_script_memory.sh" % (platform, out_dir, variant)], ) native.sh_binary( - name = target_name + "_memory_make", - srcs = ["//:" + target_name + "_memory_make_script"], - data = [Label("//:orfs"), design_config, stage_config, make_pattern, Label("//scripts:mem_dump.tcl"), Label("//scripts:mem_dump.py")], + name = target_name + "_memory_local_script", + srcs = ["//:" + target_name + "_memory_make_local_script"], + data = [Label("//:orfs"), design_config, stage_config, make_pattern] + mem_scripts, ) + native.genrule( - name = target_name + "_memory", + name = target_name + "_memory_make_docker_script", tools = [Label("//:docker_shell")], - srcs = [Label("//scripts:mem_dump.py"), Label("//scripts:mem_dump.tcl"), target_name + "_clock_period", design_config, stage_config, make_pattern], - cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, True, "memory", docker_image = docker_image, memory = True), - outs = outs["memory"], - tags = ["supports-graceful-termination"], + srcs = [design_config, stage_config, make_pattern] + mem_scripts, + cmd = "cat < $@ \n#!/bin/bash\n" + docker_entrypoint_cmd + " \\$$@\nEOF", + outs = ["logs/%s/%s/%s/make_docker_script_memory.sh" % (platform, out_dir, variant)], + ) + native.sh_binary( + name = target_name + "_memory_docker_script", + srcs = ["//:" + target_name + "_memory_make_docker_script"], + data = [Label("//:docker_shell"), design_config, stage_config, make_pattern] + mem_scripts, ) - # Stage (Docker) targets + native.filegroup( + name = target_name + "_memory_scripts", + srcs = [target_name + "_memory_local_script", target_name + "_memory_docker_script"], + ) + native.filegroup( + name = target_name + "_memory_make", + srcs = [target_name + "_memory_scripts", target_name + "_clock_period_build"], + ) + + # _make targets for (previous, stage) in zip(["n/a"] + stages, stages): # Generate config for stage targets stage_cfg_srcs = [] @@ -712,12 +763,22 @@ def build_openroad( stage_config = Label("@@//:" + target_name + "_" + stage + "_config.mk") make_targets = get_make_targets(stage, False, mock_area) + # Target building `target_name` `stage` and its dependencies native.genrule( - name = target_name + "_" + stage, + name = target_name + "_" + stage + "_build", tools = [Label("//:docker_shell")], - srcs = [make_pattern, design_config, stage_config] + stage_sources[stage] + ([name + target_ext + "_" + previous] if stage not in ("clock_period", "synth_sdc") else []) + - ([name + target_ext + "_generate_abstract_mock_area"] if mock_area != None and stage == "generate_abstract" else []), + srcs = [make_pattern, design_config, stage_config] + stage_sources[stage] + ([target_name + "_" + previous + "_build"] if stage not in ("clock_period", "synth_sdc") else []) + + ([target_name + "_generate_abstract_mock_area"] if mock_area != None and stage == "generate_abstract" else []), cmd = get_entrypoint_cmd(make_pattern, design_config, stage_config, True, make_targets, docker_image = docker_image, memory = False), outs = outs.get(stage, []), tags = ["supports-graceful-termination"], + visibility = ["//visibility:private"], + ) + + # Target building `target_name` `stage` dependencies and generating `stage` scripts + native.filegroup( + name = target_name + "_" + stage + "_make", + srcs = [target_name + "_" + stage + "_scripts"] + stage_sources[stage] + + ([target_name + "_" + previous + "_build"] if stage not in ("clock_period", "synth_sdc") else []) + + ([target_name + "_generate_abstract_mock_area"] if mock_area != None and stage == "generate_abstract" else []), ) diff --git a/scripts/BUILD b/scripts/BUILD index 04d29882..4df1e678 100644 --- a/scripts/BUILD +++ b/scripts/BUILD @@ -1,2 +1,3 @@ exports_files(["mem_dump.py"]) + exports_files(["mem_dump.tcl"])