From ec4535708b8abde278c512b065396e1018d053cb Mon Sep 17 00:00:00 2001 From: Song Luar Date: Thu, 12 Sep 2024 01:28:41 +0800 Subject: [PATCH] [Autotuner] CI Smoke Test - Tune & Sweep (#2042) * Add CI integration for AT Smoke tests * ci: bump version --------- Signed-off-by: Jack Luar <39641663+luarss@users.noreply.github.com> Signed-off-by: luarss <39641663+luarss@users.noreply.github.com> Signed-off-by: Vitor Bandeira Signed-off-by: luarss Signed-off-by: Vitor Bandeira Co-authored-by: Vitor Bandeira Co-authored-by: Vitor Bandeira --- docker/Dockerfile.builder | 1 + docs/user/InstructionsForAutoTuner.md | 25 +- flow/designs/asap7/gcd/autotuner.json | 2 +- flow/designs/ihp-sg13g2/gcd/autotuner.json | 10 +- flow/designs/sky130hd/gcd/autotuner.json | 1 + flow/test/test_helper.sh | 35 +++ flow/util/genReport.py | 4 +- jenkins/public_nightly.Jenkinsfile | 2 +- jenkins/public_tests_all.Jenkinsfile | 2 +- tools/AutoTuner/.gitignore | 11 +- tools/AutoTuner/RAY_README.md | 246 +++++++++++++++++ tools/AutoTuner/README.md | 247 +----------------- tools/AutoTuner/installer.sh | 5 +- tools/AutoTuner/setup.sh | 16 ++ .../autotuner/distributed-sweep-example.json | 2 +- tools/AutoTuner/src/autotuner/distributed.py | 2 +- tools/AutoTuner/test/smoke_test_sweep.py | 80 ++++++ tools/AutoTuner/test/smoke_test_tune.py | 66 +++++ 18 files changed, 487 insertions(+), 270 deletions(-) create mode 100644 tools/AutoTuner/RAY_README.md mode change 100644 => 120000 tools/AutoTuner/README.md mode change 100644 => 100755 tools/AutoTuner/installer.sh create mode 100755 tools/AutoTuner/setup.sh create mode 100644 tools/AutoTuner/test/smoke_test_sweep.py create mode 100644 tools/AutoTuner/test/smoke_test_tune.py diff --git a/docker/Dockerfile.builder b/docker/Dockerfile.builder index 372739d305..0809e95af2 100644 --- a/docker/Dockerfile.builder +++ b/docker/Dockerfile.builder @@ -33,6 +33,7 @@ COPY --link flow/platforms flow/platforms COPY --link flow/util flow/util COPY --link flow/scripts flow/scripts COPY --link flow/designs flow/designs +COPY --link tools/AutoTuner tools/AutoTuner COPY --link --from=orfs-builder-base /OpenROAD-flow-scripts/tools/install tools/install COPY --link \ diff --git a/docs/user/InstructionsForAutoTuner.md b/docs/user/InstructionsForAutoTuner.md index b7eb374317..c1e2fc1c41 100644 --- a/docs/user/InstructionsForAutoTuner.md +++ b/docs/user/InstructionsForAutoTuner.md @@ -23,18 +23,16 @@ User-defined coefficient values (`coeff_perform`, `coeff_power`, `coeff_area`) o ## Setting up AutoTuner -To setup AutoTuner, make sure you have a virtual environment set up with -Python 3.9.X. There are plenty of ways to do this, we recommend using -[Miniconda](https://docs.conda.io/en/latest/miniconda.html), -which is a free minimal installer for the package manager `conda`. +We have provided two convenience scripts, `./install.sh` and `./setup.sh` +that works in Python3.8 for installation and configuration of AutoTuner, +as shown below: ```shell -# set up conda environment -conda create -n autotuner_env python=3.9 -conda activate autotuner_env +# Install prerequisites +./tools/AutoTuner/install.sh -# install requirements -pip install -r ./tools/AutoTuner/requirements.txt +# Start virtual environment +./tools/AutoTuner/setup.sh ``` ## Input JSON structure @@ -198,6 +196,15 @@ We show three different views possible at the end, namely: `Table View`, `Scatte ![Parallel Coordinate View](../images/Autotuner_best_parameter_view.webp)

Parallel Coordinate View (best run is in green)

+## Testing framework + +Assuming the virtual environment is setup at `./tools/AutoTuner/autotuner_env`: + +``` +./tools/AutoTuner/setup.sh +python3 ./tools/AutoTuner/test/smoke_test_sweep.py +python3 ./tools/AutoTuner/test/smoke_test_tune.py +``` ## Citation diff --git a/flow/designs/asap7/gcd/autotuner.json b/flow/designs/asap7/gcd/autotuner.json index aa07bed2fb..5070c35bb0 100644 --- a/flow/designs/asap7/gcd/autotuner.json +++ b/flow/designs/asap7/gcd/autotuner.json @@ -3,7 +3,7 @@ "_SDC_CLK_PERIOD": { "type": "float", "minmax": [ - 50, + 300, 1000 ], "step": 0 diff --git a/flow/designs/ihp-sg13g2/gcd/autotuner.json b/flow/designs/ihp-sg13g2/gcd/autotuner.json index 85422b5afa..d349a2322f 100644 --- a/flow/designs/ihp-sg13g2/gcd/autotuner.json +++ b/flow/designs/ihp-sg13g2/gcd/autotuner.json @@ -3,8 +3,8 @@ "_SDC_CLK_PERIOD": { "type": "float", "minmax": [ - 1.0, - 4.3647 + 7.0, + 12.0 ], "step": 0 }, @@ -52,7 +52,7 @@ "type": "float", "minmax": [ 0.1, - 0.7 + 0.3 ], "step": 0 }, @@ -60,7 +60,7 @@ "type": "float", "minmax": [ 0.0, - 0.99 + 0.1 ], "step": 0 }, @@ -68,7 +68,7 @@ "type": "int", "minmax": [ 1, - 4 + 1 ], "step": 1 }, diff --git a/flow/designs/sky130hd/gcd/autotuner.json b/flow/designs/sky130hd/gcd/autotuner.json index 9125f73936..6d12dd634d 100644 --- a/flow/designs/sky130hd/gcd/autotuner.json +++ b/flow/designs/sky130hd/gcd/autotuner.json @@ -99,3 +99,4 @@ "step": 0 } } + diff --git a/flow/test/test_helper.sh b/flow/test/test_helper.sh index 8f66aee7fe..0d0ebecd10 100755 --- a/flow/test/test_helper.sh +++ b/flow/test/test_helper.sh @@ -77,4 +77,39 @@ if [ $ret -eq 0 ] && grep -q 'power:' <(echo $TARGETS); then ret=$(( ret + $? )) fi +# Run Autotuner CI specifically for gcd on selected platforms. +RUN_AUTOTUNER=0 +case $DESIGN_NAME in + "gcd") + RUN_AUTOTUNER=1 + ;; +esac +case $PLATFORM in + "asap7" | "sky130hd" | "ihp-sg13g2" ) + # Keep RUN_AUTOTUNER enabled only for these platforms + ;; + *) + RUN_AUTOTUNER=0 + ;; +esac + +if [ $RUN_AUTOTUNER -eq 1 ]; then + # change directory to the root of the repo + echo "Install and starting venv" + cd ../ + ./tools/AutoTuner/installer.sh + . ./tools/AutoTuner/setup.sh + + # remove dashes + PLATFORM=${PLATFORM//-/} + # convert to uppercase + PLATFORM=${PLATFORM^^} + + echo "Running Autotuner smoke tune test" + python3 -m unittest tools.AutoTuner.test.smoke_test_tune.${PLATFORM}TuneSmokeTest.test_tune + + echo "Running Autotuner smoke sweep test" + python3 -m unittest tools.AutoTuner.test.smoke_test_sweep.${PLATFORM}SweepSmokeTest.test_sweep +fi + exit $ret diff --git a/flow/util/genReport.py b/flow/util/genReport.py index f76065eb2d..c6bf63b1ba 100755 --- a/flow/util/genReport.py +++ b/flow/util/genReport.py @@ -246,7 +246,9 @@ def write_summary(): for log_dir, dirs, files in sorted(os.walk(LOGS_FOLDER, topdown=False)): dir_list = log_dir.split(os.sep) - if len(dir_list) != 4: + # Handles autotuner folders, which do not have `report.log` natively. + # TODO: Can we log something for autotuner? + if len(dir_list) != 4 or "test-" in dir_list[-1]: continue report_dir = log_dir.replace(LOGS_FOLDER, REPORTS_FOLDER) diff --git a/jenkins/public_nightly.Jenkinsfile b/jenkins/public_nightly.Jenkinsfile index b8b29bbe6c..b5379370e3 100644 --- a/jenkins/public_nightly.Jenkinsfile +++ b/jenkins/public_nightly.Jenkinsfile @@ -1,4 +1,4 @@ -@Library('utils@orfs-v2.1.0') _ +@Library('utils@orfs-v2.1.1') _ node { diff --git a/jenkins/public_tests_all.Jenkinsfile b/jenkins/public_tests_all.Jenkinsfile index 3a99aec191..214e8e6c62 100644 --- a/jenkins/public_tests_all.Jenkinsfile +++ b/jenkins/public_tests_all.Jenkinsfile @@ -1,4 +1,4 @@ -@Library('utils@orfs-v2.1.0') _ +@Library('utils@orfs-v2.1.1') _ node { diff --git a/tools/AutoTuner/.gitignore b/tools/AutoTuner/.gitignore index 92513ff15e..36ec367c7b 100644 --- a/tools/AutoTuner/.gitignore +++ b/tools/AutoTuner/.gitignore @@ -1,2 +1,11 @@ -# Autotuner specific +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +*.egg-info/ + +# Jupyter Notebook +.ipynb_checkpoints + +# Autotuner env autotuner_env diff --git a/tools/AutoTuner/RAY_README.md b/tools/AutoTuner/RAY_README.md new file mode 100644 index 0000000000..8c9fd33ad0 --- /dev/null +++ b/tools/AutoTuner/RAY_README.md @@ -0,0 +1,246 @@ +# AutoTuner with Ray cluster at GCP + +This documentation shows how to create a Ray cluster on Google Cloud +Kubernetes Engine (i.e., GKE) and the required support infrastructure to +enable AutoTuner to work properly. The documentation is intended to users +with some familiarity with Google Cloud or other cloud services. For +more details on how to use AutoTuner see the main documentation page +[here](https://openroad-flow-scripts.readthedocs.io/en/latest/user/InstructionsForAutoTuner.html). + +## How to use this document + +If you want to create a new cluster, follow the document from begin to end. + +If you want to run experiments on an existing cluster, make sure you have +all the [Prerequisites](#prerequisites) and then you can jump to [Running +Ray programs with Ray Client](#running-ray-programs-with-ray-client). + +## Prerequisites + +- Google Cloud CLI installed, see instructions [here](https://cloud.google.com/sdk/docs/install). +- Access to an existing Google Cloud project with "Editor" permissions to + create the cluster. To use an existing cluster contact the person who + created the cluster. +- `kubectl` installed and available on your PATH. See instructions bellow. + + +Configure `gcloud` to use the Kubernetes credentials of the newly created +cluster. The credentials allow the use of `kubectl` locally. + +```bash +gcloud components install kubectl +``` + +## Enable GKE + +Follow the Google quickstart guide up to the section "Create a GKE cluster" +[here](https://cloud.google.com/kubernetes-engine/docs/quickstart). The +quickstart guide instructs how to enable GKE (Google's Kubernetes Engine) +start a CLI interface and get the settings for your project. + +## Create a Kubernetes cluster + +Create a GKE cluster using the following `gcloud` command as a guide. Note +that each argument defines a characteristic of the cluster. Furthermore, +the cluster and node pool allocate resources that cost money. Hence, be +mindful when choosing the configuration. For additional information see: + +```bash +gcloud beta container clusters create --help +gcloud beta container node-pools create --help +``` + +```bash +gcloud beta container clusters create "autotuner" \ + --machine-type "e2-standard-8" \ + --image-type "UBUNTU_CONTAINERD" \ + --disk-type "pd-standard" \ + --disk-size "100" \ + --num-nodes "1" \ + --enable-autoscaling \ + --min-nodes "1" \ + --max-nodes "10" +``` + +Configure `gcloud` to use the Kubernetes credentials of the newly created +cluster. The credentials allow the use of `kubectl` locally. + +```bash +gcloud container clusters get-credentials autotuner +``` + +Create a new node pool. This step is optional, however, recommended. The +new pool uses preemptive nodes which are not only cheaper, but also have +a more powerful CPU and have more disk space. + +```bash +gcloud beta container node-pools create "worker-pool" \ + --cluster "autotuner" \ + --machine-type "c2-standard-60" \ + --image-type "UBUNTU_CONTAINERD" \ + --disk-type "pd-standard" \ + --disk-size "2000" \ + --preemptible \ + --num-nodes "3" \ + --enable-autoscaling \ + --min-nodes "1" \ + --max-nodes "625" +``` + +## Create NFS and setup mount options + +NOTE: This tutorial requires a working NFS server. + +To access the NFS mount point in the Ray cluster, we use a NFS helm +chart. You need to modify the helm chart with the information about your +server IP and mount point path. + +### Install NFS Kubernetes provisioner + +```bash +helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner +helm repo update +``` + +Before installing the helm chart, double check the fields marked with +`TODO` on the file `./nfs/nfs-helm-values.yaml`. The `server` and `path` +need to match the NFS server IP and the path to the exposed folder. +The `nodeSelector` must match the non-preemptive Kubernetes pool. + +```bash +helm install nfs nfs-subdir-external-provisioner/nfs-subdir-external-provisioner -f nfs/nfs-helm-values.yaml +``` + +### Create a PVC + +Create the PVC: + +```bash +kubectl create -f nfs/nfs-pvc.yaml +``` + +## Ray cluster + +The two main files for the helm chart are: + +```bash +helm-chart/templates/raycluster.yaml +helm-chart/values.yaml +``` + +You can restrict the node pool your AutoTuner jobs will use. To create +this policy, replace POOL_NAME with the name of the pool you created on +the previous step. For this tutorial we use `worker-pool`. + +```yaml +nodeSelector: + cloud.google.com/gke-nodepool: POOL_NAME +``` + +### Deploy Ray cluster inside Kubernetes + +Use Helm to deploy a Ray cluster. + +```bash +helm install autotuner ./helm-chart +``` + +### Upgrade deployment + +After the initial deployment, if you change the values inside `./helm-chart` +you need to upgrade the configuration stored at the Kubernetes cluster. + +```bash +helm upgrade autotuner ./helm-chart +``` + +### Useful ways to observe + +Ray dashboard: + +```bash +kubectl port-forward service/autotuner-ray-head 8265 +``` + +Overall cluster status: + +```bash +kubectl get nodes,rayclusters,pods,services,replicaset,pvc,pv +``` + +Ray auto-scaler logs: + +```bash +kubectl logs \ + $(kubectl get pod -l cluster.ray.io/component=operator -o custom-columns=:metadata.name) \ + --tail=100 -f +``` + +### Remove + +First, delete the `RayCluster` custom resource. + +```bash +kubectl delete raycluster autotuner +``` + +Delete the Ray release. + +```bash +helm uninstall autotuner +``` + +## Running Ray programs with Ray Client + +Currently there are three different ways to launch a job on the GKE cluster. +All three methods depend on having `kubectl` installed and correctly setup. + +To configure `gcloud` to use the Kubernetes credentials of a existing cluster. + +```bash +gcloud components install kubectl +gcloud container clusters get-credentials autotuner +``` + +### Using port forwarding + +NOTE: Ray requires that the version of Python on the server and locally +match. The current `openroad/ray` image has Python 3.7.7, make sure your +local machine has at least Python 3.7.x before continuing. + +```bash +pip3 install -U --user 'ray[default,tune]==1.11.0' ax-platform hyperopt nevergrad optuna pandas +pip3 install -U --user colorama==0.4.4 bayesian-optimization==1.4.0 +``` + +Start the port forwarding: + +```bash +kubectl port-forward service/autotuner-ray-head 10001 +``` + +Run the test script locally: + +```bash +python3 kubernetes/run.py +``` + +### Connecting to head node + +Instead of depending on your local environment, you can connect to the head +node of the Ray cluster and run the scripts from there. + +```bash +kubectl exec -it $(kubectl get pod -l cluster.ray.io/component=autotuner-ray-head -o custom-columns=:metadata.name) -- bash +wget https://raw.githubusercontent.com/The-OpenROAD-Project/OpenROAD-flow-scripts/master/tools/AutoTuner/kubernetes/run.py +python run.py +``` + +### Using Kubernetes job submit + +Finally, if you do not wish to keep a terminal session open, you can submit +a Kubernetes job. + +```bash +kubectl create -f kubernetes/submit.yaml +``` diff --git a/tools/AutoTuner/README.md b/tools/AutoTuner/README.md deleted file mode 100644 index 8c9fd33ad0..0000000000 --- a/tools/AutoTuner/README.md +++ /dev/null @@ -1,246 +0,0 @@ -# AutoTuner with Ray cluster at GCP - -This documentation shows how to create a Ray cluster on Google Cloud -Kubernetes Engine (i.e., GKE) and the required support infrastructure to -enable AutoTuner to work properly. The documentation is intended to users -with some familiarity with Google Cloud or other cloud services. For -more details on how to use AutoTuner see the main documentation page -[here](https://openroad-flow-scripts.readthedocs.io/en/latest/user/InstructionsForAutoTuner.html). - -## How to use this document - -If you want to create a new cluster, follow the document from begin to end. - -If you want to run experiments on an existing cluster, make sure you have -all the [Prerequisites](#prerequisites) and then you can jump to [Running -Ray programs with Ray Client](#running-ray-programs-with-ray-client). - -## Prerequisites - -- Google Cloud CLI installed, see instructions [here](https://cloud.google.com/sdk/docs/install). -- Access to an existing Google Cloud project with "Editor" permissions to - create the cluster. To use an existing cluster contact the person who - created the cluster. -- `kubectl` installed and available on your PATH. See instructions bellow. - - -Configure `gcloud` to use the Kubernetes credentials of the newly created -cluster. The credentials allow the use of `kubectl` locally. - -```bash -gcloud components install kubectl -``` - -## Enable GKE - -Follow the Google quickstart guide up to the section "Create a GKE cluster" -[here](https://cloud.google.com/kubernetes-engine/docs/quickstart). The -quickstart guide instructs how to enable GKE (Google's Kubernetes Engine) -start a CLI interface and get the settings for your project. - -## Create a Kubernetes cluster - -Create a GKE cluster using the following `gcloud` command as a guide. Note -that each argument defines a characteristic of the cluster. Furthermore, -the cluster and node pool allocate resources that cost money. Hence, be -mindful when choosing the configuration. For additional information see: - -```bash -gcloud beta container clusters create --help -gcloud beta container node-pools create --help -``` - -```bash -gcloud beta container clusters create "autotuner" \ - --machine-type "e2-standard-8" \ - --image-type "UBUNTU_CONTAINERD" \ - --disk-type "pd-standard" \ - --disk-size "100" \ - --num-nodes "1" \ - --enable-autoscaling \ - --min-nodes "1" \ - --max-nodes "10" -``` - -Configure `gcloud` to use the Kubernetes credentials of the newly created -cluster. The credentials allow the use of `kubectl` locally. - -```bash -gcloud container clusters get-credentials autotuner -``` - -Create a new node pool. This step is optional, however, recommended. The -new pool uses preemptive nodes which are not only cheaper, but also have -a more powerful CPU and have more disk space. - -```bash -gcloud beta container node-pools create "worker-pool" \ - --cluster "autotuner" \ - --machine-type "c2-standard-60" \ - --image-type "UBUNTU_CONTAINERD" \ - --disk-type "pd-standard" \ - --disk-size "2000" \ - --preemptible \ - --num-nodes "3" \ - --enable-autoscaling \ - --min-nodes "1" \ - --max-nodes "625" -``` - -## Create NFS and setup mount options - -NOTE: This tutorial requires a working NFS server. - -To access the NFS mount point in the Ray cluster, we use a NFS helm -chart. You need to modify the helm chart with the information about your -server IP and mount point path. - -### Install NFS Kubernetes provisioner - -```bash -helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner -helm repo update -``` - -Before installing the helm chart, double check the fields marked with -`TODO` on the file `./nfs/nfs-helm-values.yaml`. The `server` and `path` -need to match the NFS server IP and the path to the exposed folder. -The `nodeSelector` must match the non-preemptive Kubernetes pool. - -```bash -helm install nfs nfs-subdir-external-provisioner/nfs-subdir-external-provisioner -f nfs/nfs-helm-values.yaml -``` - -### Create a PVC - -Create the PVC: - -```bash -kubectl create -f nfs/nfs-pvc.yaml -``` - -## Ray cluster - -The two main files for the helm chart are: - -```bash -helm-chart/templates/raycluster.yaml -helm-chart/values.yaml -``` - -You can restrict the node pool your AutoTuner jobs will use. To create -this policy, replace POOL_NAME with the name of the pool you created on -the previous step. For this tutorial we use `worker-pool`. - -```yaml -nodeSelector: - cloud.google.com/gke-nodepool: POOL_NAME -``` - -### Deploy Ray cluster inside Kubernetes - -Use Helm to deploy a Ray cluster. - -```bash -helm install autotuner ./helm-chart -``` - -### Upgrade deployment - -After the initial deployment, if you change the values inside `./helm-chart` -you need to upgrade the configuration stored at the Kubernetes cluster. - -```bash -helm upgrade autotuner ./helm-chart -``` - -### Useful ways to observe - -Ray dashboard: - -```bash -kubectl port-forward service/autotuner-ray-head 8265 -``` - -Overall cluster status: - -```bash -kubectl get nodes,rayclusters,pods,services,replicaset,pvc,pv -``` - -Ray auto-scaler logs: - -```bash -kubectl logs \ - $(kubectl get pod -l cluster.ray.io/component=operator -o custom-columns=:metadata.name) \ - --tail=100 -f -``` - -### Remove - -First, delete the `RayCluster` custom resource. - -```bash -kubectl delete raycluster autotuner -``` - -Delete the Ray release. - -```bash -helm uninstall autotuner -``` - -## Running Ray programs with Ray Client - -Currently there are three different ways to launch a job on the GKE cluster. -All three methods depend on having `kubectl` installed and correctly setup. - -To configure `gcloud` to use the Kubernetes credentials of a existing cluster. - -```bash -gcloud components install kubectl -gcloud container clusters get-credentials autotuner -``` - -### Using port forwarding - -NOTE: Ray requires that the version of Python on the server and locally -match. The current `openroad/ray` image has Python 3.7.7, make sure your -local machine has at least Python 3.7.x before continuing. - -```bash -pip3 install -U --user 'ray[default,tune]==1.11.0' ax-platform hyperopt nevergrad optuna pandas -pip3 install -U --user colorama==0.4.4 bayesian-optimization==1.4.0 -``` - -Start the port forwarding: - -```bash -kubectl port-forward service/autotuner-ray-head 10001 -``` - -Run the test script locally: - -```bash -python3 kubernetes/run.py -``` - -### Connecting to head node - -Instead of depending on your local environment, you can connect to the head -node of the Ray cluster and run the scripts from there. - -```bash -kubectl exec -it $(kubectl get pod -l cluster.ray.io/component=autotuner-ray-head -o custom-columns=:metadata.name) -- bash -wget https://raw.githubusercontent.com/The-OpenROAD-Project/OpenROAD-flow-scripts/master/tools/AutoTuner/kubernetes/run.py -python run.py -``` - -### Using Kubernetes job submit - -Finally, if you do not wish to keep a terminal session open, you can submit -a Kubernetes job. - -```bash -kubectl create -f kubernetes/submit.yaml -``` diff --git a/tools/AutoTuner/README.md b/tools/AutoTuner/README.md new file mode 120000 index 0000000000..0710f55115 --- /dev/null +++ b/tools/AutoTuner/README.md @@ -0,0 +1 @@ +../../docs/user/InstructionsForAutoTuner.md \ No newline at end of file diff --git a/tools/AutoTuner/installer.sh b/tools/AutoTuner/installer.sh old mode 100644 new mode 100755 index 043b13ca03..c694715511 --- a/tools/AutoTuner/installer.sh +++ b/tools/AutoTuner/installer.sh @@ -2,11 +2,10 @@ # Get the directory where the script is located script_dir="$(dirname "${BASH_SOURCE[0]}")" -cd $script_dir # Define the virtual environment name venv_name="autotuner_env" -python${required_version} -m venv "$script_dir/$venv_name" +python3 -m venv "$script_dir/$venv_name" source "$script_dir/$venv_name/bin/activate" -pip3 install -U -r requirements.txt +pip3 install -U -r $script_dir/requirements.txt deactivate diff --git a/tools/AutoTuner/setup.sh b/tools/AutoTuner/setup.sh new file mode 100755 index 0000000000..1dc969d995 --- /dev/null +++ b/tools/AutoTuner/setup.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Get the directory of the current script +script_dir="$(dirname "${BASH_SOURCE[0]}")" + +# Check if the activation script exists +venv_path="$script_dir/autotuner_env/bin/activate" +if [ ! -f "$venv_path" ]; then + echo "Error: Virtual environment activation script not found at $venv_path" + echo "Please run installer.sh for installing the packages." + exit 1 +fi + +# Source the activation script to activate the virtual environment +source "$venv_path" +echo "Virtual environment activated successfully." diff --git a/tools/AutoTuner/src/autotuner/distributed-sweep-example.json b/tools/AutoTuner/src/autotuner/distributed-sweep-example.json index a9fd6bd970..4402ae925d 100644 --- a/tools/AutoTuner/src/autotuner/distributed-sweep-example.json +++ b/tools/AutoTuner/src/autotuner/distributed-sweep-example.json @@ -3,7 +3,7 @@ "type": "int", "minmax": [ 50, - 60 + 54 ], "step": 1 } diff --git a/tools/AutoTuner/src/autotuner/distributed.py b/tools/AutoTuner/src/autotuner/distributed.py index c6ed57eab6..80caf13a3e 100644 --- a/tools/AutoTuner/src/autotuner/distributed.py +++ b/tools/AutoTuner/src/autotuner/distributed.py @@ -526,7 +526,7 @@ def openroad(base_dir, parameters, flow_variant, path=""): log_path = report_path = os.getcwd() + "/" export_command = f"export PATH={INSTALL_PATH}/OpenROAD/bin" - export_command += f":{INSTALL_PATH}/yosys/bin" + export_command += f":{INSTALL_PATH}/yosys/bin:$PATH" export_command += " && " make_command = export_command diff --git a/tools/AutoTuner/test/smoke_test_sweep.py b/tools/AutoTuner/test/smoke_test_sweep.py new file mode 100644 index 0000000000..7a1b013911 --- /dev/null +++ b/tools/AutoTuner/test/smoke_test_sweep.py @@ -0,0 +1,80 @@ +import unittest +import subprocess +import os +import json + +cur_dir = os.path.dirname(os.path.abspath(__file__)) +src_dir = os.path.join(cur_dir, "../src/autotuner") +os.chdir(src_dir) + + +class BaseSweepSmokeTest(unittest.TestCase): + platform = "" + design = "" + + def setUp(self): + self.config = "distributed-sweep-example.json" + # make sure this json only has 1 key called "CTS_CLUSTER_SIZE" and 4 possible values + with open(self.config) as f: + contents = json.load(f) + assert len(contents.keys()) == 1, "Must be size 1" + assert "CTS_CLUSTER_SIZE" in contents, "Must have key CTS_CLUSTER_SIZE" + assert ( + contents["CTS_CLUSTER_SIZE"]["minmax"][1] + - contents["CTS_CLUSTER_SIZE"]["minmax"][0] + ) / contents["CTS_CLUSTER_SIZE"][ + "step" + ] == 4, "Must have only 4 possible values" + + # limit jobs because ray.get() does not terminate if jobs > number of samples + core = os.cpu_count() + self.jobs = 4 if core >= 4 else core + self.experiment = f"smoke-test-sweep-{self.platform}" + self.command = ( + "python3 distributed.py" + f" --design {self.design}" + f" --platform {self.platform}" + f" --experiment {self.experiment}" + f" --config {self.config}" + f" --jobs {self.jobs}" + f" sweep" + ) + + def test_sweep(self): + raise NotImplementedError( + "This method needs to be implemented in the derivative classes." + ) + + +class ASAP7SweepSmokeTest(BaseSweepSmokeTest): + platform = "asap7" + design = "gcd" + + def test_sweep(self): + out = subprocess.run(self.command, shell=True, check=True) + successful = out.returncode == 0 + self.assertTrue(successful) + + +class SKY130HDSweepSmokeTest(BaseSweepSmokeTest): + platform = "sky130hd" + design = "gcd" + + def test_sweep(self): + out = subprocess.run(self.command, shell=True, check=True) + successful = out.returncode == 0 + self.assertTrue(successful) + + +class IHPSG13G2SweepSmokeTest(BaseSweepSmokeTest): + platform = "ihp-sg13g2" + design = "gcd" + + def test_sweep(self): + out = subprocess.run(self.command, shell=True, check=True) + successful = out.returncode == 0 + self.assertTrue(successful) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/AutoTuner/test/smoke_test_tune.py b/tools/AutoTuner/test/smoke_test_tune.py new file mode 100644 index 0000000000..0fcdc6419e --- /dev/null +++ b/tools/AutoTuner/test/smoke_test_tune.py @@ -0,0 +1,66 @@ +import unittest +import subprocess +import os + +cur_dir = os.path.dirname(os.path.abspath(__file__)) +src_dir = os.path.join(cur_dir, "../src/autotuner") +os.chdir(src_dir) + + +class BaseTuneSmokeTest(unittest.TestCase): + platform = "" + design = "" + + def setUp(self): + self.config = os.path.join( + cur_dir, + f"../../../flow/designs/{self.platform}/{self.design}/autotuner.json", + ) + self.experiment = f"smoke-test-tune-{self.platform}" + self.command = ( + "python3 distributed.py" + f" --design {self.design}" + f" --platform {self.platform}" + f" --experiment {self.experiment}" + f" --config {self.config}" + f" tune --samples 1" + ) + + def test_tune(self): + raise NotImplementedError( + "This method needs to be implemented in the derivative classes." + ) + + +class ASAP7TuneSmokeTest(BaseTuneSmokeTest): + platform = "asap7" + design = "gcd" + + def test_tune(self): + out = subprocess.run(self.command, shell=True, check=True) + successful = out.returncode == 0 + self.assertTrue(successful) + + +class SKY130HDTuneSmokeTest(BaseTuneSmokeTest): + platform = "sky130hd" + design = "gcd" + + def test_tune(self): + out = subprocess.run(self.command, shell=True, check=True) + successful = out.returncode == 0 + self.assertTrue(successful) + + +class IHPSG13G2TuneSmokeTest(BaseTuneSmokeTest): + platform = "ihp-sg13g2" + design = "gcd" + + def test_tune(self): + out = subprocess.run(self.command, shell=True, check=True) + successful = out.returncode == 0 + self.assertTrue(successful) + + +if __name__ == "__main__": + unittest.main()