From ab39ea1217c6b80a4253c3b7c469d951f2d9a442 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 18 Jun 2025 07:34:03 -0500 Subject: [PATCH 01/71] [AOMP] Split aomp_utils out of aomp_common_vars This patch splits aomp_utils (shell utility functions) out of aomp_common_vars, in preparation for adding lots more non-configuration-related stuff to the new file. This is mostly straightfoward, but build scripts, etc. need to source the new file also as well as aomp_common_vars. --- bin/CBL_run_sollve.sh | 1 + bin/aomp_common_vars | 301 -------------------------- bin/aomp_utils | 305 +++++++++++++++++++++++++++ bin/build-deb-aomp.sh | 1 + bin/build-rpm.sh | 1 + bin/build_amdsmi.sh | 1 + bin/build_aomp.sh | 1 + bin/build_bolt.sh | 1 + bin/build_comgr.sh | 1 + bin/build_extras.sh | 1 + bin/build_fixups.sh | 1 + bin/build_flang-classic.sh | 1 + bin/build_flang.sh | 1 + bin/build_flang_runtime.sh | 1 + bin/build_hipamd.sh | 1 + bin/build_hipcc.sh | 1 + bin/build_hipfort.sh | 1 + bin/build_hipify.sh | 1 + bin/build_libdevice.sh | 1 + bin/build_llvm-classic.sh | 1 + bin/build_offload.sh | 1 + bin/build_openmp.sh | 1 + bin/build_pgmath.sh | 1 + bin/build_project.sh | 1 + bin/build_qmcpack.sh | 1 + bin/build_rocdbgapi.sh | 1 + bin/build_rocgdb.sh | 1 + bin/build_rocm-cmake.sh | 1 + bin/build_rocm_smi_lib.sh | 1 + bin/build_rocminfo.sh | 1 + bin/build_rocprofiler-register.sh | 1 + bin/build_rocprofiler-sdk.sh | 1 + bin/build_rocprofiler.sh | 1 + bin/build_rocr.sh | 1 + bin/build_roct.sh | 1 + bin/build_roctracer.sh | 1 + bin/build_supp.sh | 1 + bin/build_supp_llvm-flang.sh | 1 + bin/check_amdgpu_modversion.sh | 1 + bin/check_omptests.sh | 1 + bin/check_openmpvv.sh | 1 + bin/check_sollve.sh | 1 + bin/clone_aomp.sh | 1 + bin/clone_epsdb_test.sh | 1 + bin/clone_test.sh | 1 + bin/rocmlibs/build_half.sh | 1 + bin/rocmlibs/build_hipBLAS-common.sh | 1 + bin/rocmlibs/build_hipBLAS.sh | 1 + bin/rocmlibs/build_hipRAND.sh | 1 + bin/rocmlibs/build_hipSOLVER.sh | 1 + bin/rocmlibs/build_powerinfer.sh | 1 + bin/rocmlibs/build_rccl.sh | 1 + bin/rocmlibs/build_rocBLAS.sh | 1 + bin/rocmlibs/build_rocPRIM.sh | 1 + bin/rocmlibs/build_rocRAND.sh | 1 + bin/rocmlibs/build_rocSOLVER.sh | 1 + bin/rocmlibs/build_rocSPARSE.sh | 1 + bin/rocmlibs/build_rocmlibs.sh | 1 + bin/rocmlibs/clone_rocmlibs.sh | 1 + bin/rocmlibs/test_powerinfer.sh | 1 + bin/run_Fnekbone.sh | 1 + bin/run_OpenMP_VV.sh | 3 +- bin/run_RSBench.sh | 1 + bin/run_XSBench.sh | 1 + bin/run_accel2023.sh | 1 + bin/run_babelstream.sh | 1 + bin/run_composable-kernels.sh | 2 + bin/run_fBabel.sh | 1 + bin/run_genasis.sh | 1 + bin/run_genasis_flang_new.sh | 1 + bin/run_gests.sh | 1 + bin/run_hpc2021.sh | 1 + bin/run_hpcg.sh | 1 + bin/run_miniQMC.sh | 2 + bin/run_nekbone.sh | 1 + bin/run_nio.sh | 1 + bin/run_omptests.sh | 1 + bin/run_openlibm_test.sh | 1 + bin/run_openmpapps.sh | 1 + bin/run_ovo.sh | 1 + bin/run_rajaperf.sh | 1 + bin/run_rushlarsen.sh | 1 + bin/run_sollve.sh | 1 + bin/run_su3bench.sh | 1 + bin/run_umt.sh | 1 + 85 files changed, 391 insertions(+), 302 deletions(-) create mode 100644 bin/aomp_utils diff --git a/bin/CBL_run_sollve.sh b/bin/CBL_run_sollve.sh index e1b578cd18..ca6b8ba1a0 100755 --- a/bin/CBL_run_sollve.sh +++ b/bin/CBL_run_sollve.sh @@ -21,6 +21,7 @@ export EFFLAGS="-ffree-form -ffree-line-length-none" # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/aomp_common_vars b/bin/aomp_common_vars index 9ae09efd26..0e30014d20 100644 --- a/bin/aomp_common_vars +++ b/bin/aomp_common_vars @@ -242,33 +242,6 @@ else fi fi -# Quote argument list suitable for passing as a single (string) argument to -# cmake. Result can be used within a double-quoted string, i.e. using -# "$(cmquot ...)". -function cmquot() { - local escaped_flags - local escaped_flag - local flag - escaped_flags=() - for flag in "$@"; do - escaped_flag=$(printf "%s" "$flag" | sed 's/\\/\\\\/g; s/\$/\\$/g; s/ /\\ /g; s/"/\\"/g') - escaped_flags+=("$escaped_flag") - done - echo "${escaped_flags[*]}" -} - -# Quote argument list suitable for passing back to the shell as a string. -# Useful for e.g. dumping argument lists in such a way that they can be safely -# copy & pasted into the user's terminal. Output should not be further quoted. -function shquot() { - local -a output - output=() - for arg in "$@"; do - output+=(\'${arg//\'/\'\\\'\'}\') - done - printf '%s' "${output[*]}" -} - # AOMP uses RPATH (not) RUNPATH because LD_LIBRARY_PATH is a user feature for # user lib development. We do not want the compiler runtime to search user paths # first because we want assurance to recreate reported compiler runtime fails. @@ -568,277 +541,3 @@ if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then fi fi -function check_writable_installdir() { - local action=$1 - local installdir=$2 - - # Make sure we can update the install directory - if [ "$action" == "install" ] ; then - $SUDO mkdir -p "$installdir" - - if ! $SUDO touch "$installdir/testfile"; then - echo "ERROR: No update access to $installdir" - exit 1 - fi - $SUDO rm "$installdir/testfile" - fi -} - -# TO use this function set variables patchdir and patchfile -function patchrepo(){ -patchdir=$1 -if [ "$AOMP_APPLY_ROCM_PATCHES" == 1 ] && [ -d "$patchdir" ] ; then - patches="" - cd "$patchdir" || exit - if [[ "$2" =~ "postinstall" ]]; then - getpatchlist "$2" - else - getpatchlist - fi - - #loop through list of patches to apply - if [ "$patches" != "" ] ; then - patchloc=${AOMP_PATCH_CONTROL_FILE%/*} - echo "patchloc=$patchloc" - for patch in $patches; do - patchfile=$patchloc/$patch - if [ ! -f "$patchfile" ] ; then - echo - echo "ERROR: Patch $patchfile does not exist" - echo " It is referenced in ${AOMP_PATCH_CONTROL_FILE}" - exit 1 - fi - - echo "Testing patch $patchfile to $patchdir" - - applypatch="yes" - if ! patch -p1 -t -N --dry-run <"$patchfile" >/dev/null; then - applypatch="no" - # Check to see if reverse patch applies cleanly - if patch -p1 -R --dry-run -t <"$patchfile" >/dev/null; then - echo "patch $patchfile was already applied to $patchdir" - else - echo - echo "ERROR: Patch $patchfile will not apply" - echo " cleanly to directory $patchdir" - echo " Check if it was already applied." - echo - exit 1 - fi - fi - if [ "$applypatch" == "yes" ] ; then - echo "Applying patch $patchfile to $patchdir" - patch -p1 --no-backup-if-mismatch <"$patchfile" - fi - done - fi -fi - -} - -function removepatch(){ -patchdir=$1 -if [ "$AOMP_APPLY_ROCM_PATCHES" == 1 ] && [ -d "$patchdir" ] ; then - patches="" - cd "$patchdir" || exit - getpatchlist - if [ "$patches" != "" ] ; then - echo "Patchdir $patchdir" - echo "PATCHES TO REMOVE: $patches" - fi - patchloc=${AOMP_PATCH_CONTROL_FILE%/*} - if [ "$patches" != "" ] ; then - for patch in $patches; do - patchfile=$patchloc/$patch - echo "Testing reverse patch $patchfile to $patchdir" - reversepatch="yes" - # Check to see if reverse patch applies cleanly - - if ! patch -p1 -R --dry-run -f <"$patchfile" >/dev/null; then - echo "patch $patchfile was NOT applied $patchdir, no patch to reverse" - reversepatch="no" - fi - if [ "$reversepatch" == "yes" ] ; then - echo "Reversing patch $patchfile to $patchdir" - patch -p1 -R -f --no-backup-if-mismatch <"$patchfile" - fi - done - fi -fi -} - -function getpatchlist(){ - currdir=$(pwd) - basedir=$(basename "$currdir") - if [[ "$1" =~ "postinstall" ]]; then - reporegex="(^$1:\s)" - else - reporegex="(^$basedir:\s)" - fi - echo "FILE: $AOMP_PATCH_CONTROL_FILE" - echo "regex $reporegex" - #read patch control file and look for correct patches - while read -r line; do - if [[ "$line" =~ $reporegex ]]; then - #remove basename from list of patches - patches=${line/"${BASH_REMATCH[1]}"} - echo "patches: $patches" - break - fi - done < "$AOMP_PATCH_CONTROL_FILE" -} - -function setaompgpu (){ - if [[ -e "$AOMP/../../bin/rocm_agent_enumerator" ]]; then - echo Set AOMP_GPU with ../.. rocm_agent_enumerator. - detected_gpu=$("$AOMP"/../../bin/rocm_agent_enumerator | grep -m 1 -E 'gfx[^0]{1}.{2}') - elif [[ -e "$AOMP/../bin/rocm_agent_enumerator" ]]; then - echo Set AOMP_GPU with .. rocm_agent_enumerator. - detected_gpu=$("$AOMP"/../bin/rocm_agent_enumerator | grep -m 1 -E 'gfx[^0]{1}.{2}') - elif [[ "$AOMP" =~ "opt" ]]; then - echo Set AOMP_GPU with rocm_agent_enumerator. - detected_gpu=$("$AOMP"/../bin/rocm_agent_enumerator | grep -m 1 -E 'gfx[^0]{1}.{2}') - else - echo Set AOMP_GPU with rocm_agent_enumerator. - if [ -a "$AOMP"/bin/rocm_agent_enumerator ]; then - detected_gpu=$("$AOMP"/bin/rocm_agent_enumerator | grep -m 1 -E 'gfx[^0]{1}.{2}') - elif [ -a "$AOMP"/bin/amdgpu-arch ]; then - detected_gpu=$("$AOMP"/bin/amdgpu-arch) - detected_gpu=$(echo "$detected_gpu" | awk '{print $1,$5}') - detected_gpu=$(echo "$detected_gpu" | cut -d" " -f1) # pick first found - elif [ -e "$AOMP"/../bin/mygpu ]; then - detected_gpu=$("$AOMP"/../bin/mygpu) - else - echo "Error: in setaompgpu, could not find rocm_agent_enumerator" - echo " Set AOMP_GPU, AOMP, or install ROCm" - exit 1 - fi - fi - - AOMP_GPU=${AOMP_GPU:-$detected_gpu} - export AOMP_GPU - echo "AOMP_GPU = $AOMP_GPU" - echo "AOMP = $AOMP" - - if [ "$AOMP_GPU" == "" ] || [ "$AOMP_GPU" == "unknown" ]; then - echo Error: AOMP_GPU not properly set...exiting. - exit 1 - fi -} - -# GPUs which need HSA_XNACK=1 to be set for USM to work. The canonical place -# this info is stored in these scripts is in test/Makefile.defs (SUPPORTS_USM). -# We use a tiny custom makefile to extract the info. -# Usage: -# if gpu_needs_xnack_for_usm "$GPU"; then ...; fi - -function gpu_needs_xnack_for_usm(){ - local needs_usm - needs_usm=$(make -s -C "$thisdir"/../test -f USM_check.make GPU="$1") - case "$needs_usm" in - true) - return 0 - ;; - false) - return 1 - ;; - *) - return 2 - ;; - esac -} - -# Return success (0) if ROCR_VISIBLE_DEVICES (or the first GPU if it is unset) -# refers to an APU, as indicated by rocminfo returning -# "Coherent Host Access: TRUE" for the device, else return failure (1). - -function is_apu(){ - local device_num=${ROCR_VISIBLE_DEVICES:-0} - local cha - cha=$(ROCR_VISIBLE_DEVICES="$device_num" rocminfo | grep -m 1 -F "Coherent Host Access:") - if [[ "$cha" =~ Coherent\ Host\ Access:[[:blank:]]+(TRUE|FALSE) ]]; then - case "${BASH_REMATCH[1]}" in - TRUE) - return 0 - ;; - FALSE) - return 1 - ;; - esac - else - # If we don't see the above pattern in rocminfo output, it's probably not - # an APU. - return 1 - fi -} - -function help_build_aomp(){ - /bin/cat 2>&1 <<"EOF" - - The build scripts in this directory are used to build AOMP. - - Repositories: - Many repositories are used to build AOMP. The script clone_aomp.sh will - clone all the necessary repositories as subdirectories of the directory - $HOME/git/aomp11. The web repository locations and the required branches - are set with the file aomp_common_vars - - Build all components: - To build all components, run these commands: - - ./clone_aomp.sh - unset LD_LIBRARY_PATH - ./build_aomp.sh - - Component builds: - Developers can rebuild individual components by running the build script for - that component. Make sure dependent components are built first. You can run - build_aomp.sh to build call components in the correct order orsee the README.md - file in this directory for the required order. - - Each build script can run with no arguments or with a single argument - "install" or "nocmake". Running with no options starts fresh with an empty - component build directory. It then runs cmake with the correct cmake options - then it runs make with a proper -j option. - - Optional Arguments 'nocmake' and 'install' : - The 'nocmake' or 'install' options can only be used after your initial build - with no options. The 'nocmake' option is intended to restart make after - you fix code following a failed build. The 'install' option will run 'make' - and 'make install' causing installation into the directory $AOMP_INSTALL_DIR. - The 'install' option will also create a symbolic link to directory $AOMP. - - Environment Variables: - You can set environment variables to override behavior of the build scripts - NAME DEFAULT DESCRIPTION - ---- ------- ----------- - AOMP $HOME/rocm/aomp Where the compiler will be installed - AOMP_REPOS $HOME/git/aomp11 Location of all aomp repos - BUILD_TYPE Release The CMAKE build type - BUILD_AOMP same as AOMP_REPOS Set a different build location than AOMP_REPOS - AOMP_USE_NINJA 0 Use ninja if possible - - To build a debug version of the compiler, run this command before the build: - export BUILD_TYPE=debug - - The BUILD_AOMP Envronment Variable: - The build scripts will always build with cmake and make outside your source git trees. - By default (without BUILD_AOMP) the build will occur in the "build" subdirectory of - AOMP_REPOS. For example build_llvm will build in $AOMP_REPOS/build/llvm - - The BUILD_AOMP environment variable enables source development outside your git - repositories. By default, this feature is OFF. The BUILD_AOMP environment variable - can be used if access to your git repositories is very slow or you want to test - changes outside of your local git repositories (specified by AOMP_REPOS env var). - If BUILD_AOMP is set, your git repositories (specifed by AOMP_REPOS) will be - replicated to subdirectories of BUILD_AOMP using rsync. The subsequent build - (cmake and make) will occur in subdirectory BUILD_AOMP/build/llvm. - This replication only happens on your initial build, that is, if you specify no arguments. - The option 'nocmake' skips replication and then restarts make in the build directory. - The install option skips replication, skips cmake, runs 'make' and 'make install'. - Be careful to always use options nocmake or install if you made local changes in - BUILD_AOMP or your changes will be lost by a new replica of your git repositories. - -EOF - exit 0 -} diff --git a/bin/aomp_utils b/bin/aomp_utils new file mode 100644 index 0000000000..788625464c --- /dev/null +++ b/bin/aomp_utils @@ -0,0 +1,305 @@ +#!/bin/bash + +# Quote argument list suitable for passing as a single (string) argument to +# cmake. Result can be used within a double-quoted string, i.e. using +# "$(cmquot ...)". +function cmquot() { + local escaped_flags + local escaped_flag + local flag + escaped_flags=() + for flag in "$@"; do + escaped_flag=$(printf "%s" "$flag" | sed 's/\\/\\\\/g; s/\$/\\$/g; s/ /\\ /g; s/"/\\"/g') + escaped_flags+=("$escaped_flag") + done + echo "${escaped_flags[*]}" +} + +# Quote argument list suitable for passing back to the shell as a string. +# Useful for e.g. dumping argument lists in such a way that they can be safely +# copy & pasted into the user's terminal. Output should not be further quoted. +function shquot() { + local -a output + output=() + for arg in "$@"; do + output+=(\'"${arg//\'/\'\\\'\'}"\') + done + printf '%s' "${output[*]}" +} + +function check_writable_installdir() { + local action=$1 + local installdir=$2 + + # Make sure we can update the install directory + if [ "$action" == "install" ] ; then + $SUDO mkdir -p "$installdir" + + if ! $SUDO touch "$installdir/testfile"; then + echo "ERROR: No update access to $installdir" + exit 1 + fi + $SUDO rm "$installdir/testfile" + fi +} + +# TO use this function set variables patchdir and patchfile +function patchrepo(){ +patchdir=$1 +if [ "$AOMP_APPLY_ROCM_PATCHES" == 1 ] && [ -d "$patchdir" ] ; then + patches="" + cd "$patchdir" || exit + if [[ "$2" =~ "postinstall" ]]; then + getpatchlist "$2" + else + getpatchlist + fi + + #loop through list of patches to apply + if [ "$patches" != "" ] ; then + patchloc=${AOMP_PATCH_CONTROL_FILE%/*} + echo "patchloc=$patchloc" + for patch in $patches; do + patchfile=$patchloc/$patch + if [ ! -f "$patchfile" ] ; then + echo + echo "ERROR: Patch $patchfile does not exist" + echo " It is referenced in ${AOMP_PATCH_CONTROL_FILE}" + exit 1 + fi + + echo "Testing patch $patchfile to $patchdir" + + applypatch="yes" + if ! patch -p1 -t -N --dry-run <"$patchfile" >/dev/null; then + applypatch="no" + # Check to see if reverse patch applies cleanly + if patch -p1 -R --dry-run -t <"$patchfile" >/dev/null; then + echo "patch $patchfile was already applied to $patchdir" + else + echo + echo "ERROR: Patch $patchfile will not apply" + echo " cleanly to directory $patchdir" + echo " Check if it was already applied." + echo + exit 1 + fi + fi + if [ "$applypatch" == "yes" ] ; then + echo "Applying patch $patchfile to $patchdir" + patch -p1 --no-backup-if-mismatch <"$patchfile" + fi + done + fi +fi + +} + +function removepatch(){ +patchdir=$1 +if [ "$AOMP_APPLY_ROCM_PATCHES" == 1 ] && [ -d "$patchdir" ] ; then + patches="" + cd "$patchdir" || exit + getpatchlist + if [ "$patches" != "" ] ; then + echo "Patchdir $patchdir" + echo "PATCHES TO REMOVE: $patches" + fi + patchloc=${AOMP_PATCH_CONTROL_FILE%/*} + if [ "$patches" != "" ] ; then + for patch in $patches; do + patchfile=$patchloc/$patch + echo "Testing reverse patch $patchfile to $patchdir" + reversepatch="yes" + # Check to see if reverse patch applies cleanly + + if ! patch -p1 -R --dry-run -f <"$patchfile" >/dev/null; then + echo "patch $patchfile was NOT applied $patchdir, no patch to reverse" + reversepatch="no" + fi + if [ "$reversepatch" == "yes" ] ; then + echo "Reversing patch $patchfile to $patchdir" + patch -p1 -R -f --no-backup-if-mismatch <"$patchfile" + fi + done + fi +fi +} + +function getpatchlist(){ + currdir=$(pwd) + basedir=$(basename "$currdir") + if [[ "$1" =~ "postinstall" ]]; then + reporegex="(^$1:\s)" + else + reporegex="(^$basedir:\s)" + fi + echo "FILE: $AOMP_PATCH_CONTROL_FILE" + echo "regex $reporegex" + #read patch control file and look for correct patches + while read -r line; do + if [[ "$line" =~ $reporegex ]]; then + #remove basename from list of patches + patches=${line/"${BASH_REMATCH[1]}"} + echo "patches: $patches" + break + fi + done < "$AOMP_PATCH_CONTROL_FILE" +} + +function setaompgpu (){ + if [[ -e "$AOMP/../../bin/rocm_agent_enumerator" ]]; then + echo Set AOMP_GPU with ../.. rocm_agent_enumerator. + detected_gpu=$("$AOMP"/../../bin/rocm_agent_enumerator | grep -m 1 -E 'gfx[^0]{1}.{2}') + elif [[ -e "$AOMP/../bin/rocm_agent_enumerator" ]]; then + echo Set AOMP_GPU with .. rocm_agent_enumerator. + detected_gpu=$("$AOMP"/../bin/rocm_agent_enumerator | grep -m 1 -E 'gfx[^0]{1}.{2}') + elif [[ "$AOMP" =~ "opt" ]]; then + echo Set AOMP_GPU with rocm_agent_enumerator. + detected_gpu=$("$AOMP"/../bin/rocm_agent_enumerator | grep -m 1 -E 'gfx[^0]{1}.{2}') + else + echo Set AOMP_GPU with rocm_agent_enumerator. + if [ -a "$AOMP"/bin/rocm_agent_enumerator ]; then + detected_gpu=$("$AOMP"/bin/rocm_agent_enumerator | grep -m 1 -E 'gfx[^0]{1}.{2}') + elif [ -a "$AOMP"/bin/amdgpu-arch ]; then + detected_gpu=$("$AOMP"/bin/amdgpu-arch) + detected_gpu=$(echo "$detected_gpu" | awk '{print $1,$5}') + detected_gpu=$(echo "$detected_gpu" | cut -d" " -f1) # pick first found + elif [ -e "$AOMP"/../bin/mygpu ]; then + detected_gpu=$("$AOMP"/../bin/mygpu) + else + echo "Error: in setaompgpu, could not find rocm_agent_enumerator" + echo " Set AOMP_GPU, AOMP, or install ROCm" + exit 1 + fi + fi + + AOMP_GPU=${AOMP_GPU:-$detected_gpu} + export AOMP_GPU + echo "AOMP_GPU = $AOMP_GPU" + echo "AOMP = $AOMP" + + if [ "$AOMP_GPU" == "" ] || [ "$AOMP_GPU" == "unknown" ]; then + echo Error: AOMP_GPU not properly set...exiting. + exit 1 + fi +} + +# GPUs which need HSA_XNACK=1 to be set for USM to work. The canonical place +# this info is stored in these scripts is in test/Makefile.defs (SUPPORTS_USM). +# We use a tiny custom makefile to extract the info. +# Usage: +# if gpu_needs_xnack_for_usm "$GPU"; then ...; fi + +function gpu_needs_xnack_for_usm(){ + local needs_usm + # $thisdir is always set by aomp_common_vars. + # shellcheck disable=SC2154 + needs_usm=$(make -s -C "$thisdir"/../test -f USM_check.make GPU="$1") + case "$needs_usm" in + true) + return 0 + ;; + false) + return 1 + ;; + *) + return 2 + ;; + esac +} + +# Return success (0) if ROCR_VISIBLE_DEVICES (or the first GPU if it is unset) +# refers to an APU, as indicated by rocminfo returning +# "Coherent Host Access: TRUE" for the device, else return failure (1). + +function is_apu(){ + local device_num=${ROCR_VISIBLE_DEVICES:-0} + local cha + cha=$(ROCR_VISIBLE_DEVICES="$device_num" rocminfo | grep -m 1 -F "Coherent Host Access:") + if [[ "$cha" =~ Coherent\ Host\ Access:[[:blank:]]+(TRUE|FALSE) ]]; then + case "${BASH_REMATCH[1]}" in + TRUE) + return 0 + ;; + FALSE) + return 1 + ;; + esac + else + # If we don't see the above pattern in rocminfo output, it's probably not + # an APU. + return 1 + fi +} + +function help_build_aomp(){ + /bin/cat 2>&1 <<"EOF" + + The build scripts in this directory are used to build AOMP. + + Repositories: + Many repositories are used to build AOMP. The script clone_aomp.sh will + clone all the necessary repositories as subdirectories of the directory + $HOME/git/aomp11. The web repository locations and the required branches + are set with the file aomp_common_vars + + Build all components: + To build all components, run these commands: + + ./clone_aomp.sh + unset LD_LIBRARY_PATH + ./build_aomp.sh + + Component builds: + Developers can rebuild individual components by running the build script for + that component. Make sure dependent components are built first. You can run + build_aomp.sh to build call components in the correct order orsee the README.md + file in this directory for the required order. + + Each build script can run with no arguments or with a single argument + "install" or "nocmake". Running with no options starts fresh with an empty + component build directory. It then runs cmake with the correct cmake options + then it runs make with a proper -j option. + + Optional Arguments 'nocmake' and 'install' : + The 'nocmake' or 'install' options can only be used after your initial build + with no options. The 'nocmake' option is intended to restart make after + you fix code following a failed build. The 'install' option will run 'make' + and 'make install' causing installation into the directory $AOMP_INSTALL_DIR. + The 'install' option will also create a symbolic link to directory $AOMP. + + Environment Variables: + You can set environment variables to override behavior of the build scripts + NAME DEFAULT DESCRIPTION + ---- ------- ----------- + AOMP $HOME/rocm/aomp Where the compiler will be installed + AOMP_REPOS $HOME/git/aomp11 Location of all aomp repos + BUILD_TYPE Release The CMAKE build type + BUILD_AOMP same as AOMP_REPOS Set a different build location than AOMP_REPOS + AOMP_USE_NINJA 0 Use ninja if possible + + To build a debug version of the compiler, run this command before the build: + export BUILD_TYPE=debug + + The BUILD_AOMP Envronment Variable: + The build scripts will always build with cmake and make outside your source git trees. + By default (without BUILD_AOMP) the build will occur in the "build" subdirectory of + AOMP_REPOS. For example build_llvm will build in $AOMP_REPOS/build/llvm + + The BUILD_AOMP environment variable enables source development outside your git + repositories. By default, this feature is OFF. The BUILD_AOMP environment variable + can be used if access to your git repositories is very slow or you want to test + changes outside of your local git repositories (specified by AOMP_REPOS env var). + If BUILD_AOMP is set, your git repositories (specifed by AOMP_REPOS) will be + replicated to subdirectories of BUILD_AOMP using rsync. The subsequent build + (cmake and make) will occur in subdirectory BUILD_AOMP/build/llvm. + This replication only happens on your initial build, that is, if you specify no arguments. + The option 'nocmake' skips replication and then restarts make in the build directory. + The install option skips replication, skips cmake, runs 'make' and 'make install'. + Be careful to always use options nocmake or install if you made local changes in + BUILD_AOMP or your changes will be lost by a new replica of your git repositories. + +EOF + exit 0 +} diff --git a/bin/build-deb-aomp.sh b/bin/build-deb-aomp.sh index 770037b548..7342db689f 100755 --- a/bin/build-deb-aomp.sh +++ b/bin/build-deb-aomp.sh @@ -12,6 +12,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build-rpm.sh b/bin/build-rpm.sh index da5f5db9e7..02f2a5a459 100755 --- a/bin/build-rpm.sh +++ b/bin/build-rpm.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_amdsmi.sh b/bin/build_amdsmi.sh index ffa078e5e3..9a515b969b 100755 --- a/bin/build_amdsmi.sh +++ b/bin/build_amdsmi.sh @@ -31,6 +31,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_aomp.sh b/bin/build_aomp.sh index 228b98b51a..c12ebe7f03 100755 --- a/bin/build_aomp.sh +++ b/bin/build_aomp.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_bolt.sh b/bin/build_bolt.sh index cd95b11f35..511791d0a4 100755 --- a/bin/build_bolt.sh +++ b/bin/build_bolt.sh @@ -30,6 +30,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_comgr.sh b/bin/build_comgr.sh index 109bebf244..8b8643b5a5 100755 --- a/bin/build_comgr.sh +++ b/bin/build_comgr.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_extras.sh b/bin/build_extras.sh index b58f93ebae..d949065fdd 100755 --- a/bin/build_extras.sh +++ b/bin/build_extras.sh @@ -32,6 +32,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_fixups.sh b/bin/build_fixups.sh index 1b464462b2..b8295b23dc 100755 --- a/bin/build_fixups.sh +++ b/bin/build_fixups.sh @@ -7,6 +7,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_flang-classic.sh b/bin/build_flang-classic.sh index b61228f56c..b656ef4b51 100755 --- a/bin/build_flang-classic.sh +++ b/bin/build_flang-classic.sh @@ -18,6 +18,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_flang.sh b/bin/build_flang.sh index 74f9162b23..23219d4f51 100755 --- a/bin/build_flang.sh +++ b/bin/build_flang.sh @@ -8,6 +8,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_flang_runtime.sh b/bin/build_flang_runtime.sh index 1bddf15381..ab2b2dab96 100755 --- a/bin/build_flang_runtime.sh +++ b/bin/build_flang_runtime.sh @@ -8,6 +8,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_hipamd.sh b/bin/build_hipamd.sh index 0a0ae14d13..ad79fb56d8 100755 --- a/bin/build_hipamd.sh +++ b/bin/build_hipamd.sh @@ -30,6 +30,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_hipcc.sh b/bin/build_hipcc.sh index 7ad2314c4b..eb23af4b85 100755 --- a/bin/build_hipcc.sh +++ b/bin/build_hipcc.sh @@ -26,6 +26,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_hipfort.sh b/bin/build_hipfort.sh index 83e584bbf4..58522ae753 100755 --- a/bin/build_hipfort.sh +++ b/bin/build_hipfort.sh @@ -30,6 +30,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_hipify.sh b/bin/build_hipify.sh index e2b835f686..a925bcab1d 100755 --- a/bin/build_hipify.sh +++ b/bin/build_hipify.sh @@ -26,6 +26,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_libdevice.sh b/bin/build_libdevice.sh index 511bfe4167..a1693e67b5 100755 --- a/bin/build_libdevice.sh +++ b/bin/build_libdevice.sh @@ -7,6 +7,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_llvm-classic.sh b/bin/build_llvm-classic.sh index 9c456233dc..cc319e978a 100755 --- a/bin/build_llvm-classic.sh +++ b/bin/build_llvm-classic.sh @@ -18,6 +18,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_offload.sh b/bin/build_offload.sh index 5303a3ee69..f6aa6f002c 100755 --- a/bin/build_offload.sh +++ b/bin/build_offload.sh @@ -7,6 +7,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_openmp.sh b/bin/build_openmp.sh index 0f587bc9ff..547c50840c 100755 --- a/bin/build_openmp.sh +++ b/bin/build_openmp.sh @@ -7,6 +7,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_pgmath.sh b/bin/build_pgmath.sh index cdd1045cf9..ec03dc469d 100755 --- a/bin/build_pgmath.sh +++ b/bin/build_pgmath.sh @@ -8,6 +8,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_project.sh b/bin/build_project.sh index 2a1d086968..0700200a98 100755 --- a/bin/build_project.sh +++ b/bin/build_project.sh @@ -13,6 +13,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_qmcpack.sh b/bin/build_qmcpack.sh index 0130e2f2aa..2fd3880dc8 100755 --- a/bin/build_qmcpack.sh +++ b/bin/build_qmcpack.sh @@ -25,6 +25,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocdbgapi.sh b/bin/build_rocdbgapi.sh index 4e64222db3..695ad241c4 100755 --- a/bin/build_rocdbgapi.sh +++ b/bin/build_rocdbgapi.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocgdb.sh b/bin/build_rocgdb.sh index 4c5388815c..cf43180648 100755 --- a/bin/build_rocgdb.sh +++ b/bin/build_rocgdb.sh @@ -9,6 +9,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocm-cmake.sh b/bin/build_rocm-cmake.sh index 98f405935d..cd67067f5c 100755 --- a/bin/build_rocm-cmake.sh +++ b/bin/build_rocm-cmake.sh @@ -31,6 +31,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocm_smi_lib.sh b/bin/build_rocm_smi_lib.sh index b074713b76..7927ade7d6 100755 --- a/bin/build_rocm_smi_lib.sh +++ b/bin/build_rocm_smi_lib.sh @@ -31,6 +31,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocminfo.sh b/bin/build_rocminfo.sh index 50371d9cb0..6be1de87e2 100755 --- a/bin/build_rocminfo.sh +++ b/bin/build_rocminfo.sh @@ -31,6 +31,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocprofiler-register.sh b/bin/build_rocprofiler-register.sh index f8cc44faa2..002cf47117 100755 --- a/bin/build_rocprofiler-register.sh +++ b/bin/build_rocprofiler-register.sh @@ -10,6 +10,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocprofiler-sdk.sh b/bin/build_rocprofiler-sdk.sh index 74e3cb0ec2..07754e7d61 100755 --- a/bin/build_rocprofiler-sdk.sh +++ b/bin/build_rocprofiler-sdk.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocprofiler.sh b/bin/build_rocprofiler.sh index 8cf77057d3..2b37b638f3 100755 --- a/bin/build_rocprofiler.sh +++ b/bin/build_rocprofiler.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_rocr.sh b/bin/build_rocr.sh index b78bcb9370..1d5958d5ce 100755 --- a/bin/build_rocr.sh +++ b/bin/build_rocr.sh @@ -8,6 +8,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_roct.sh b/bin/build_roct.sh index e928aa3fa8..aa8379b991 100755 --- a/bin/build_roct.sh +++ b/bin/build_roct.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_roctracer.sh b/bin/build_roctracer.sh index ec9dc3d666..58707b1e25 100755 --- a/bin/build_roctracer.sh +++ b/bin/build_roctracer.sh @@ -7,6 +7,7 @@ realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/build_supp.sh b/bin/build_supp.sh index ee4f1fa2d0..0cf8b2de6a 100755 --- a/bin/build_supp.sh +++ b/bin/build_supp.sh @@ -58,6 +58,7 @@ PREREQUISITE_COMPONENTS=${PREREQUISITE_COMPONENTS:-cmake rocmsmilib hwloc aqlpro # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- FLANG=${FLANG:-flang} diff --git a/bin/build_supp_llvm-flang.sh b/bin/build_supp_llvm-flang.sh index d7c70accc5..0766c1c3ab 100755 --- a/bin/build_supp_llvm-flang.sh +++ b/bin/build_supp_llvm-flang.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/check_amdgpu_modversion.sh b/bin/check_amdgpu_modversion.sh index 4af2e72317..b4587847ab 100755 --- a/bin/check_amdgpu_modversion.sh +++ b/bin/check_amdgpu_modversion.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" [ -f "$thisdir/aomp_common_vars" ] && . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/check_omptests.sh b/bin/check_omptests.sh index 453f5671b0..a32e8de44a 100755 --- a/bin/check_omptests.sh +++ b/bin/check_omptests.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/check_openmpvv.sh b/bin/check_openmpvv.sh index e28d1d1242..9b7e82bc52 100755 --- a/bin/check_openmpvv.sh +++ b/bin/check_openmpvv.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/check_sollve.sh b/bin/check_sollve.sh index ecdbd7815e..236f618c74 100755 --- a/bin/check_sollve.sh +++ b/bin/check_sollve.sh @@ -6,6 +6,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/clone_aomp.sh b/bin/clone_aomp.sh index 0df4f42470..76f5bf3e70 100755 --- a/bin/clone_aomp.sh +++ b/bin/clone_aomp.sh @@ -8,6 +8,7 @@ realpath=$(realpath "$0") thisdir=$(dirname "$realpath") export AOMP_USE_CCACHE=${AOMP_USE_CCACHE:-0} +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/clone_epsdb_test.sh b/bin/clone_epsdb_test.sh index f949401b27..c385f9eb51 100755 --- a/bin/clone_epsdb_test.sh +++ b/bin/clone_epsdb_test.sh @@ -7,6 +7,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/clone_test.sh b/bin/clone_test.sh index 85d8686d53..77fd1fb42b 100755 --- a/bin/clone_test.sh +++ b/bin/clone_test.sh @@ -9,6 +9,7 @@ realpath=$(realpath "$0") thisdir=$(dirname "$realpath") export AOMP_USE_CCACHE=${AOMP_USE_CCACHE:-0} +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/rocmlibs/build_half.sh b/bin/rocmlibs/build_half.sh index 418f567235..5349d93f7e 100755 --- a/bin/rocmlibs/build_half.sh +++ b/bin/rocmlibs/build_half.sh @@ -5,6 +5,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_hipBLAS-common.sh b/bin/rocmlibs/build_hipBLAS-common.sh index ed16b68590..525ee5c03f 100755 --- a/bin/rocmlibs/build_hipBLAS-common.sh +++ b/bin/rocmlibs/build_hipBLAS-common.sh @@ -8,6 +8,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_hipBLAS.sh b/bin/rocmlibs/build_hipBLAS.sh index 76849c6ca2..a67ed333cc 100755 --- a/bin/rocmlibs/build_hipBLAS.sh +++ b/bin/rocmlibs/build_hipBLAS.sh @@ -12,6 +12,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_hipRAND.sh b/bin/rocmlibs/build_hipRAND.sh index c35fab740c..090967c1b5 100755 --- a/bin/rocmlibs/build_hipRAND.sh +++ b/bin/rocmlibs/build_hipRAND.sh @@ -7,6 +7,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_hipSOLVER.sh b/bin/rocmlibs/build_hipSOLVER.sh index 05137d502c..99c29fc3e3 100755 --- a/bin/rocmlibs/build_hipSOLVER.sh +++ b/bin/rocmlibs/build_hipSOLVER.sh @@ -8,6 +8,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_powerinfer.sh b/bin/rocmlibs/build_powerinfer.sh index a6143a920d..604e1b55d0 100755 --- a/bin/rocmlibs/build_powerinfer.sh +++ b/bin/rocmlibs/build_powerinfer.sh @@ -12,6 +12,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_rccl.sh b/bin/rocmlibs/build_rccl.sh index 36c92c5608..5e1125ca2a 100755 --- a/bin/rocmlibs/build_rccl.sh +++ b/bin/rocmlibs/build_rccl.sh @@ -10,6 +10,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_rocBLAS.sh b/bin/rocmlibs/build_rocBLAS.sh index 9a75c22d2b..a50654bbf7 100755 --- a/bin/rocmlibs/build_rocBLAS.sh +++ b/bin/rocmlibs/build_rocBLAS.sh @@ -13,6 +13,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_rocPRIM.sh b/bin/rocmlibs/build_rocPRIM.sh index 2c49ce1fe8..e6ab223383 100755 --- a/bin/rocmlibs/build_rocPRIM.sh +++ b/bin/rocmlibs/build_rocPRIM.sh @@ -12,6 +12,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_rocRAND.sh b/bin/rocmlibs/build_rocRAND.sh index d76261daf5..f74ac7469d 100755 --- a/bin/rocmlibs/build_rocRAND.sh +++ b/bin/rocmlibs/build_rocRAND.sh @@ -7,6 +7,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_rocSOLVER.sh b/bin/rocmlibs/build_rocSOLVER.sh index e511511d68..409a23ca3a 100755 --- a/bin/rocmlibs/build_rocSOLVER.sh +++ b/bin/rocmlibs/build_rocSOLVER.sh @@ -13,6 +13,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_rocSPARSE.sh b/bin/rocmlibs/build_rocSPARSE.sh index bd9ef06c9e..e66dd674d8 100755 --- a/bin/rocmlibs/build_rocSPARSE.sh +++ b/bin/rocmlibs/build_rocSPARSE.sh @@ -13,6 +13,7 @@ BUILD_TYPE=${BUILD_TYPE:-Release} # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/build_rocmlibs.sh b/bin/rocmlibs/build_rocmlibs.sh index f6697fd7a7..043a7332ea 100755 --- a/bin/rocmlibs/build_rocmlibs.sh +++ b/bin/rocmlibs/build_rocmlibs.sh @@ -10,6 +10,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/clone_rocmlibs.sh b/bin/rocmlibs/clone_rocmlibs.sh index 7ed39dbe68..cd249fad88 100755 --- a/bin/rocmlibs/clone_rocmlibs.sh +++ b/bin/rocmlibs/clone_rocmlibs.sh @@ -12,6 +12,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/rocmlibs/test_powerinfer.sh b/bin/rocmlibs/test_powerinfer.sh index ef3adba407..d52403bbd9 100755 --- a/bin/rocmlibs/test_powerinfer.sh +++ b/bin/rocmlibs/test_powerinfer.sh @@ -11,6 +11,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/../aomp_utils" . $thisdir/../aomp_common_vars # --- end standard header ---- diff --git a/bin/run_Fnekbone.sh b/bin/run_Fnekbone.sh index 9b7911301b..961284b098 100755 --- a/bin/run_Fnekbone.sh +++ b/bin/run_Fnekbone.sh @@ -8,6 +8,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_OpenMP_VV.sh b/bin/run_OpenMP_VV.sh index a417501e49..0487882fde 100755 --- a/bin/run_OpenMP_VV.sh +++ b/bin/run_OpenMP_VV.sh @@ -24,7 +24,8 @@ realpath=$(realpath "$0") thisdir=$(dirname "${realpath}") export AOMP_USE_CCACHE=0 -. ${thisdir}/aomp_common_vars +. "$thisdir/aomp_utils" +. "${thisdir}"/aomp_common_vars # --- end standard header ---- # Setup AOMP variables diff --git a/bin/run_RSBench.sh b/bin/run_RSBench.sh index e8ada16342..526177aea9 100755 --- a/bin/run_RSBench.sh +++ b/bin/run_RSBench.sh @@ -8,6 +8,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_XSBench.sh b/bin/run_XSBench.sh index 110094943e..d7abbbd938 100755 --- a/bin/run_XSBench.sh +++ b/bin/run_XSBench.sh @@ -8,6 +8,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_accel2023.sh b/bin/run_accel2023.sh index 5ab8dd5e61..10ec26d497 100755 --- a/bin/run_accel2023.sh +++ b/bin/run_accel2023.sh @@ -14,6 +14,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars : ${ACCEL2023_SOURCE_DIR:=$AOMP_REPOS_TEST/accel2023-2.0.18} diff --git a/bin/run_babelstream.sh b/bin/run_babelstream.sh index 9c0c1e3880..30d977dbec 100755 --- a/bin/run_babelstream.sh +++ b/bin/run_babelstream.sh @@ -30,6 +30,7 @@ export AOMP_USE_CCACHE=0 export ROCR_VISIBLE_DEVICES=0 +. "$thisdir"/aomp_utils . "$thisdir"/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_composable-kernels.sh b/bin/run_composable-kernels.sh index e2d6feaff9..f36826c603 100755 --- a/bin/run_composable-kernels.sh +++ b/bin/run_composable-kernels.sh @@ -27,6 +27,8 @@ fi realpath=$(realpath "$0") thisdir=$(dirname "$realpath") +# shellcheck disable=SC1091 +. "$thisdir"/aomp_utils # shellcheck disable=SC1091 . "$thisdir"/aomp_common_vars diff --git a/bin/run_fBabel.sh b/bin/run_fBabel.sh index 2bab219fed..11c092ad6a 100755 --- a/bin/run_fBabel.sh +++ b/bin/run_fBabel.sh @@ -18,6 +18,7 @@ export AOMP_USE_CCACHE=0 export ROCR_VISIBLE_DEVICES=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_genasis.sh b/bin/run_genasis.sh index 6d98d28afa..5df87f23be 100755 --- a/bin/run_genasis.sh +++ b/bin/run_genasis.sh @@ -8,6 +8,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_genasis_flang_new.sh b/bin/run_genasis_flang_new.sh index 9f54d16424..ec8e26c9d4 100755 --- a/bin/run_genasis_flang_new.sh +++ b/bin/run_genasis_flang_new.sh @@ -27,6 +27,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_gests.sh b/bin/run_gests.sh index 62cd6bb2ab..b646f443cf 100755 --- a/bin/run_gests.sh +++ b/bin/run_gests.sh @@ -8,6 +8,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_hpc2021.sh b/bin/run_hpc2021.sh index cf1fb84bfa..7517c92833 100755 --- a/bin/run_hpc2021.sh +++ b/bin/run_hpc2021.sh @@ -14,6 +14,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars : ${HPC2021_SOURCE_DIR:=$AOMP_REPOS_TEST/hpc2021-1.1.9} diff --git a/bin/run_hpcg.sh b/bin/run_hpcg.sh index d62edf3183..d82f7a6341 100755 --- a/bin/run_hpcg.sh +++ b/bin/run_hpcg.sh @@ -7,6 +7,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars : ${HPCG_SOURCE_DIR:=$AOMP_REPOS_TEST/hpcg} diff --git a/bin/run_miniQMC.sh b/bin/run_miniQMC.sh index 7e864432e4..f6447aacff 100755 --- a/bin/run_miniQMC.sh +++ b/bin/run_miniQMC.sh @@ -13,6 +13,8 @@ realpath=$(realpath "$0") thisdir=$(dirname "$realpath") export AOMP_USE_CCACHE=0 +# shellcheck source-path=SCRIPTDIR +. "$thisdir"/aomp_utils # shellcheck source-path=SCRIPTDIR . "$thisdir"/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_nekbone.sh b/bin/run_nekbone.sh index 6d00cf288d..affc017517 100755 --- a/bin/run_nekbone.sh +++ b/bin/run_nekbone.sh @@ -8,6 +8,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_nio.sh b/bin/run_nio.sh index 7a36d6c8eb..cbd945ff95 100755 --- a/bin/run_nio.sh +++ b/bin/run_nio.sh @@ -5,6 +5,7 @@ # --- Start standard header to set AOMP environment variables ---- realpath=`realpath $0` thisdir=`dirname $realpath` +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_omptests.sh b/bin/run_omptests.sh index 6acb386492..6970803b20 100755 --- a/bin/run_omptests.sh +++ b/bin/run_omptests.sh @@ -5,6 +5,7 @@ realpath=$(realpath "$0") thisdir=$(dirname "$realpath") export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- diff --git a/bin/run_openlibm_test.sh b/bin/run_openlibm_test.sh index b2a3006318..90b94755d5 100755 --- a/bin/run_openlibm_test.sh +++ b/bin/run_openlibm_test.sh @@ -5,6 +5,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_openmpapps.sh b/bin/run_openmpapps.sh index 3c664debfb..9d61b35c92 100755 --- a/bin/run_openmpapps.sh +++ b/bin/run_openmpapps.sh @@ -8,6 +8,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_ovo.sh b/bin/run_ovo.sh index 8245a06ad8..222ae6ed3f 100755 --- a/bin/run_ovo.sh +++ b/bin/run_ovo.sh @@ -5,6 +5,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_rajaperf.sh b/bin/run_rajaperf.sh index 727b888c9b..22d2225156 100755 --- a/bin/run_rajaperf.sh +++ b/bin/run_rajaperf.sh @@ -5,6 +5,7 @@ realpath=$(realpath "$0") thisdir=$(dirname "$realpath") export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . "${thisdir}/aomp_common_vars" # --- end standard header ---- diff --git a/bin/run_rushlarsen.sh b/bin/run_rushlarsen.sh index 78cb8b4d3f..bb518fa6c4 100755 --- a/bin/run_rushlarsen.sh +++ b/bin/run_rushlarsen.sh @@ -8,6 +8,7 @@ realpath=$(realpath "$0") thisdir=$(dirname "$realpath") export AOMP_USE_CCACHE=0 +. "$thisdir"/aomp_utils . "$thisdir"/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_sollve.sh b/bin/run_sollve.sh index 26991ece64..cb0436922b 100755 --- a/bin/run_sollve.sh +++ b/bin/run_sollve.sh @@ -10,6 +10,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_su3bench.sh b/bin/run_su3bench.sh index 629201549f..fa1904af47 100755 --- a/bin/run_su3bench.sh +++ b/bin/run_su3bench.sh @@ -8,6 +8,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- diff --git a/bin/run_umt.sh b/bin/run_umt.sh index e4668ff0e6..1e565b1f51 100755 --- a/bin/run_umt.sh +++ b/bin/run_umt.sh @@ -9,6 +9,7 @@ realpath=`realpath $0` thisdir=`dirname $realpath` export AOMP_USE_CCACHE=0 +. "$thisdir/aomp_utils" . $thisdir/aomp_common_vars # --- end standard header ---- From c4045ad4908cd08fe74ea79f3ee6359b951ddca5 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Thu, 17 Jul 2025 13:43:17 -0500 Subject: [PATCH 02/71] [AOMP] Taskification/control-flow inversion for scripts, part 1 This is an experimental patch to incrementally refactor the build scripts. The approach taken is particularly relevant to scripts which build multiple configurations of a component. There are several ideas here. Firstly, build scripts can be introspected so you can see what they are doing: $ ./build_offload.sh list_configs asan perf perf+asan debug debug+asan $ AOMP_BUILD_SANITIZER=0 ./build_offload.sh list_configs perf debug Build steps are split into different tasks, each of which is wrapped in a "task_foo" function (which is passed the configuration name): $ ./build_offload.sh list_tasks perf clean cmake build install You can list all tasks list this: $ ./build_offload.sh list task_precheck task_patch task_clean asan task_cmake asan task_build asan task_install asan task_clean perf task_cmake perf task_build perf task_install perf task_clean perf+asan task_cmake perf+asan task_build perf+asan task_install perf+asan task_clean debug task_cmake debug task_build debug task_install debug task_postinstall debug task_clean debug+asan task_cmake debug+asan task_build debug+asan task_install debug+asan task_unpatch Or e.g. see what will happen for different env var settings: $ AOMP_BUILD_DEBUG=0 ./build_offload.sh list task_precheck task_patch task_clean asan task_cmake asan task_build asan task_install asan task_clean perf task_cmake perf task_build perf task_install perf task_clean perf+asan task_cmake perf+asan task_build perf+asan task_install perf+asan task_unpatch You can still invoke the build scripts the same way as at present: $ ./build_offload.sh [...builds everything...] $ ./build_offload.sh cmake [...just runs cmake steps...] $ ./build_offload.sh nocmake [...just runs build steps...] $ ./build_offload.sh install [...just runs install steps...] Only the build_offload.sh script has been done so far, but this backward compatibility allows other scripts to be refactored in a similar way incrementally. The aim (not yet realised) is to then provide a new or alternate front-end (to build_aomp.sh) using exactly the same build scripts, allowing fine-grained control over which components to build/rebuild, and so on. Internally, the refactoring already done on build_offload.sh demonstrates very much deduplication, particularly around the setting of cmake options. Further work will allow much of the "boilerplate" in each of the build scripts to be replaced by a central implementation. Environment variables used to control the build are now read via two functions (get_config_var_string and get_config_var_bool). There are several reasons for this indirection: - It allows us to have a single location to check which environment variables are being used to control the build. - (For the alternate frontend) the options can be changed via e.g. command-line options instead of environment variables. - The _bool function emits the string 'true' or 'false'. This allows the use of: if $Result; then ... fi instead of if [ "$Result" -eq 1 ]; then ... fi which is shorter/somewhat easier to read. "Actions" (the emulated "nocmake", etc. options, and the new "list", etc. options) are implemented as functions named "do_{foo}", invoked by the new "command_dispatcher" function. There are a few other actions, e.g.: $ ./build_offload.sh show_build_dir perf /home/julbrown/git/aomp21.0/build/home/julbrown/git/aomp21.0/offload_perf These will be more useful once more scripts are "taskified". --- bin/aomp_utils | 164 ++++++++ bin/build_offload.sh | 880 ++++++++++++++++++++++--------------------- 2 files changed, 609 insertions(+), 435 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 788625464c..a60a45b4b4 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -233,6 +233,170 @@ function is_apu(){ fi } +valid_config() { + local thiscfg=$1 + local -a configs + local oldlastpipe + local cfg + oldlastpipe="$(shopt -p lastpipe)" + shopt -s lastpipe + do_list_configs | mapfile -t configs + for cfg in "${configs[@]}"; do + if [ "$cfg" = "$thiscfg" ]; then + eval "$oldlastpipe" + return 0 + fi + done + eval "$oldlastpipe" + return 1 +} + +runcmd() { + "$@" +} + +aomp_tasks_filtered() { + local filter + local cfg + local task + local cmd + if [ "$1" = "--dryrun" ]; then + cmd="echo" + shift + else + cmd="runcmd" + fi + filter=$1 + do_list_init | while read -r initfn; do + $cmd "task_${initfn}" + done + do_list_configs | while read -r cfg; do + do_list_tasks "$cfg" | while read -r task; do + if [[ "$task" =~ $filter ]]; then + $cmd "task_${task}" "$cfg" + fi + done + done + do_list_fini | while read -r finifn; do + $cmd "task_${finifn}" + done +} + +get_config_var_string() { + #local component=$1 + local -n _varname=$2 + case "$2" in + BUILD_DIR) + printf "%s/build" "$_varname" + return + ;; + LLVM_INSTALL_LOC|AOMP_PROC|CUDABIN|CUDAT|CUDAINCLUDE|REPO_DIR|\ + AOMP_NINJA_BIN|AOMP_JOB_THREADS|LLVM_PROJECT_ROOT) + ;; + *) + >&2 echo "Unknown string configuration variable '$2'" + exit 1 + ;; + esac + printf "%s" "$_varname" +} + +get_config_var_bool() { + #local component=$1 + local -n _varname=$2 + case "$2" in + AOMP_BUILD_CUDA|AOMP_APPLY_ATD_AMD_STAGING_PATCH|AOMP_USE_NINJA|\ + AOMP_STANDALONE_BUILD|SANITIZER|AOMP_LEGACY_OPENMP|AOMP_BUILD_SANITIZER|\ + AOMP_BUILD_PERF|AOMP_BUILD_DEBUG) + ;; + *) + >&2 echo "Unknown bool configuration variable '$2'" + exit 1 + ;; + esac + if [[ $_varname = 1 ]]; then + echo "true" + else + echo "false" + fi +} + +do_aomp_all() { + aomp_tasks_filtered '.*' +} + +do_cmake() { + aomp_tasks_filtered '^(clean|cmake)' +} + +do_nocmake() { + aomp_tasks_filtered 'build' +} + +do_install() { + aomp_tasks_filtered '^(install|postinstall)' +} + +do_show_src_dir() { + if [ $# -eq 0 ]; then + printf "%s\n" "$(get_src_dir)" + else + local WhichComp=$1 + "$thisdir/build_${WhichComp}.sh" show_src_dir + fi +} + +do_show_build_dir() { + local WhichComp + local Cfg + if [ $# -eq 1 ]; then + Cfg=$1 + printf "%s\n" "$(get_build_dir "$Cfg")" + elif [ $# -eq 2 ]; then + WhichComp=$1 + Cfg=$2 + "$thisdir/build_${WhichComp}.sh" show_build_dir "$Cfg" + else + >&2 echo "Usage: show_build_dir [] " + exit 1 + fi +} + +do_show_install_dir() { + local WhichComp + local Cfg + if [ $# -eq 1 ]; then + Cfg=$1 + printf "%s\n" "$(get_install_dir "$Cfg")" + elif [ $# -eq 2 ]; then + WhichComp=$1 + Cfg=$2 + "$thisdir/build_${WhichComp}.sh" show_install_dir "$Cfg" + else + >&2 echo "Usage: show_install_dir [] " + exit 1 + fi +} + +do_list() { + aomp_tasks_filtered --dryrun '.*' +} + +command_dispatcher() { + local _proc + _proc=$1 + if [ "$_proc" ]; then + shift + if [[ $_proc =~ ^task_ ]]; then + "$_proc" "$@" + else + "do_${_proc}" "$@" + fi + else + do_aomp_all + fi +} + function help_build_aomp(){ /bin/cat 2>&1 <<"EOF" diff --git a/bin/build_offload.sh b/bin/build_offload.sh index f6aa6f002c..8f0bca2953 100755 --- a/bin/build_offload.sh +++ b/bin/build_offload.sh @@ -4,6 +4,11 @@ # This script will install in location defined by AOMP env variable # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- realpath=$(realpath "$0") thisdir=$(dirname "$realpath") @@ -11,6 +16,15 @@ thisdir=$(dirname "$realpath") . "$thisdir/aomp_common_vars" # --- end standard header ---- +# Get a configuration (environment) variable for this config +cfgvar() { + get_config_var_string offload "$1" +} + +cfgbool() { + get_config_var_bool offload "$1" +} + if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi @@ -18,491 +32,487 @@ fi REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME _ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - CUDAH=$(find "$CUDAT" -type f,l -name "cuda.h" 2>/dev/null) - if [ "$CUDAH" == "" ] ; then - CUDAH=$(find "$CUDAINCLUDE" -type f,l -name "cuda.h" 2>/dev/null) - fi - if [ "$CUDAH" == "" ] ; then - echo - echo "ERROR: THE cuda.h FILE WAS NOT FOUND WITH ARCH $AOMP_PROC" - echo " A CUDA installation is necessary to build libomptarget deviceRTLs" - echo " Please install CUDA to build offload" - echo +get_src_dir() { + echo "$REPO_DIR/offload" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/offload" + ;; + "asan") + echo -n "$BuildDir/offload/asan" + ;; + "perf") + echo -n "$BuildDir/offload_perf" + ;; + "perf+asan") + echo -n "$BuildDir/offload_perf/asan" + ;; + "debug") + echo -n "$BuildDir/offload_debug" + ;; + "debug+asan") + echo -n "$BuildDir/offload_debug/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar LLVM_INSTALL_LOC +} + +task_precheck() { + local CUDAVER + local SrcDir + local CUDAH + local CUDAVER + local BuildCUDA + local CUDATop + local CUDAInclude + local CUDABin + local AOMPProc + + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir " + echo " Consider setting env variables AOMP_REPOS and/or AOMP_PROJECT_REPO_NAME " exit 1 fi - # I don't see now nvcc is called, but this eliminates the deprecated warnings - export CUDAFE_FLAGS="-w" -fi - -if [ ! -d "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_PROJECT_REPO_NAME " - echo " Consider setting env variables AOMP_REPOS and/or AOMP_PROJECT_REPO_NAME " - exit 1 -fi -check_writable_installdir "$1" "$LLVM_INSTALL_LOC" + check_writable_installdir "$1" "$(cfgvar LLVM_INSTALL_LOC)" -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - if [ -f "$CUDABIN/nvcc" ] ; then - CUDAVER=$("$CUDABIN"/nvcc --version | grep compilation | cut -d" " -f5 | cut -d"." -f1) - echo "CUDA VERSION IS $CUDAVER" - fi -fi - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN=() -else - AOMP_SET_NINJA_GEN=(-G Ninja) -fi + BuildCUDA="$(cfgbool AOMP_BUILD_CUDA)" -export LLVM_DIR=$AOMP_INSTALL_DIR -GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') -ALTAOMP=${ALTAOMP:-$LLVM_INSTALL_LOC} - -declare -a COMMON_CMAKE_OPTS - -COMMON_CMAKE_OPTS=("${AOMP_SET_NINJA_GEN[@]}" -DOPENMP_ENABLE_LIBOMPTARGET=1 - -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" - -DOPENMP_TEST_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DOPENMP_TEST_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - -DCMAKE_C_COMPILER="$ALTAOMP/bin/clang" - -DCMAKE_CXX_COMPILER="$ALTAOMP/bin/clang++" - -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" - -DLIBOMPTARGET_ENABLE_DEBUG=ON - -DLLVM_DIR="$LLVM_DIR") - -if [ "$AOMP_STANDALONE_BUILD" == 0 ]; then - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_MAIN_INCLUDE_DIR="$LLVM_PROJECT_ROOT/llvm/include" - -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$LLVM_PROJECT_ROOT/llvm/include") -else - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_MAIN_INCLUDE_DIR="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/include" - -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/include") -fi + if "$BuildCUDA"; then + CUDATop=$(cfgvar CUDAT) + CUDAH=$(find "$CUDATop" -type f,l -name "cuda.h" 2>/dev/null) + if [ "$CUDAH" == "" ] ; then + CUDAInclude=$(cfgvar CUDAINCLUDE) + CUDAH=$(find "$CUDAInclude" -type f,l -name "cuda.h" 2>/dev/null) + fi + if [ "$CUDAH" == "" ] ; then + AOMPProc=$(cfgvar AOMP_PROC) + echo + echo "ERROR: THE cuda.h FILE WAS NOT FOUND WITH ARCH $AOMPProc" + echo " A CUDA installation is necessary to build libomptarget deviceRTLs" + echo " Please install CUDA to build offload" + echo + exit 1 + fi + # I don't see now nvcc is called, but this eliminates the deprecated warnings + export CUDAFE_FLAGS="-w" -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLIBOMPTARGET_NVPTX_ENABLE_BCLIB=ON - -DLIBOMPTARGET_NVPTX_CUDA_COMPILER="$AOMP/bin/clang++" - -DLIBOMPTARGET_NVPTX_BC_LINKER="$AOMP/bin/llvm-link" - -DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES="$NVPTXGPUS") -else -# Need to force CUDA off this way in case cuda is installed in this system - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCUDA_TOOLKIT_ROOT_DIR=OFF) -fi + CUDABin=$(cfgvar CUDABIN) + if [ -f "$CUDABin/nvcc" ] ; then + CUDAVER=$("$CUDABin"/nvcc --version | grep compilation | cut -d" " -f5 | cut -d"." -f1) + echo "CUDA VERSION IS $CUDAVER" + fi + fi +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$1") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_patch() { + local ApplyPatch + local RepoDir + ApplyPatch=$(cfgbool AOMP_APPLY_ATD_AMD_STAGING_PATCH) + RepoDir=$(cfgvar REPO_DIR) + # Patch llvm-project with ATD patch customized for amd-staging. + # WARNING: This patch (ATD_ASO_full.patch) rarely applies cleanly + # because of its size and constant trunk merges to amd-staging. + # This is why default is 0 (OFF). + if "$ApplyPatch" ; then + patchrepo "$RepoDir" + fi +} + +task_unpatch() { + local ApplyPatch + local RepoDir + ApplyPatch=$(cfgbool AOMP_APPLY_ATD_AMD_STAGING_PATCH) + RepoDir=$(cfgvar REPO_DIR) + if "$ApplyPatch" ; then + removepatch "$RepoDir" + fi +} + +asan_config() { + local Cfg=$1 + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} + +debug_config() { + local Cfg=$1 + case "$Cfg" in + debug|debug+*) + return 0 + ;; + *) + ;; + esac + return 1 +} + +perf_config() { + local Cfg=$1 + case "$Cfg" in + perf|perf+*) + return 0 + ;; + *) + ;; + esac + return 1 +} + +libdir_suffix() { + local Cfg=$1 + case "$Cfg" in + default) + ;; + asan) + echo "/asan" + ;; + perf) + printf "%s" "-perf" + ;; + perf+asan) + printf "%s" "-perf/asan" + ;; + debug) + printf "%s" "-debug" + ;; + debug+asan) + printf "%s" "-debug/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + esac +} + +task_cmake() { + local Cfg=$1 + local UseNinja + local -a AOMP_SET_NINJA_GEN + local GFXSEMICOLONS + local ALTAOMP + local Standalone + local -a MYCMAKEOPTS + local HSA_RUNTIME_PATH + local BuildDir + local _prefix_map + local LibdirSuffix + + UseNinja=$(cfgbool AOMP_USE_NINJA) + + if "$UseNinja"; then + AOMP_SET_NINJA_GEN=(-G Ninja) + fi -#if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - #LDFLAGS=$(shquot '-fuse-ld=lld' "${ASAN_FLAGS[@]}") - #export LDFLAGS -#fi + BuildDir=$(get_build_dir "$Cfg") -# This is how we tell the hsa plugin where to find hsa -export HSA_RUNTIME_PATH=$ROCM_DIR + export LLVM_DIR=$AOMP_INSTALL_DIR + GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') + ALTAOMP=${ALTAOMP:-$LLVM_INSTALL_LOC} -#breaks build as it cant find rocm-path -#export HIP_DEVICE_LIB_PATH=$ROCM_DIR/lib + Standalone=$(cfgbool AOMP_STANDALONE_BUILD) -# Patch llvm-project with ATD patch customized for amd-staging. -# WARNING: This patch (ATD_ASO_full.patch) rarely applies cleanly -# because of its size and constant trunk merges to amd-staging. -# This is why default is 0 (OFF). -if [ "$AOMP_APPLY_ATD_AMD_STAGING_PATCH" == 1 ] ; then - patchrepo "$REPO_DIR" -fi + MYCMAKEOPTS=("${AOMP_SET_NINJA_GEN[@]}" + -DOPENMP_ENABLE_LIBOMPTARGET=1 + -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" + -DOPENMP_TEST_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DOPENMP_TEST_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DCMAKE_C_COMPILER="$ALTAOMP/bin/clang" + -DCMAKE_CXX_COMPILER="$ALTAOMP/bin/clang++" + -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" + -DLLVM_DIR="$LLVM_DIR") -declare -a ASAN_CMAKE_OPTS - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/offload." - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - echo "rm -rf $BUILD_DIR/build/offload" - rm -rf "$BUILD_DIR/build/offload" - declare -a MYCMAKEOPTS - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DCMAKE_BUILD_TYPE=Release "${AOMP_ORIGIN_RPATH[@]}") + if ! "$Standalone" ; then + MYCMAKEOPTS+=(-DLLVM_MAIN_INCLUDE_DIR="$LLVM_PROJECT_ROOT/llvm/include" + -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$LLVM_PROJECT_ROOT/llvm/include") else - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$INSTALL_PREFIX/lib/cmake" - -DCMAKE_BUILD_TYPE=Release "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") + MYCMAKEOPTS+=(-DLLVM_MAIN_INCLUDE_DIR="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/include" + -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/include") fi - if [ "$AOMP_LEGACY_OPENMP" == "1" ] && [ "$SANITIZER" != 1 ]; then - echo " -----Running offload cmake ---- " - mkdir -p "$BUILD_DIR/build/offload" - cd "$BUILD_DIR/build/offload" || exit - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload"; then - echo "ERROR offload cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 - fi + + if "$(cfgbool AOMP_BUILD_CUDA)"; then + MYCMAKEOPTS+=(-DLIBOMPTARGET_NVPTX_ENABLE_BCLIB=ON + -DLIBOMPTARGET_NVPTX_CUDA_COMPILER="$AOMP/bin/clang++" + -DLIBOMPTARGET_NVPTX_BC_LINKER="$AOMP/bin/llvm-link" + -DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES="$NVPTXGPUS") + else + # Need to force CUDA off this way in case cuda is installed in this system + MYCMAKEOPTS+=(-DCUDA_TOOLKIT_ROOT_DIR=OFF) fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DSANITIZER_AMDGPU=1 -DCMAKE_BUILD_TYPE=Release - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - "${AOMP_ASAN_ORIGIN_RPATH[@]}") - else - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH;$INSTALL_PREFIX/lib/llvm/lib/asan" - -DSANITIZER_AMDGPU=1 -DCMAKE_BUILD_TYPE=Release - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - fi - echo " -----Running offload cmake for asan ---- " - mkdir -p "$BUILD_DIR/build/offload/asan" - cd "$BUILD_DIR/build/offload/asan" || exit - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DOFFLOAD_LIBDIR_SUFFIX="/asan" \ - -DLLVM_LIBDIR_SUFFIX="/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload" - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DOFFLOAD_LIBDIR_SUFFIX="/asan" \ - -DLLVM_LIBDIR_SUFFIX="/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload"; then - echo "ERROR offload cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - # Build a dedicatd "performance" version of libomptarget - if [ "$AOMP_BUILD_PERF" == "1" ]; then - echo "rm -rf $BUILD_DIR/build/offload_perf" - rm -rf "$BUILD_DIR/build/offload_perf" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DLIBOMPTARGET_ENABLE_DEBUG=OFF -DCMAKE_BUILD_TYPE=Release - -DLIBOMPTARGET_PERF=ON -DOFFLOAD_LIBDIR_SUFFIX=-perf - -DLLVM_LIBDIR_SUFFIX="-perf") - mkdir -p "$BUILD_DIR/build/offload_perf" - cd "$BUILD_DIR/build/offload_perf" || exit - echo " -----Running offload cmake for perf ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload" \ - "$(shquot "${AOMP_ORIGIN_RPATH[@]}")" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload" \ - "${AOMP_ORIGIN_RPATH[@]}"; then - echo "error offload cmake failed. cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DLIBOMPTARGET_ENABLE_DEBUG=OFF - -DCMAKE_BUILD_TYPE=Release - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DLIBOMPTARGET_PERF=ON -DSANITIZER_AMDGPU=1 - "${AOMP_ASAN_ORIGIN_RPATH[@]}") - echo " -----Running offload cmake for perf-asan ---- " - mkdir -p "$BUILD_DIR/build/offload_perf/asan" - cd "$BUILD_DIR/build/offload_perf/asan" || exit - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DOFFLOAD_LIBDIR_SUFFIX="-perf/asan" \ - -DLLVM_LIBDIR_SUFFIX="-perf/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DOFFLOAD_LIBDIR_SUFFIX="-perf/asan" \ - -DLLVM_LIBDIR_SUFFIX="-perf/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload"; then - echo "error offload cmake failed. cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - fi + #if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then + #LDFLAGS=$(shquot '-fuse-ld=lld' "${ASAN_FLAGS[@]}") + #export LDFLAGS + #fi - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - _prefix_map=(-fdebug-prefix-map="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload=$_ompd_src_dir/offload") + # This is how we tell the hsa plugin where to find hsa + export HSA_RUNTIME_PATH=$ROCM_DIR - declare -a DEBUGCMAKEOPTS + #breaks build as it cant find rocm-path + #export HIP_DEVICE_LIB_PATH=$ROCM_DIR/lib - DEBUGCMAKEOPTS=(-DLIBOMPTARGET_NVPTX_DEBUG=ON - -DLLVM_ENABLE_ASSERTIONS=ON - -DCMAKE_BUILD_TYPE=Debug - -DROCM_DIR="$ROCM_DIR" - -DLIBOMP_ARCH=x86_64 - -DLIBOMP_OMPT_SUPPORT=ON - -DLIBOMP_USE_DEBUGGER=ON - -DLIBOMP_CPPFLAGS='-O0' - -DLIBOMP_OMPD_SUPPORT=ON - -DLIBOMP_OMPT_DEBUG=ON) + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + + if perf_config "$Cfg"; then + MYCMAKEOPTS+=(-DLIBOMPTARGET_PERF=ON + -DLIBOMPTARGET_ENABLE_DEBUG=OFF) + else + MYCMAKEOPTS+=(-DLIBOMPTARGET_ENABLE_DEBUG=ON) + fi + + if debug_config "$Cfg"; then + MYCMAKEOPTS+=(-DLIBOMPTARGET_NVPTX_DEBUG=ON + -DLLVM_ENABLE_ASSERTIONS=ON + -DROCM_DIR="$ROCM_DIR" + -DCMAKE_BUILD_TYPE=Debug + -DLIBOMP_ARCH=x86_64 + -DLIBOMP_OMPT_SUPPORT=ON + -DLIBOMP_USE_DEBUGGER=ON + -DLIBOMP_CPPFLAGS='-O0' + -DLIBOMP_OMPD_SUPPORT=ON + -DLIBOMP_OMPT_DEBUG=ON) # The 'pip install --system' command is not supported on non-debian systems. This will disable # the system option if the debian_version file is not present. if [ ! -f /etc/debian_version ]; then echo "==> Non-Debian OS, disabling use of pip install --system" - DEBUGCMAKEOPTS=("${DEBUGCMAKEOPTS[@]}" -DDISABLE_SYSTEM_NON_DEBIAN=1) + MYCMAKEOPTS+=(-DDISABLE_SYSTEM_NON_DEBIAN=1) fi # Redhat 7.6 does not have python36-devel package, which is needed for ompd compilation. # This is acquired through RH Software Collections. if [ -f /opt/rh/rh-python36/enable ]; then echo "==> Using python3.6 out of rh tools." - DEBUGCMAKEOPTS=("${DEBUGCMAKEOPTS[@]}" - -DPython3_ROOT_DIR=/opt/rh/rh-python36/root/bin - -DPYTHON_HEADERS=/opt/rh/rh-python36/root/usr/include/python3.6m) + MYCMAKEOPTS+=(-DPython3_ROOT_DIR=/opt/rh/rh-python36/root/bin + -DPYTHON_HEADERS=/opt/rh/rh-python36/root/usr/include/python3.6m) fi + else + MYCMAKEOPTS+=(-DCMAKE_BUILD_TYPE=Release) + fi - echo - if [ "$SANITIZER" != 1 ] ; then - echo "rm -rf $BUILD_DIR/build/offload_debug" - rm -rf "$BUILD_DIR/build/offload_debug" - echo " -----Running offload cmake for debug ---- " - mkdir -p "$BUILD_DIR/build/offload_debug" - cd "$BUILD_DIR/build/offload_debug" || exit - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - PREFIX_PATH="-DCMAKE_PREFIX_PATH=$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - "${AOMP_DEBUG_ORIGIN_RPATH[@]}") - else - PREFIX_PATH="-DCMAKE_PREFIX_PATH=$INSTALL_PREFIX/lib/cmake" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - fi + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DSANITIZER_AMDGPU=1 + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF) + fi - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$PREFIX_PATH" \ - -DCMAKE_C_FLAGS="$CFLAGS -g" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -g $(cmquot "${_prefix_map[@]}")" \ - -DOFFLOAD_LIBDIR_SUFFIX="-debug" \ - -DLLVM_LIBDIR_SUFFIX="-debug" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload"; then - echo "ERROR offload debug cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 - fi - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DSANITIZER_AMDGPU=1) - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - "${AOMP_ASAN_ORIGIN_RPATH[@]}") + # rpath options + if "$Standalone"; then + if asan_config "$Cfg"; then + MYCMAKEOPTS+=("${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake") + else + if debug_config "$Cfg"; then + MYCMAKEOPTS+=("${AOMP_DEBUG_ORIGIN_RPATH[@]}") else - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH;$INSTALL_PREFIX/lib/llvm/lib/asan" - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - fi - echo " -----Running offload cmake for debug-asan ---- " - mkdir -p "$BUILD_DIR/build/offload_debug/asan" - cd "$BUILD_DIR/build/offload_debug/asan" || exit - echo "${AOMP_CMAKE}" "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DOFFLOAD_LIBDIR_SUFFIX="-debug/asan" \ - -DLLVM_LIBDIR_SUFFIX="-debug/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DOFFLOAD_LIBDIR_SUFFIX="-debug/asan" \ - -DLLVM_LIBDIR_SUFFIX="-debug/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload"; then - echo "ERROR offload debug cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 + MYCMAKEOPTS+=("${AOMP_ORIGIN_RPATH[@]}") fi + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake") + fi + else + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH;$INSTALL_PREFIX/lib/llvm/lib/asan") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$INSTALL_PREFIX/lib/cmake") fi + MYCMAKEOPTS+=("${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi -if [ "$1" != "install" ] ; then -if [ "$AOMP_LEGACY_OPENMP" == "1" ] && [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/offload" || exit - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/offload ---- " - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_DIR/build/offload" - echo " $AOMP_NINJA_BIN" - exit 1 - fi -fi + # libdir suffix options + LibdirSuffix=$(libdir_suffix "$Cfg") -if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/offload/asan" || exit - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/offload/asan ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_DIR/build/offload/asan" - echo " $AOMP_NINJA_BIN" - exit 1 + if [ -n "$LibdirSuffix" ]; then + MYCMAKEOPTS+=(-DOFFLOAD_LIBDIR_SUFFIX="$LibdirSuffix" + -DLLVM_LIBDIR_SUFFIX="$LibdirSuffix") fi -fi -if [ "$AOMP_BUILD_PERF" == "1" ] ; then - cd "$BUILD_DIR/build/offload_perf" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/offload_perf ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/offload_perf/asan" || exit - echo - echo - echo " ----- Running $AOMP_NINJA_BIN for $BUILD_DIR/build/offload_perf/asan ----- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 - fi + # C/C++ flags + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + elif debug_config "$Cfg"; then + _prefix_map=(-fdebug-prefix-map="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload=$_ompd_src_dir/offload") + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$CFLAGS -g" + -DCMAKE_CXX_FLAGS="$CXXFLAGS -g $(cmquot "${_prefix_map[@]}")") fi -fi -if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - if [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/offload_debug" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/offload_debug ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 - fi - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/offload_debug/asan" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/offload_debug/asan ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 - fi + echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ + "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload" + + if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ + "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload"; then + echo "ERROR offload cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 fi -fi - - echo - echo "Successful build of ./build_offload.sh . Please run:" - echo " ./build_offload.sh install " - echo -fi -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - if [ "$AOMP_LEGACY_OPENMP" == "1" ] && [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/offload" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib ----- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local NinjaBin + local Jobs + BuildDir=$(get_build_dir "$Cfg") + NinjaBin="$(cfgvar AOMP_NINJA_BIN)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $NinjaBin for $BuildDir ---- " + if ! $NinjaBin -j "$Jobs"; then + echo " " + echo "ERROR: $NinjaBin -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" + echo " $NinjaBin" + exit 1 fi - fi + popd >& /dev/null || exit +} - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/offload/asan" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib/asan ----- " +task_install() { + local Cfg=$1 + local BuildDir + local NinjaBin + local Jobs + BuildDir=$(get_build_dir "$Cfg") + NinjaBin="$(cfgvar AOMP_NINJA_BIN)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - fi + pushd "$BuildDir" >& /dev/null || exit - if [ "$AOMP_BUILD_PERF" == "1" ]; then - cd "$BUILD_DIR/build/offload_perf" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib-perf ----- " + echo " -----Installing to $LLVM_INSTALL_LOC/lib ----- " - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/offload_perf/asan" || exit - echo - echo " ----- Installing to $LLVM_INSTALL_LOC/lib-perf/asan ----- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - fi + if ! $SUDO "$NinjaBin" -j "$Jobs" install; then + echo "ERROR $NinjaBin install failed " + exit 1 fi - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - if [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/offload_debug" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib-debug ---- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/offload_debug/asan" || exit - echo " -----Installing to $LLVM_INSTALL_LOC/lib-debug/asan ---- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - fi - - # Copy selected debugable runtime sources into the installation directory - # $_ompd_src_dir directory to satisfy the above CXXOPT -fdebug-prefix-map. - $SUDO mkdir -p "$_ompd_src_dir/offload" - $SUDO mkdir -p "$_ompd_src_dir/offload/plugins-nextgen" - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - _from_dir_src="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload/libomptarget" - _from_dir_plugins="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload/plugins-nextgen" - else - _from_dir_src="$LLVM_PROJECT_ROOT/offload/libomptarget" - _from_dir_plugins="$LLVM_PROJECT_ROOT/offload/plugins-nextgen" - fi - echo cp -rp "$_from_dir_src" "$_ompd_src_dir/offload" - $SUDO cp -rp "$_from_dir_src" "$_ompd_src_dir/offload" - echo cp -rp "$_from_dir_plugins" "$_ompd_src_dir/offload" - $SUDO cp -rp "$_from_dir_plugins" "$_ompd_src_dir/offload" - fi # end of AOMP_BUILD_DEBUG install block - - if [ "$AOMP_APPLY_ATD_AMD_STAGING_PATCH" == 1 ] ; then - removepatch "$REPO_DIR" + popd >& /dev/null || exit +} + +task_postinstall() { + local Cfg=$1 + local Standalone + local LLVMRoot + local _from_dir_src + local _from_dir_plugins + + Standalone="$(cfgbool AOMP_STANDALONE_BUILD)" + LLVMRoot="$(cfgvar LLVM_PROJECT_ROOT)" + + # Copy selected debugable runtime sources into the installation directory + # $_ompd_src_dir directory to satisfy the above CXXOPT -fdebug-prefix-map. + $SUDO mkdir -p "$_ompd_src_dir/offload" + $SUDO mkdir -p "$_ompd_src_dir/offload/plugins-nextgen" + if "$Standalone"; then + _from_dir_src="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload/libomptarget" + _from_dir_plugins="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload/plugins-nextgen" + else + _from_dir_src="$LLVMRoot/offload/libomptarget" + _from_dir_plugins="$LLVMRoot/offload/plugins-nextgen" fi + echo cp -rp "$_from_dir_src" "$_ompd_src_dir/offload" + $SUDO cp -rp "$_from_dir_src" "$_ompd_src_dir/offload" + echo cp -rp "$_from_dir_plugins" "$_ompd_src_dir/offload" + $SUDO cp -rp "$_from_dir_plugins" "$_ompd_src_dir/offload" +} + +do_list_configs() { + local Sanitizer + local LegacyOpenMP + local BuildSanitizer + local BuildPerf + local BuildDebug + + Sanitizer="$(cfgbool SANITIZER)" + LegacyOpenMP="$(cfgbool AOMP_LEGACY_OPENMP)" + BuildSanitizer="$(cfgbool AOMP_BUILD_SANITIZER)" + BuildPerf="$(cfgbool AOMP_BUILD_PERF)" + BuildDebug="$(cfgbool AOMP_BUILD_DEBUG)" + + if ! "$Sanitizer" && "$LegacyOpenMP" ; then + echo "default" + fi + if "$BuildSanitizer"; then + echo "asan" + fi + if "$BuildPerf"; then + echo "perf" + if "$BuildSanitizer"; then + echo "perf+asan" + fi + fi + if "$BuildDebug" ; then + if ! "$Sanitizer"; then + echo "debug" + fi + if "$BuildSanitizer"; then + echo "debug+asan" + fi + fi +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + case "$Cfg" in + debug) + echo "postinstall" + ;; + *) + ;; + esac + else + echo "Unknown config '$Cfg'" + fi +} -fi # end of install block +command_dispatcher "$@" From 0d51d28815ed3e76850061c8d305dbb47141b9ea Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 05:52:19 -0500 Subject: [PATCH 03/71] realpath arg tweak --- bin/build_offload.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/build_offload.sh b/bin/build_offload.sh index 8f0bca2953..7b8bc41e7f 100755 --- a/bin/build_offload.sh +++ b/bin/build_offload.sh @@ -10,7 +10,7 @@ set -e shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" From 55b2f71c6394366c93a4f46c5279c7fb17f92776 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 06:54:46 -0500 Subject: [PATCH 04/71] [AOMP] Taskify build_comgr.sh Refactor build_comgr.sh into the taskified control-flow-inversion form established by build_offload.sh: split work into task_* functions over default/asan configs, add introspection hooks (list_configs/list_tasks), and dispatch via command_dispatcher while preserving the existing nocmake/cmake/install CLI behavior. Add INSTALL_COMGR to the get_config_var_string allow-list in aomp_utils. --- bin/aomp_utils | 2 +- bin/build_comgr.sh | 322 ++++++++++++++++++++++++++++----------------- 2 files changed, 202 insertions(+), 122 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index a60a45b4b4..d045dd1646 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -291,7 +291,7 @@ get_config_var_string() { return ;; LLVM_INSTALL_LOC|AOMP_PROC|CUDABIN|CUDAT|CUDAINCLUDE|REPO_DIR|\ - AOMP_NINJA_BIN|AOMP_JOB_THREADS|LLVM_PROJECT_ROOT) + AOMP_NINJA_BIN|AOMP_JOB_THREADS|LLVM_PROJECT_ROOT|INSTALL_COMGR) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_comgr.sh b/bin/build_comgr.sh index 8b8643b5a5..873b210715 100755 --- a/bin/build_comgr.sh +++ b/bin/build_comgr.sh @@ -3,8 +3,13 @@ # build_comgr.sh: Script to build the code object manager for aomp # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" @@ -14,11 +19,20 @@ INSTALL_COMGR=${INSTALL_COMGR:-$AOMP_INSTALL_DIR} REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME +# Get a configuration (environment) variable for this config +cfgvar() { + get_config_var_string comgr "$1" +} + +cfgbool() { + get_config_var_bool comgr "$1" +} + if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the code object manager" - echo " It gets the source from: $AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/comgr" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/comgr" echo " It installs in: $INSTALL_COMGR" echo " " echo "Example commands and actions: " @@ -28,145 +42,211 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit -fi - -if [ ! -d "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_COMGR_REPO_NAME set correctly?" - exit 1 + exit 0 fi -check_writable_installdir "$1" "$INSTALL_COMGR" - -osversion=$(cat /etc/os-release) -#if [ "$AOMP_MAJOR_VERSION" != "12" ] && [[ "$osversion" =~ "Ubuntu 16" ]]; then - patchrepo "$REPO_DIR" -#fi +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/comgr" + ;; + "asan") + echo -n "$BuildDir/comgr/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_COMGR +} + +asan_config() { + local Cfg=$1 + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_COMGR_REPO_NAME set correctly?" + exit 1 + fi -#if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - #LDFLAGS=$(shquot '-fuse-ld=lld' "${ASAN_FLAGS[@]}") - #export LDFLAGS -#fi + check_writable_installdir "$1" "$(cfgvar INSTALL_COMGR)" +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then +task_patch() { + patchrepo "$REPO_DIR" +} - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/build_comgr" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." +task_unpatch() { + local osversion + osversion=$(cat /etc/os-release) + if [ "$AOMP_MAJOR_VERSION" != "12" ] && [[ "$osversion" =~ "Ubuntu 16" ]]; then + removepatch "$REPO_DIR" + fi +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "$SUDO rm -rf $(shquot "$BuildDir")" + $SUDO rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local DEVICELIBS_BUILD_PATH + local PACKAGE_ROOT + local COMMON_PREFIX_PATH + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" - BUILDTYPE="Release" - echo $SUDO rm -rf "$BUILD_AOMP/build/comgr" - $SUDO rm -rf "$BUILD_AOMP/build/comgr" export LLVM_DIR=$AOMP_INSTALL_DIR export Clang_DIR=$AOMP_INSTALL_DIR - mkdir -p "$BUILD_AOMP/build/comgr" - cd "$BUILD_AOMP/build/comgr" || exit - echo " -----Running comgr cmake ---- " - DEVICELIBS_BUILD_PATH=$AOMP_REPOS/build/AOMP_LIBDEVICE_REPO_NAME - PACKAGE_ROOT=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME + PACKAGE_ROOT=$SrcDir COMMON_PREFIX_PATH="$AOMP/include/amd_comgr;$DEVICELIBS_BUILD_PATH;$PACKAGE_ROOT;$LLVM_INSTALL_LOC" - MYCMAKEOPTS=( - -DCMAKE_INSTALL_PREFIX="$INSTALL_COMGR" - -DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DBUILD_TESTING=OFF - -DROCM_DIR="$AOMP_INSTALL_DIR" - -DLLVM_DIR="$AOMP_INSTALL_DIR" - -DClang_DIR="$AOMP_INSTALL_DIR") - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - -DCMAKE_PREFIX_PATH="$AOMP/lib/cmake;$COMMON_PREFIX_PATH" \ - -DCMAKE_INSTALL_LIBDIR=lib "${AOMP_ORIGIN_RPATH[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - -DCMAKE_PREFIX_PATH="$AOMP/lib/cmake;$COMMON_PREFIX_PATH" \ - -DCMAKE_INSTALL_LIBDIR=lib "${AOMP_ORIGIN_RPATH[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME"; then - echo "ERROR comgr cmake failed. cmake flags" - exit 1 - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - mkdir -p "$BUILD_AOMP/build/comgr/asan" - cd "$BUILD_AOMP/build/comgr/asan" || exit - echo " -----Running comgr-asan cmake ----- " - ASAN_CMAKE_OPTS=("${MYCMAKEOPTS[@]}" - -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++") - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake;$COMMON_PREFIX_PATH:$AOMP/lib/cmake" \ - -DCMAKE_INSTALL_LIBDIR=lib/asan "$(shquot "${AOMP_ASAN_ORIGIN_RPATH[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake;$COMMON_PREFIX_PATH;$AOMP/lib/cmake" \ - -DCMAKE_INSTALL_LIBDIR=lib/asan "${AOMP_ASAN_ORIGIN_RPATH[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME"; then - echo "ERROR comgr-asan cmake failed. cmake flags" - exit 1 - fi + MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_COMGR)" + -DCMAKE_BUILD_TYPE=Release + -DBUILD_TESTING=OFF + -DROCM_DIR="$AOMP_INSTALL_DIR" + -DLLVM_DIR="$AOMP_INSTALL_DIR" + -DClang_DIR="$AOMP_INSTALL_DIR") + + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake;$COMMON_PREFIX_PATH;$AOMP/lib/cmake" + -DCMAKE_INSTALL_LIBDIR=lib/asan + "${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP/lib/cmake;$COMMON_PREFIX_PATH" + -DCMAKE_INSTALL_LIBDIR=lib + "${AOMP_ORIGIN_RPATH[@]}") fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi -cd "$BUILD_AOMP/build/comgr" || exit -echo -echo " -----Running make for comgr ---- " + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running comgr $Cfg cmake ---- " + echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" -if ! make -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/comgr" - echo " make" + if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR comgr $Cfg cmake failed. cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 -fi - -if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_AOMP/build/comgr/asan" || exit - echo " -----Running make for comgr-asan ---- " - - if ! make -j "$AOMP_JOB_THREADS"; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for comgr $Cfg ---- " + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_AOMP/build/comgr/asan" + echo " cd $BuildDir" echo " make" exit 1 fi -fi - -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP/build/comgr" || exit - echo " -----Installing to $INSTALL_COMGR/lib ----- " - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + if asan_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib/asan ----" + else + echo " -----Installing to $InstallDir/lib ----- " + fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_AOMP/build/comgr/asan" || exit - echo " -----Installing to $INSTALL_COMGR/lib/asan ----" + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit - if ! $SUDO make install; then - echo "ERROR make install failed" - exit 1 - fi - fi - # amd_comgr.h is now in amd_comgr/amd_comgr.h, so remove depracated file - [ -f "$INSTALL_COMGR/include/amd_comgr.h" ] && rm "$INSTALL_COMGR/include/amd_comgr.h" - if [ "$AOMP_MAJOR_VERSION" != "12" ] && [[ "$osversion" =~ "Ubuntu 16" ]]; then - removepatch "$REPO_DIR" + if ! asan_config "$Cfg"; then + # amd_comgr.h is now in amd_comgr/amd_comgr.h, so remove deprecated file + if [ -f "$InstallDir/include/amd_comgr.h" ]; then + rm "$InstallDir/include/amd_comgr.h" fi -fi + fi +} + +do_list_configs() { + echo "default" + if "$(cfgbool AOMP_BUILD_SANITIZER)"; then + echo "asan" + fi +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 1a7fd5c900c1acd6aeadcdd43db95aa7df6c055b Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 06:59:47 -0500 Subject: [PATCH 05/71] [AOMP] Taskify build_rocr.sh Refactor build_rocr.sh into the taskified form: split into task_* functions over default/asan/debug configs, with the debug runtime-source copy expressed as task_postinstall. Add introspection hooks and dispatch via command_dispatcher, preserving the nocmake/cmake/install CLI. Add INSTALL_ROCM to the get_config_var_string allow-list in aomp_utils. --- bin/aomp_utils | 3 +- bin/build_rocr.sh | 433 ++++++++++++++++++++++++++-------------------- 2 files changed, 250 insertions(+), 186 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index d045dd1646..742e6842ae 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -291,7 +291,8 @@ get_config_var_string() { return ;; LLVM_INSTALL_LOC|AOMP_PROC|CUDABIN|CUDAT|CUDAINCLUDE|REPO_DIR|\ - AOMP_NINJA_BIN|AOMP_JOB_THREADS|LLVM_PROJECT_ROOT|INSTALL_COMGR) + AOMP_NINJA_BIN|AOMP_JOB_THREADS|LLVM_PROJECT_ROOT|INSTALL_COMGR|\ + INSTALL_ROCM) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_rocr.sh b/bin/build_rocr.sh index 1d5958d5ce..b016ef7420 100755 --- a/bin/build_rocr.sh +++ b/bin/build_rocr.sh @@ -5,20 +5,35 @@ # Requires that "build_roct.sh install" be installed first # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- INSTALL_ROCM=${INSTALL_ROCM:-$AOMP_INSTALL_DIR} +REPO_DIR=$AOMP_REPOS/$AOMP_ROCR_REPO_NAME +_ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" + +cfgvar() { + get_config_var_string rocr "$1" +} + +cfgbool() { + get_config_var_bool rocr "$1" +} if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the ROCM runtime libraries" - echo " It gets the source from: $AOMP_REPOS/$AOMP_ROCR_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/rocr" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/rocr" echo " It installs in: $INSTALL_ROCM" echo " " echo "Example commands and actions: " @@ -28,209 +43,257 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit + exit 0 fi -if [ ! -d "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_ROCR_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_ROCR_REPO_NAME set correctly?" - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR" +} -check_writable_installdir "$1" "$INSTALL_ROCM" +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" -patchrepo "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" + case "$Cfg" in + "default") + echo -n "$BuildDir/rocr" + ;; + "asan") + echo -n "$BuildDir/rocr/asan" + ;; + "debug") + echo -n "$BuildDir/rocr_debug" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} -#if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - #LDFLAGS=$(shquot '-fuse-ld=lld' "${ASAN_FLAGS[@]}") - #export LDFLAGS -#fi +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_ROCM +} -_ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" +asan_config() { + local Cfg=$1 + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then +debug_config() { + local Cfg=$1 + case "$Cfg" in + debug|debug+*) + return 0 + ;; + *) + ;; + esac + return 1 +} - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/build_rocr" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" - BUILDTYPE="Release" - echo "rm -rf $BUILD_AOMP/build/rocr" - rm -rf "$BUILD_AOMP/build/rocr" - export PATH=/opt/rocm/llvm/bin:$PATH - declare -a MYCMAKEOPTS - MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$INSTALL_ROCM" - -DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" - -DIMAGE_SUPPORT=OFF "${AOMP_ORIGIN_RPATH[@]}" - -DCMAKE_INSTALL_LIBDIR=lib - -DCMAKE_C_COMPILER="${AOMP_INSTALL_DIR}/lib/llvm/bin/clang" - -DCMAKE_CXX_COMPILER="${AOMP_INSTALL_DIR}/lib/llvm/bin/clang++" - -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" - -DBUILD_SHARED_LIBS=On) - mkdir -p "$BUILD_AOMP/build/rocr" - cd "$BUILD_AOMP/build/rocr" || exit - echo - echo " -----Running rocr cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME"; then - echo "ERROR rocr cmake failed. cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_ROCR_REPO_NAME set correctly?" exit 1 fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - declare -a ASAN_CMAKE_OPTS - # unused prefix path :$ROCM_DIR/lib/asan/cmake;${AOMP_INSTALL_DIR}/lib/cmake - ASAN_CMAKE_OPTS=(-DCMAKE_C_COMPILER="${AOMP_INSTALL_DIR}/lib/llvm/bin/clang" - -DCMAKE_CXX_COMPILER="${AOMP_INSTALL_DIR}/lib/llvm/bin/clang++" - -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" - -DCMAKE_INSTALL_LIBDIR=lib/asan - -DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" - -DIMAGE_SUPPORT=OFF "${AOMP_ASAN_ORIGIN_RPATH[@]}" - -DBUILD_SHARED_LIBS=On) - mkdir -p "$BUILD_AOMP/build/rocr/asan" - cd "$BUILD_AOMP/build/rocr/asan" || exit - echo - echo " ----Running rocr-asan cmake ----- " - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME"; then - echo "ERROR rocr-asan cmake failed. cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - echo "rm -rf $BUILD_AOMP/build/rocr_debug" - [ -d "$BUILD_AOMP/build/rocr_debug" ] && rm -rf "$BUILD_AOMP/build/rocr_debug" - declare -a ROCR_CMAKE_OPTS - ROCR_CMAKE_OPTS=(-DCMAKE_C_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang" - -DCMAKE_CXX_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" - -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" - -DCMAKE_BUILD_TYPE=Debug - "${AOMP_DEBUG_ORIGIN_RPATH[@]}" - -DCMAKE_INSTALL_LIBDIR=lib-debug - -DBUILD_SHARED_LIBS=On - -DIMAGE_SUPPORT=OFF - -DTARGET_DEVICES="gfx900;gfx90a;gfx942;gfx1010;gfx1030;gfx1100;gfx1200") - echo - echo " -----Running rocr_debug cmake -----" - mkdir -p "$BUILD_AOMP/build/rocr_debug" - cd "$BUILD_AOMP/build/rocr_debug" || exit - _prefix_map=(-fdebug-prefix-map="$AOMP_REPOS/$AOMP_ROCR_REPO_NAME=$_ompd_src_dir/rocr") - echo "${AOMP_CMAKE}" "$(shquot "${ROCR_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot -g "${_prefix_map[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot -g "${_prefix_map[@]}")\"" \ - "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" - - if ! ${AOMP_CMAKE} "${ROCR_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot -g "${_prefix_map[@]}")" \ - "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME"; then - echo "ERROR rocr_debug cmake failed.cmake flags" - echo " $(shquot "${ROCR_CMAKE_OPTS[@]}")" - exit 1 - fi - fi -fi + check_writable_installdir "$1" "$(cfgvar INSTALL_ROCM)" +} -if [ "$1" = "cmake" ]; then - exit 0 -fi +task_patch() { + patchrepo "$REPO_DIR" +} -cd "$BUILD_AOMP/build/rocr" || exit -echo -echo " -----Running make for rocr ---- " -echo "make -j $AOMP_JOB_THREADS" +task_unpatch() { + removepatch "$REPO_DIR" +} -if ! make -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/rocr" - echo " make" +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local -a MYCMAKEOPTS + local -a _prefix_map + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + export PATH=/opt/rocm/llvm/bin:$PATH + + if asan_config "$Cfg"; then + MYCMAKEOPTS=(-DCMAKE_C_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang" + -DCMAKE_CXX_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" + -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_LIBDIR=lib/asan + -DCMAKE_BUILD_TYPE="$BUILD_TYPE" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" + -DIMAGE_SUPPORT=OFF "${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DBUILD_SHARED_LIBS=On + -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + elif debug_config "$Cfg"; then + _prefix_map=(-fdebug-prefix-map="$SrcDir=$_ompd_src_dir/rocr") + MYCMAKEOPTS=(-DCMAKE_C_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang" + -DCMAKE_CXX_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" + -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_BUILD_TYPE=Debug + "${AOMP_DEBUG_ORIGIN_RPATH[@]}" + -DCMAKE_INSTALL_LIBDIR=lib-debug + -DBUILD_SHARED_LIBS=On + -DIMAGE_SUPPORT=OFF + -DTARGET_DEVICES="gfx900;gfx90a;gfx942;gfx1010;gfx1030;gfx1100;gfx1200" + -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot -g "${_prefix_map[@]}")") + else + MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_ROCM)" + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" + -DIMAGE_SUPPORT=OFF "${AOMP_ORIGIN_RPATH[@]}" + -DCMAKE_INSTALL_LIBDIR=lib + -DCMAKE_C_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang" + -DCMAKE_CXX_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" + -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" + -DBUILD_SHARED_LIBS=On) + fi + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running rocr $Cfg cmake ---- " + echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" + + if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR rocr $Cfg cmake failed. cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 -fi + fi + popd >& /dev/null || exit +} -if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_AOMP/build/rocr/asan" || exit - echo - echo " -----Running make for rocr-asan ---- " - echo "make -j $AOMP_JOB_THREADS" +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" - if ! make -j "$AOMP_JOB_THREADS"; then + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocr $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_AOMP/build/rocr/asan" + echo " cd $BuildDir" echo " make" exit 1 fi -fi -if [ "$AOMP_BUILD_DEBUG" == 1 ] ; then - cd "$BUILD_AOMP/build/rocr_debug" || exit - echo - echo " ----- Running make for rocr_debug ----- " - - if ! make -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/rocr_debug" - echo " make" - exit 1 + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + if asan_config "$Cfg"; then + echo " ------Installing to $InstallDir/lib/asan ------ " + elif debug_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib-debug ----- " + else + echo " -----Installing to $InstallDir/lib ----- " fi -fi -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP/build/rocr" || exit - echo " -----Installing to $INSTALL_ROCM/lib ----- " - echo "$SUDO make install " - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_AOMP/build/rocr/asan" || exit - echo " ------Installing to $INSTALL_ROCM/lib/asan ------ " - echo "$SUDO make install" - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - fi - if [ "$AOMP_BUILD_DEBUG" == 1 ] ; then - cd "$BUILD_AOMP/build/rocr_debug" || exit - echo " -----Installing to $INSTALL_ROCM/lib-debug ----- " - if ! $SUDO make install; then - echo "ERROR make install for rocr failed " - exit 1 - fi - # copy rocr sources into the installation for runtime source debugging - _dirs="runtime/hsa-runtime/image runtime/hsa-runtime/inc runtime/hsa-runtime/core runtime/hsa-runtime/loader runtime/hsa-runtime/pcs libhsakmt/src libhsakmt/include" - for _dirname in $_dirs ; do - $SUDO mkdir -p "$_ompd_src_dir/rocr/$_dirname" - echo "cp -r $AOMP_REPOS/$AOMP_ROCR_REPO_NAME/$_dirname/ $_ompd_src_dir/rocr/$_dirname/" - $SUDO cp -r "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME/$_dirname/" "$_ompd_src_dir/rocr/$_dirname/" - done - # remove non-source files to save space - find "$_ompd_src_dir/rocr" -type f | grep -v "\.cpp$\|\.h$\|\.hpp$\|\.c$\|\.s$" | xargs rm - fi - removepatch "$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" -fi + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +task_postinstall() { + local Cfg=$1 + local SrcDir + local _dirs + local _dirname + SrcDir="$(get_src_dir)" + + # copy rocr sources into the installation for runtime source debugging + _dirs="runtime/hsa-runtime/image runtime/hsa-runtime/inc runtime/hsa-runtime/core runtime/hsa-runtime/loader runtime/hsa-runtime/pcs libhsakmt/src libhsakmt/include" + for _dirname in $_dirs ; do + $SUDO mkdir -p "$_ompd_src_dir/rocr/$_dirname" + echo "cp -r $SrcDir/$_dirname/ $_ompd_src_dir/rocr/$_dirname/" + $SUDO cp -r "$SrcDir/$_dirname/" "$_ompd_src_dir/rocr/$_dirname/" + done + # remove non-source files to save space + find "$_ompd_src_dir/rocr" -type f | grep -v "\.cpp$\|\.h$\|\.hpp$\|\.c$\|\.s$" | xargs -r rm +} + +do_list_configs() { + echo "default" + if "$(cfgbool AOMP_BUILD_SANITIZER)"; then + echo "asan" + fi + if "$(cfgbool AOMP_BUILD_DEBUG)"; then + echo "debug" + fi +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + case "$Cfg" in + debug) + echo "postinstall" + ;; + *) + ;; + esac + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 114fae5d783f83a702652a10b3bd3c72ee2b19b9 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 07:14:59 -0500 Subject: [PATCH 06/71] [AOMP] Taskify build_project.sh Refactor build_project.sh into the taskified form. The single (default) config build is split into task_* functions: cmake-option assembly and the source version-banner patch move into task_cmake (via the fixup_source_banner helper), the partial/full builds into task_build, and install plus the amd* symlinks and per-driver .cfg generation into task_install. rocr/ATD patching becomes task_patch/task_unpatch. Add INSTALL_PROJECT to the get_config_var_string allow-list in aomp_utils. --- bin/aomp_utils | 2 +- bin/build_project.sh | 571 +++++++++++++++++++++++++------------------ 2 files changed, 334 insertions(+), 239 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 742e6842ae..f06abe6ed9 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -292,7 +292,7 @@ get_config_var_string() { ;; LLVM_INSTALL_LOC|AOMP_PROC|CUDABIN|CUDAT|CUDAINCLUDE|REPO_DIR|\ AOMP_NINJA_BIN|AOMP_JOB_THREADS|LLVM_PROJECT_ROOT|INSTALL_COMGR|\ - INSTALL_ROCM) + INSTALL_ROCM|INSTALL_PROJECT) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_project.sh b/bin/build_project.sh index 0700200a98..76b76575c6 100755 --- a/bin/build_project.sh +++ b/bin/build_project.sh @@ -8,198 +8,65 @@ # # See the help text below, run 'build_project.sh -h' for more information. # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -echo "LLVM PROJECTS TO BUILD:$AOMP_PROJECTS_LIST" +BUILD_TYPE=${BUILD_TYPE:-Release} INSTALL_PROJECT=${INSTALL_PROJECT:-$LLVM_INSTALL_LOC} - WEBSITE="http\:\/\/github.com\/ROCm\/aomp" - -# Check-openmp prep -# Patch rocr ROCR_REPO_DIR=$AOMP_REPOS/$AOMP_ROCR_REPO_NAME -patchrepo "$ROCR_REPO_DIR" - -# Patch llvm-project with ATD patch customized for amd-staging. -# WARNING: This patch (ATD_ASO_full.patch) rarely applies cleanly -# because of its size and constant trunk merges to amd-staging. -# This is why default is 0 (OFF). REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME -if [ "$AOMP_APPLY_ATD_AMD_STAGING_PATCH" == 1 ] ; then - patchrepo "$REPO_DIR" -fi - -# End check-openmp prep - -declare -a COMPILERS -declare -a _qmathopt -declare -a _amdflangrtopt -# Enable AMD-specific Fortran runtime extensions if not skipped -_amdflangrtopt=(-DFLANG_RT_INCLUDE_AMD=ON) -if [ "$AOMP_SKIP_AMD_FLANGRT" == "1" ]; then - _amdflangrtopt=() -fi +cfgvar() { + get_config_var_string project "$1" +} -# Enable support for real(kind=16) via libquadmath -_qmathopt=(-DFLANG_RUNTIME_F128_MATH_LIB=libquadmath) - -if [ "$AOMP_PROC" == "ppc64le" ] ; then - COMPILERS=(-DCMAKE_C_COMPILER=/usr/bin/gcc-7 - -DCMAKE_CXX_COMPILER=/usr/bin/g++-7) - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}PowerPC" -else - COMPILERS=(-DCMAKE_C_COMPILER="$AOMP_CC_COMPILER" - -DCMAKE_CXX_COMPILER="$AOMP_CXX_COMPILER") - if [ "$AOMP_PROC" == "aarch64" ] ; then - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64;SPIRV" - _qmathopt=() - else - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86;SPIRV" - fi -fi - -# When building from release source (no git), turn off test items that are not distributed -# also ubuntu 16.04 only has python 3.5 and lit testing needs 3.6 minimum, so turn off -# testing with ubuntu 16.04 which goes EOL in April 2021. -declare -a DO_TESTS_OPTS -if [ -z ${DO_TESTS+x} ]; then - DO_TESTS_OPTS=(-DLLVM_BUILD_TESTS=ON - -DLLVM_INCLUDE_TESTS=ON - -DCLANG_INCLUDE_TESTS=ON) -else - # Incoming DO_TESTS is a string with space-separated arguments. Convert it - # to an array. - IFS=" " read -r -a DO_TESTS_OPTS <<< "$DO_TESTS" -fi -#-DCOMPILER_RT_INCLUDE_TESTS=OFF" - -if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then - standalone_word="_STANDALONE" -else - standalone_word="" -fi - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN=() -else - AOMP_SET_NINJA_GEN=(-G Ninja) -fi - -if [ "$AOMP_LEGACY_OPENMP" != 0 ]; then - LLVM_RUNTIMES="libcxx;libcxxabi;libunwind;compiler-rt" -else - LLVM_RUNTIMES="libcxx;libcxxabi;libunwind;openmp;offload;compiler-rt;flang-rt" -fi - -rocmdevicelib_loc_new=lib/llvm/lib/clang/$AOMP_MAJOR_VERSION/lib/amdgcn - -GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') - -declare -a MYCMAKEOPTS - -MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_INSTALL_PREFIX="$INSTALL_PROJECT" - -DLLVM_ENABLE_ASSERTIONS=ON - -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" - "${COMPILERS[@]}" - -DLLVM_VERSION_SUFFIX="_AOMP${standalone_word}_$AOMP_VERSION_STRING" - -DCLANG_VENDOR="AOMP${standalone_word}_$AOMP_VERSION_STRING" - "$LLVM_FORCE_VC_REVISION_OPT" - "$LLVM_FORCE_VC_REPOSITORY_OPT" - -DCLANG_DEFAULT_PIE_ON_LINUX=0 - -DLLVM_ENABLE_ZLIB=ON - -DBUG_REPORT_URL='https://github.com/ROCm/aomp' - -DLLVM_ENABLE_BINDINGS=OFF - -DCMAKE_PREFIX_PATH=$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME/lib/cmake - -DLLVM_INCLUDE_BENCHMARKS=OFF - "${DO_TESTS_OPTS[@]}" - "${AOMP_ORIGIN_RPATH[@]}" - -DCLANG_DEFAULT_LINKER=lld - "${AOMP_SET_NINJA_GEN[@]}" - "${_qmathopt[@]}" - "${_amdflangrtopt[@]}" - -DLIBOMPTARGET_BUILD_DEVICE_FORTRT=ON - -DLLVM_BUILD_LLVM_DYLIB=ON - -DLLVM_LINK_LLVM_DYLIB=ON - -DCLANG_LINK_CLANG_DYLIB=ON - -DLIBOMPTARGET_EXTERNAL_PROJECT_HSA_PATH="$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" - -DOFFLOAD_EXTERNAL_PROJECT_UNIFIED_ROCR=On - -DLIBOMPTARGET_EXTERNAL_PROJECT_ROCM_DEVICE_LIBS_PATH="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/device-libs" - -DLLVM_EXTERNAL_PROJECTS=SPIRV_TRANSLATOR - -DLLVM_EXTERNAL_SPIRV_TRANSLATOR_SOURCE_DIR="$AOMP_REPOS/SPIRV-LLVM-Translator" - -DROCM_DEVICE_LIBS_INSTALL_PREFIX_PATH="$AOMP_INSTALL_DIR" - -DROCM_DEVICE_LIBS_BITCODE_INSTALL_LOC="$rocmdevicelib_loc_new" - -DROCM_LLVM_BACKWARD_COMPAT_LINK="$AOMP_INSTALL_DIR/llvm" - -DROCM_LLVM_BACKWARD_COMPAT_LINK_TARGET="./lib/llvm" - -DLIBOMP_COPY_EXPORTS=OFF - -DLIBOMPTARGET_ENABLE_DEBUG=ON - -DLIBOMPTEST_INSTALL_COMPONENTS=ON - -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" - -DLIBOMP_USE_HWLOC=ON - -DLIBOMP_HWLOC_INSTALL_DIR="$AOMP_SUPP/hwloc" - -DOPENMP_ENABLE_LIBOMPTARGET=1 - -DLIBOMP_SHARED_LINKER_FLAGS="-Wl,--disable-new-dtags" - -DLIBOMP_INSTALL_RPATH="$AOMP_ORIGIN_RPATH_LIST" - -DLIBOMPTARGET_INSTALL_RPATH="$AOMP_ORIGIN_RPATH_LIST" - -DLIBOMPTARGET_NO_SANITIZER_AMDGPU=1 - -DLIBOMPTARGET_BUILD_DEVICE_FORTRT=On - -DCMAKE_EXPORT_COMPILE_COMMANDS=ON) - -if [ -f "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/device/CMakeLists.txt" ]; then - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" - -DLLVM_RUNTIME_TARGETS='default;amdgcn-amd-amdhsa' - -DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES='compiler-rt;libc;libcxx;libcxxabi;flang-rt;openmp' - -DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON) -fi - -# -DCLANG_LINK_FLANG_LEGACY=ON - -# Enable amdflang, amdclang, amdclang++, amdllvm. -# clang-tools-extra added to LLVM_ENABLE_PROJECTS above. -MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" - "${AOMP_CCACHE_OPTS[@]}" - -DLLVM_ENABLE_PROJECTS="$AOMP_PROJECTS_LIST" - -DCLANG_ENABLE_AMDCLANG=ON - -DLLVM_ENABLE_RUNTIMES="$LLVM_RUNTIMES" - -DLIBCXX_ENABLE_STATIC=ON - -DLIBCXXABI_ENABLE_STATIC=ON - -DLLVM_RUNTIME_TARGETS="default;amdgcn-amd-amdhsa" - -DRUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBC_PROVIDER=llvm - -DRUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBCXX_PROVIDER=llvm - -DRUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/compiler-rt/cmake/caches/AMDGPU.cmake;$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/libcxx/cmake/caches/AMDGPU.cmake" - ) - -# Enable Compiler-rt Sanitizer Build -if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" -DSANITIZER_AMDGPU=1 - -DSANITIZER_HSA_INCLUDE_PATH="$AOMP_REPOS/$AOMP_ROCR_REPO_NAME/runtime/hsa-runtime/inc" - -DSANITIZER_COMGR_INCLUDE_PATH="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/comgr/include") -fi +cfgbool() { + get_config_var_bool project "$1" +} if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi -if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then - if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi -fi - -check_writable_installdir "$1" "$INSTALL_PROJECT" - -# Fix the banner to print the AOMP version string. -if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then +get_src_dir() { + echo "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/$AOMP_PROJECT_REPO_NAME" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_PROJECT +} + +# Patch the LLVM version banner in CommandLine.cpp with the AOMP version +# string. This edits the (git-tracked) source file in place; task_install +# reverts it with "git checkout". +fixup_source_banner() { + local MONO_REPO_ID SOURCEID TEMPCLFILE ORIGCLFILE BUILDCLFILE cd "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME" || exit MONO_REPO_ID=$(git log | grep -m1 commit | cut -d" " -f2) SOURCEID="Source ID:$AOMP_VERSION_STRING-$MONO_REPO_ID" @@ -211,28 +78,9 @@ if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then echo "ERROR sed command to fix CommandLine.cpp failed." exit 1 fi -fi - -# Skip synchronization from git repos if nocmake or install are specified -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - rm -rf "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME" - mkdir -p "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME" -else - if [ ! -d "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME" ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME does not exist" - echo " run $0 without nocmake or install options. " - exit 1 - fi -fi -if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then - cd "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME" || exit if [ -f "$BUILDCLFILE" ] ; then # only copy if there has been a change to the source. - if ! diff "$TEMPCLFILE" "$BUILDCLFILE" >/dev/null; then echo "Updating $BUILDCLFILE with corrected $SOURCEID" cp "$TEMPCLFILE" "$BUILDCLFILE" @@ -244,62 +92,289 @@ if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then cp "$TEMPCLFILE" "$BUILDCLFILE" fi rm "$TEMPCLFILE" -fi +} + +task_precheck() { + if "$(cfgbool AOMP_STANDALONE_BUILD)"; then + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" + exit 1 + fi + fi + + check_writable_installdir "$1" "$(cfgvar INSTALL_PROJECT)" +} + +task_patch() { + # Patch rocr (check-openmp prep). + patchrepo "$ROCR_REPO_DIR" + + # Patch llvm-project with ATD patch customized for amd-staging. + # WARNING: This patch (ATD_ASO_full.patch) rarely applies cleanly + # because of its size and constant trunk merges to amd-staging. + # This is why default is 0 (OFF). + if "$(cfgbool AOMP_APPLY_ATD_AMD_STAGING_PATCH)"; then + patchrepo "$REPO_DIR" + fi +} + +task_unpatch() { + if "$(cfgbool AOMP_APPLY_ATD_AMD_STAGING_PATCH)"; then + removepatch "$REPO_DIR" + fi + removepatch "$ROCR_REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local standalone_word + local TARGETS_TO_BUILD + local LLVM_RUNTIMES + local rocmdevicelib_loc_new + local GFXSEMICOLONS + local -a COMPILERS + local -a _qmathopt + local -a _amdflangrtopt + local -a DO_TESTS_OPTS + local -a AOMP_SET_NINJA_GEN + local -a MYCMAKEOPTS + local -a MYLITOPTS + + echo "LLVM PROJECTS TO BUILD:$AOMP_PROJECTS_LIST" + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + + # Enable AMD-specific Fortran runtime extensions if not skipped + _amdflangrtopt=(-DFLANG_RT_INCLUDE_AMD=ON) + if [ "$AOMP_SKIP_AMD_FLANGRT" == "1" ]; then + _amdflangrtopt=() + fi + + # Enable support for real(kind=16) via libquadmath + _qmathopt=(-DFLANG_RUNTIME_F128_MATH_LIB=libquadmath) + + if [ "$AOMP_PROC" == "ppc64le" ] ; then + COMPILERS=(-DCMAKE_C_COMPILER=/usr/bin/gcc-7 + -DCMAKE_CXX_COMPILER=/usr/bin/g++-7) + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}PowerPC" + else + COMPILERS=(-DCMAKE_C_COMPILER="$AOMP_CC_COMPILER" + -DCMAKE_CXX_COMPILER="$AOMP_CXX_COMPILER") + if [ "$AOMP_PROC" == "aarch64" ] ; then + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64;SPIRV" + _qmathopt=() + else + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86;SPIRV" + fi + fi -cd "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME" || exit + # When building from release source (no git), turn off test items that are not distributed + # also ubuntu 16.04 only has python 3.5 and lit testing needs 3.6 minimum, so turn off + # testing with ubuntu 16.04 which goes EOL in April 2021. + if [ -z ${DO_TESTS+x} ]; then + DO_TESTS_OPTS=(-DLLVM_BUILD_TESTS=ON + -DLLVM_INCLUDE_TESTS=ON + -DCLANG_INCLUDE_TESTS=ON) + else + # Incoming DO_TESTS is a string with space-separated arguments. Convert it + # to an array. + IFS=" " read -r -a DO_TESTS_OPTS <<< "$DO_TESTS" + fi + #-DCOMPILER_RT_INCLUDE_TESTS=OFF" + + if "$(cfgbool AOMP_STANDALONE_BUILD)"; then + standalone_word="_STANDALONE" + else + standalone_word="" + fi + + if [ "$AOMP_USE_NINJA" == 0 ] ; then + AOMP_SET_NINJA_GEN=() + else + AOMP_SET_NINJA_GEN=(-G Ninja) + fi + + if [ "$AOMP_LEGACY_OPENMP" != 0 ]; then + LLVM_RUNTIMES="libcxx;libcxxabi;libunwind;compiler-rt" + else + LLVM_RUNTIMES="libcxx;libcxxabi;libunwind;openmp;offload;compiler-rt;flang-rt" + fi + + rocmdevicelib_loc_new=lib/llvm/lib/clang/$AOMP_MAJOR_VERSION/lib/amdgcn + + GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') + + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" + -DCMAKE_INSTALL_PREFIX="$INSTALL_PROJECT" + -DLLVM_ENABLE_ASSERTIONS=ON + -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" + "${COMPILERS[@]}" + -DLLVM_VERSION_SUFFIX="_AOMP${standalone_word}_$AOMP_VERSION_STRING" + -DCLANG_VENDOR="AOMP${standalone_word}_$AOMP_VERSION_STRING" + "${LLVM_FORCE_VC_REVISION_OPT:-}" + "${LLVM_FORCE_VC_REPOSITORY_OPT:-}" + -DCLANG_DEFAULT_PIE_ON_LINUX=0 + -DLLVM_ENABLE_ZLIB=ON + -DBUG_REPORT_URL='https://github.com/ROCm/aomp' + -DLLVM_ENABLE_BINDINGS=OFF + -DCMAKE_PREFIX_PATH="$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME/lib/cmake" + -DLLVM_INCLUDE_BENCHMARKS=OFF + "${DO_TESTS_OPTS[@]}" + "${AOMP_ORIGIN_RPATH[@]}" + -DCLANG_DEFAULT_LINKER=lld + "${AOMP_SET_NINJA_GEN[@]}" + "${_qmathopt[@]}" + "${_amdflangrtopt[@]}" + -DLIBOMPTARGET_BUILD_DEVICE_FORTRT=ON + -DLLVM_BUILD_LLVM_DYLIB=ON + -DLLVM_LINK_LLVM_DYLIB=ON + -DCLANG_LINK_CLANG_DYLIB=ON + -DLIBOMPTARGET_EXTERNAL_PROJECT_HSA_PATH="$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" + -DOFFLOAD_EXTERNAL_PROJECT_UNIFIED_ROCR=On + -DLIBOMPTARGET_EXTERNAL_PROJECT_ROCM_DEVICE_LIBS_PATH="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/device-libs" + -DLLVM_EXTERNAL_PROJECTS=SPIRV_TRANSLATOR + -DLLVM_EXTERNAL_SPIRV_TRANSLATOR_SOURCE_DIR="$AOMP_REPOS/SPIRV-LLVM-Translator" + -DROCM_DEVICE_LIBS_INSTALL_PREFIX_PATH="$AOMP_INSTALL_DIR" + -DROCM_DEVICE_LIBS_BITCODE_INSTALL_LOC="$rocmdevicelib_loc_new" + -DROCM_LLVM_BACKWARD_COMPAT_LINK="$AOMP_INSTALL_DIR/llvm" + -DROCM_LLVM_BACKWARD_COMPAT_LINK_TARGET="./lib/llvm" + -DLIBOMP_COPY_EXPORTS=OFF + -DLIBOMPTARGET_ENABLE_DEBUG=ON + -DLIBOMPTEST_INSTALL_COMPONENTS=ON + -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" + -DLIBOMP_USE_HWLOC=ON + -DLIBOMP_HWLOC_INSTALL_DIR="$AOMP_SUPP/hwloc" + -DOPENMP_ENABLE_LIBOMPTARGET=1 + -DLIBOMP_SHARED_LINKER_FLAGS="-Wl,--disable-new-dtags" + -DLIBOMP_INSTALL_RPATH="$AOMP_ORIGIN_RPATH_LIST" + -DLIBOMPTARGET_INSTALL_RPATH="$AOMP_ORIGIN_RPATH_LIST" + -DLIBOMPTARGET_NO_SANITIZER_AMDGPU=1 + -DLIBOMPTARGET_BUILD_DEVICE_FORTRT=On + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON) + + if [ -f "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/device/CMakeLists.txt" ]; then + MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" + -DLLVM_RUNTIME_TARGETS='default;amdgcn-amd-amdhsa' + -DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES='compiler-rt;libc;libcxx;libcxxabi;flang-rt;openmp' + -DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON) + fi -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then + # -DCLANG_LINK_FLANG_LEGACY=ON + + # Enable amdflang, amdclang, amdclang++, amdllvm. + # clang-tools-extra added to LLVM_ENABLE_PROJECTS above. + MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" + "${AOMP_CCACHE_OPTS[@]}" + -DLLVM_ENABLE_PROJECTS="$AOMP_PROJECTS_LIST" + -DCLANG_ENABLE_AMDCLANG=ON + -DLLVM_ENABLE_RUNTIMES="$LLVM_RUNTIMES" + -DLIBCXX_ENABLE_STATIC=ON + -DLIBCXXABI_ENABLE_STATIC=ON + -DLLVM_RUNTIME_TARGETS="default;amdgcn-amd-amdhsa" + -DRUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBC_PROVIDER=llvm + -DRUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBCXX_PROVIDER=llvm + -DRUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/compiler-rt/cmake/caches/AMDGPU.cmake;$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/libcxx/cmake/caches/AMDGPU.cmake" + ) + + # Enable Compiler-rt Sanitizer Build + if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then + MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" -DSANITIZER_AMDGPU=1 + -DSANITIZER_HSA_INCLUDE_PATH="$AOMP_REPOS/$AOMP_ROCR_REPO_NAME/runtime/hsa-runtime/inc" + -DSANITIZER_COMGR_INCLUDE_PATH="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/comgr/include") + fi + + # Fix the banner to print the AOMP version string. + if "$(cfgbool AOMP_STANDALONE_BUILD)"; then + fixup_source_banner + fi + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit echo echo " -----Running cmake ---- " MYLITOPTS=(-DLLVM_LIT_ARGS='-vv --show-unsupported --show-xfail -j 16') echo "${AOMP_CMAKE}" "$(shquot "${MYLITOPTS[@]}")" \ "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm" + "$SrcDir" if ! ${AOMP_CMAKE} "${MYLITOPTS[@]}" \ "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm" 2>&1; then + "$SrcDir" 2>&1; then echo "ERROR cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi + popd >& /dev/null || exit +} -if [ "$1" = "cmake" ]; then - exit 0 -fi +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" -echo -echo " -----Running make ---- " + pushd "$BuildDir" >& /dev/null || exit + echo + echo " -----Running make ---- " -if [ "$AOMP_LIMIT_FLANG" == "1" ] ; then - # Required for building flang on memory limited systems. - echo "${AOMP_CMAKE} --build . -- -j $AOMP_JOB_THREADS clang lld compiler-rt" - ${AOMP_CMAKE} --build . -- -j "$AOMP_JOB_THREADS" clang lld compiler-rt + if [ "$AOMP_LIMIT_FLANG" == "1" ] ; then + # Required for building flang on memory limited systems. + echo "${AOMP_CMAKE} --build . -- -j $Jobs clang lld compiler-rt" + ${AOMP_CMAKE} --build . -- -j "$Jobs" clang lld compiler-rt || true - echo "${AOMP_CMAKE} --build . -- -j $AOMP_FLANG_THREADS flang" - ${AOMP_CMAKE} --build . -- -j "$AOMP_FLANG_THREADS" flang -fi + echo "${AOMP_CMAKE} --build . -- -j $AOMP_FLANG_THREADS flang" + ${AOMP_CMAKE} --build . -- -j "$AOMP_FLANG_THREADS" flang || true + fi -# Build llvm-project in one step -echo "Running CMAKE in ${PWD}" -echo "${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS" + # Build llvm-project in one step + echo "Running CMAKE in ${PWD}" + echo "${AOMP_CMAKE} --build . -j $Jobs" -if ! ${AOMP_CMAKE} --build . -j "$AOMP_JOB_THREADS"; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" - exit 1 -fi + if ! ${AOMP_CMAKE} --build . -j "$Jobs"; then + echo "ERROR make -j $Jobs failed" + exit 1 + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local SED_AOMP_REPOS + local i + local config_file + local -a amd_compiler_symlinks + local -a amd_compiler_cfg + + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" -if [ "$1" == "install" ] ; then - echo " -----Installing to $INSTALL_PROJECT ---- " + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " if ! $SUDO "$AOMP_CMAKE" --install .; then echo "ERROR make install failed " exit 1 fi - if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then + popd >& /dev/null || exit + + if "$(cfgbool AOMP_STANDALONE_BUILD)"; then echo " " - echo "------ Linking $INSTALL_PROJECT to $AOMP -------" + echo "------ Linking $InstallDir to $AOMP -------" if [ -L "$AOMP" ] ; then $SUDO rm "$AOMP" fi @@ -307,24 +382,21 @@ if [ "$1" == "install" ] ; then fi # add executables forgot by make install but needed for testing - $SUDO cp -p "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME/bin/llvm-lit" "$LLVM_INSTALL_LOC/bin/llvm-lit" + $SUDO cp -p "$BuildDir/bin/llvm-lit" "$LLVM_INSTALL_LOC/bin/llvm-lit" # update map_config and llvm_source_root paths in the copied llvm-lit file SED_AOMP_REPOS=$(echo "$AOMP_REPOS" | sed -e 's/\//\\\\\//g') sed -ie "s/..\/..\/..\//$SED_AOMP_REPOS\//g" "$LLVM_INSTALL_LOC/bin/llvm-lit" - $SUDO cp -p "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME/bin/FileCheck" "$LLVM_INSTALL_LOC/bin/FileCheck" - $SUDO cp -p "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME/bin/count" "$LLVM_INSTALL_LOC/bin/count" - $SUDO cp -p "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME/bin/not" "$LLVM_INSTALL_LOC/bin/not" - $SUDO cp -p "$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME/bin/yaml-bench" "$LLVM_INSTALL_LOC/bin/yaml-bench" + $SUDO cp -p "$BuildDir/bin/FileCheck" "$LLVM_INSTALL_LOC/bin/FileCheck" + $SUDO cp -p "$BuildDir/bin/count" "$LLVM_INSTALL_LOC/bin/count" + $SUDO cp -p "$BuildDir/bin/not" "$LLVM_INSTALL_LOC/bin/not" + $SUDO cp -p "$BuildDir/bin/yaml-bench" "$LLVM_INSTALL_LOC/bin/yaml-bench" cd "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME" || exit git checkout llvm/lib/Support/CommandLine.cpp echo - echo "SUCCESSFUL INSTALL to $INSTALL_PROJECT with link to $AOMP" + echo "SUCCESSFUL INSTALL to $InstallDir with link to $AOMP" echo - if [ "$AOMP_APPLY_ATD_AMD_STAGING_PATCH" == 1 ] ; then - removepatch "$REPO_DIR" - fi - removepatch "$ROCR_REPO_DIR" + amd_compiler_symlinks=("amdclang" "amdclang++" "amdclang-cl" "amdclang-cpp" "amdflang" "amdlld") amd_compiler_cfg=("clang" "clang++" "clang-cpp" "clang-${AOMP_MAJOR_VERSION}" "clang-cl" "flang") @@ -353,9 +425,32 @@ if [ "$1" == "install" ] ; then #cp ${LLVM_INSTALL_LOC}/bin/rocm.cfg $config_file fi done -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From a59965ae2c35ec060fa7e4e32ee09b2d2a7fa71f Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 07:19:34 -0500 Subject: [PATCH 07/71] [AOMP] Taskify rocmlibs/build_rocBLAS.sh Refactor the legacy-idiom build_rocBLAS.sh into the taskified form: split into task_* functions over the single (default) config, move the Tensile commit checkout and repo patching out of top-level into task_patch (so introspection has no side effects), and modernize quoting. nocmake remains unsupported via a do_nocmake override that errors, and the AOMP_STANDALONE_BUILD-only restriction is enforced in task_precheck. Add AOMP_BUILD_TENSILE and ROCBLAS_USE_HIPBLASLT to the get_config_var_bool allow-list in aomp_utils. --- bin/aomp_utils | 2 +- bin/rocmlibs/build_rocBLAS.sh | 332 +++++++++++++++++++--------------- 2 files changed, 191 insertions(+), 143 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index f06abe6ed9..a3b53c39bb 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -308,7 +308,7 @@ get_config_var_bool() { case "$2" in AOMP_BUILD_CUDA|AOMP_APPLY_ATD_AMD_STAGING_PATCH|AOMP_USE_NINJA|\ AOMP_STANDALONE_BUILD|SANITIZER|AOMP_LEGACY_OPENMP|AOMP_BUILD_SANITIZER|\ - AOMP_BUILD_PERF|AOMP_BUILD_DEBUG) + AOMP_BUILD_PERF|AOMP_BUILD_DEBUG|AOMP_BUILD_TENSILE|ROCBLAS_USE_HIPBLASLT) ;; *) >&2 echo "Unknown bool configuration variable '$2'" diff --git a/bin/rocmlibs/build_rocBLAS.sh b/bin/rocmlibs/build_rocBLAS.sh index a50654bbf7..47d6b7e06e 100755 --- a/bin/rocmlibs/build_rocBLAS.sh +++ b/bin/rocmlibs/build_rocBLAS.sh @@ -8,47 +8,24 @@ # build_rocblas.sh: Script to build and install rocblas library # # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- _repo_dir=$AOMP_REPOS/rocmlibs/rocBLAS +_tensile_repo_dir=$AOMP_REPOS/rocmlibs/Tensile -# Check if Tensile is to be built with rocBLAS AOMP_BUILD_TENSILE=${AOMP_BUILD_TENSILE:-1} -if [ $AOMP_BUILD_TENSILE == 0 ] ; then - echo - echo "WARNING: Building rocblas without Tensile" - _local_tensile_opt="--no_tensile" -else - _cwd=$PWD - _tensile_repo_dir=$AOMP_REPOS/rocmlibs/Tensile - cd $_tensile_repo_dir - # Read the commit SHA from the file rocBLAS/tensile_tag.txt - _tensile_commit_sha=$(cat $_repo_dir/tensile_tag.txt) - # Checkout the specific commit SHA - git checkout $_tensile_commit_sha - echo "Checking out Tensile commit $_tensile_commit_sha" - cd $_cwd - _local_tensile_opt="--test_local_path=$_tensile_repo_dir" - patchrepo $_tensile_repo_dir -fi - -# Check if rocBLAS is to be built with hipBLASLT -# It won't work unless hipBLASLT is already installed ROCBLAS_USE_HIPBLASLT=${ROCBLAS_USE_HIPBLASLT:-0} -if [ $ROCBLAS_USE_HIPBLASLT == 0 ] ; then - echo - echo "WARNING: Building rocblas without hipBLASLT" - _local_hipblaslt_opt="--no_hipblaslt" -fi - -patchrepo $_repo_dir export CC=$LLVM_INSTALL_LOC/bin/amdclang export CXX=$LLVM_INSTALL_LOC/bin/amdclang++ @@ -61,131 +38,202 @@ export USE_PERL_SCRIPTS=1 export CXXFLAGS="-I$AOMP_INSTALL_DIR/include -D__HIP_PLATFORM_AMD__=1" export LDFLAGS="-fPIC" -## this causes fail when building with Tensile -#export TENSILE_SKIP_LIBRARY=1 -if [ "$AOMP_USE_CCACHE" != 0 ] ; then - _ccache_bin=`which ccache` - # export CMAKE_CXX_COMPILER_LAUNCHER=$_ccache_bin -fi - -# Set _build_type_option to Release or Debug based on BUILD_TYPE -if [ "$BUILD_TYPE" == "Debug" ] ; then - _build_type_option="--debug" -fi - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi +cfgvar() { + get_config_var_string rocblas "$1" +} + +cfgbool() { + get_config_var_bool rocblas "$1" +} + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/rocBLAS" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} -if [ "$1" == "nocmake" ] ; then +# rocBLAS does not support an incremental (nocmake) rebuild. +do_nocmake() { echo "ERROR: nocmake is not an option for $0 because we use rmake.py" exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/rocBLAS" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $BUILD_DIR/build/rocmlibs/rocBLAS - rm -rf $BUILD_DIR/build/rocmlibs/rocBLAS - mkdir -p $BUILD_DIR/build/rocmlibs/rocBLAS - if [ $AOMP_BUILD_TENSILE != 0 ] ; then - # Cleanup possible old tensile build area - echo rm -rf $_tensile_repo_dir/build - rm -rf $_tensile_repo_dir/build - fi -else - if [ ! -d $BUILD_DIR/build/rocmlibs/rocBLAS ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/rocBLAS" - echo " run $0 without install option. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi - -if [ "$1" != "install" ] ; then - # Remember start directory to return on exit - _curdir=$PWD - MYCMAKEOPTS=" - -DCMAKE_TOOLCHAIN_FILE=toolchain-linux.cmake - -DCMAKE_CXX_COMPILER=$CXX - -DCMAKE_C_COMPILER=$CC - -DROCM_DIR:PATH=$AOMP_INSTALL_DIR - -DCPACK_PACKAGING_INSTALL_PREFIX=$AOMP_INSTALL_DIR - -DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR - -DROCM_PATH=$AOMP_INSTALL_DIR - -DCMAKE_PREFIX_PATH:PATH=$AOMP_INSTALL_DIR - -DCPACK_SET_DESTDIR=OFF - -DCMAKE_BUILD_TYPE=Release - -DTensile_CODE_OBJECT_VERSION=default - -DTensile_LOGIC=asm_full - -DTensile_TEST_LOCAL_PATH=$AOMP_REPOS/rocmlibs/Tensile - -DTensile_SEPARATE_ARCHITECTURES=ON - -DTensile_LAZY_LIBRARY_LOADING=ON - -DTensile_LIBRARY_FORMAT=msgpack - -DBUILD_WITH_HIPBLASLT=OFF - -DROCTX_PATH=$AOMP_INSTALL_DIR - -DGPU_TARGETS="""$ROCMLIBS_GFXLIST""" - " - echo "Beginning cmake for rocblas..." - cd $BUILD_DIR/build/rocmlibs/rocBLAS - echo $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - if [ $? != 0 ] ; then - echo "ERROR cmake failed. Cmake flags" - echo " $MYCMAKEOPTS" - exit 1 + + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + local _tensile_commit_sha + if "$(cfgbool AOMP_BUILD_TENSILE)"; then + cd "$_tensile_repo_dir" || exit + # Read the commit SHA from the file rocBLAS/tensile_tag.txt + _tensile_commit_sha=$(cat "$_repo_dir/tensile_tag.txt") + echo "Checking out Tensile commit $_tensile_commit_sha" + git checkout "$_tensile_commit_sha" + patchrepo "$_tensile_repo_dir" fi + patchrepo "$_repo_dir" +} - make -j$AOMP_JOB_THREADS +task_unpatch() { + removepatch "$_repo_dir" + if "$(cfgbool AOMP_BUILD_TENSILE)"; then + removepatch "$_tensile_repo_dir" + fi +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + if "$(cfgbool AOMP_BUILD_TENSILE)"; then + # Cleanup possible old tensile build area + echo "rm -rf $_tensile_repo_dir/build" + rm -rf "$_tensile_repo_dir/build" + fi +} - if [ $? != 0 ] ; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" - exit 1 +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + + if ! "$(cfgbool AOMP_BUILD_TENSILE)"; then + echo + echo "WARNING: Building rocblas without Tensile" fi -fi + if ! "$(cfgbool ROCBLAS_USE_HIPBLASLT)"; then + echo + echo "WARNING: Building rocblas without hipBLASLT" + fi + + MYCMAKEOPTS=(-DCMAKE_TOOLCHAIN_FILE=toolchain-linux.cmake + -DCMAKE_CXX_COMPILER="$CXX" + -DCMAKE_C_COMPILER="$CC" + -DROCM_DIR:PATH="$AOMP_INSTALL_DIR" + -DCPACK_PACKAGING_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DCMAKE_PREFIX_PATH:PATH="$AOMP_INSTALL_DIR" + -DCPACK_SET_DESTDIR=OFF + -DCMAKE_BUILD_TYPE=Release + -DTensile_CODE_OBJECT_VERSION=default + -DTensile_LOGIC=asm_full + -DTensile_TEST_LOCAL_PATH="$AOMP_REPOS/rocmlibs/Tensile" + -DTensile_SEPARATE_ARCHITECTURES=ON + -DTensile_LAZY_LIBRARY_LOADING=ON + -DTensile_LIBRARY_FORMAT=msgpack + -DBUILD_WITH_HIPBLASLT=OFF + -DROCTX_PATH="$AOMP_INSTALL_DIR" + -DGPU_TARGETS="$ROCMLIBS_GFXLIST") -if [ "$1" == "install" ] ; then - echo " -----Installing to $AOMP_INSTALL_DIR ---- " + echo "Beginning cmake for rocblas..." + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" - if [ "$BUILD_TYPE" == "Release" ] ; then - _build_type_dir=release - else - _build_type_dir=debug + if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocblas ---- " + if ! make -j"$Jobs"; then + echo "ERROR make -j $Jobs failed" + exit 1 fi - cd $BUILD_DIR/build/rocmlibs/rocBLAS - make -j$AOMP_JOB_THREADS install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make -j"$Jobs" install; then + echo "ERROR install to $InstallDir failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir - removepatch $_tensile_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From e5ea595ba5ec0c2b7f6e7c3a49e680ceb9e9d95b Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 07:37:19 -0500 Subject: [PATCH 08/71] [AOMP] Extend cfgvar/cfgbool allow-lists with user-controllable build vars Add the user-overridable environment variables (paths, repo names, GPU target lists, compilers, version/build-type knobs, and the flang/limit-flang booleans) to the get_config_var_string and get_config_var_bool allow-lists. This lets the build scripts route all user-supplied values through the cfgvar/cfgbool chokepoint so they can later be driven deterministically by an orchestration layer, independent of the process environment. Variables derived internally by aomp_common_vars are intentionally not added. --- bin/aomp_utils | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index a3b53c39bb..ace5a1482e 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -292,7 +292,11 @@ get_config_var_string() { ;; LLVM_INSTALL_LOC|AOMP_PROC|CUDABIN|CUDAT|CUDAINCLUDE|REPO_DIR|\ AOMP_NINJA_BIN|AOMP_JOB_THREADS|LLVM_PROJECT_ROOT|INSTALL_COMGR|\ - INSTALL_ROCM|INSTALL_PROJECT) + INSTALL_ROCM|INSTALL_PROJECT|\ + AOMP|AOMP_REPOS|AOMP_SUPP|AOMP_CMAKE|AOMP_PROJECT_REPO_NAME|\ + AOMP_ROCR_REPO_NAME|AOMP_COMGR_REPO_NAME|AOMP_PROJECTS_LIST|GFXLIST|\ + ROCMLIBS_GFXLIST|BUILD_TYPE|AOMP_VERSION_STRING|AOMP_CC_COMPILER|\ + AOMP_CXX_COMPILER|AOMP_FLANG_THREADS) ;; *) >&2 echo "Unknown string configuration variable '$2'" @@ -308,7 +312,8 @@ get_config_var_bool() { case "$2" in AOMP_BUILD_CUDA|AOMP_APPLY_ATD_AMD_STAGING_PATCH|AOMP_USE_NINJA|\ AOMP_STANDALONE_BUILD|SANITIZER|AOMP_LEGACY_OPENMP|AOMP_BUILD_SANITIZER|\ - AOMP_BUILD_PERF|AOMP_BUILD_DEBUG|AOMP_BUILD_TENSILE|ROCBLAS_USE_HIPBLASLT) + AOMP_BUILD_PERF|AOMP_BUILD_DEBUG|AOMP_BUILD_TENSILE|ROCBLAS_USE_HIPBLASLT|\ + AOMP_SKIP_AMD_FLANGRT|AOMP_LIMIT_FLANG) ;; *) >&2 echo "Unknown bool configuration variable '$2'" From cb743e144595d6360f8163c63a3412e1d6b6e35d Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 07:40:02 -0500 Subject: [PATCH 09/71] [AOMP] build_comgr.sh: route user env vars through cfgvar/cfgbool Read all user-supplied values (AOMP_REPOS/AOMP_PROJECT_REPO_NAME/ AOMP_COMGR_REPO_NAME for the repo path, AOMP, AOMP_CMAKE) through the cfgvar chokepoint instead of referencing the globals directly. aomp_common_vars-derived values (AOMP_INSTALL_DIR, LLVM_INSTALL_LOC, ASAN_FLAGS, RPATH arrays) remain direct references. The common/variant cmake-option split was already in place. --- bin/build_comgr.sh | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/bin/build_comgr.sh b/bin/build_comgr.sh index 873b210715..b0a1704a3c 100755 --- a/bin/build_comgr.sh +++ b/bin/build_comgr.sh @@ -15,11 +15,8 @@ thisdir=$(dirname "$realpath") . "$thisdir/aomp_common_vars" # --- end standard header ---- -INSTALL_COMGR=${INSTALL_COMGR:-$AOMP_INSTALL_DIR} - -REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_COMGR_REPO_NAME - -# Get a configuration (environment) variable for this config +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. cfgvar() { get_config_var_string comgr "$1" } @@ -28,6 +25,9 @@ cfgbool() { get_config_var_bool comgr "$1" } +INSTALL_COMGR=${INSTALL_COMGR:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROJECT_REPO_NAME)/amd/$(cfgvar AOMP_COMGR_REPO_NAME)" + if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the code object manager" @@ -123,6 +123,9 @@ task_cmake() { local Cfg=$1 local BuildDir local SrcDir + local Aomp + local AompCmake + local Repos local DEVICELIBS_BUILD_PATH local PACKAGE_ROOT local COMMON_PREFIX_PATH @@ -130,14 +133,18 @@ task_cmake() { SrcDir="$(get_src_dir)" BuildDir="$(get_build_dir "$Cfg")" + Aomp="$(cfgvar AOMP)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Repos="$(cfgvar AOMP_REPOS)" export LLVM_DIR=$AOMP_INSTALL_DIR export Clang_DIR=$AOMP_INSTALL_DIR - DEVICELIBS_BUILD_PATH=$AOMP_REPOS/build/AOMP_LIBDEVICE_REPO_NAME + DEVICELIBS_BUILD_PATH=$Repos/build/AOMP_LIBDEVICE_REPO_NAME PACKAGE_ROOT=$SrcDir - COMMON_PREFIX_PATH="$AOMP/include/amd_comgr;$DEVICELIBS_BUILD_PATH;$PACKAGE_ROOT;$LLVM_INSTALL_LOC" + COMMON_PREFIX_PATH="$Aomp/include/amd_comgr;$DEVICELIBS_BUILD_PATH;$PACKAGE_ROOT;$LLVM_INSTALL_LOC" + # Settings common to every config. MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_COMGR)" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF @@ -145,16 +152,17 @@ task_cmake() { -DLLVM_DIR="$AOMP_INSTALL_DIR" -DClang_DIR="$AOMP_INSTALL_DIR") + # Variant-specific settings. if asan_config "$Cfg"; then MYCMAKEOPTS+=(-DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - -DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake;$COMMON_PREFIX_PATH;$AOMP/lib/cmake" + -DCMAKE_PREFIX_PATH="$Aomp/lib/asan/cmake;$COMMON_PREFIX_PATH;$Aomp/lib/cmake" -DCMAKE_INSTALL_LIBDIR=lib/asan "${AOMP_ASAN_ORIGIN_RPATH[@]}" -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") else - MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP/lib/cmake;$COMMON_PREFIX_PATH" + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$Aomp/lib/cmake;$COMMON_PREFIX_PATH" -DCMAKE_INSTALL_LIBDIR=lib "${AOMP_ORIGIN_RPATH[@]}") fi @@ -162,9 +170,9 @@ task_cmake() { mkdir -p "$BuildDir" pushd "$BuildDir" >& /dev/null || exit echo " -----Running comgr $Cfg cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" + echo "$AompCmake" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$SrcDir"; then + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then echo "ERROR comgr $Cfg cmake failed. cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 From 2f617c1adb0f6049e5e84a66c1ab45b869e33540 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 07:43:28 -0500 Subject: [PATCH 10/71] [AOMP] build_rocr.sh: factor cmake opts and route user env vars Split the per-config cmake options into a common base array plus variant-specific (default/asan/debug) appends, removing the prior duplication. Read user-supplied values (AOMP_REPOS/AOMP_ROCR_REPO_NAME, AOMP_CMAKE, BUILD_TYPE) through cfgvar; aomp_common_vars-derived values (AOMP_INSTALL_DIR, LLVM_INSTALL_LOC, ASAN_FLAGS, RPATH arrays) stay direct. --- bin/build_rocr.sh | 75 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/bin/build_rocr.sh b/bin/build_rocr.sh index b016ef7420..62eee9fb00 100755 --- a/bin/build_rocr.sh +++ b/bin/build_rocr.sh @@ -17,10 +17,8 @@ thisdir=$(dirname "$realpath") . "$thisdir/aomp_common_vars" # --- end standard header ---- -INSTALL_ROCM=${INSTALL_ROCM:-$AOMP_INSTALL_DIR} -REPO_DIR=$AOMP_REPOS/$AOMP_ROCR_REPO_NAME -_ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" - +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. cfgvar() { get_config_var_string rocr "$1" } @@ -29,6 +27,10 @@ cfgbool() { get_config_var_bool rocr "$1" } +INSTALL_ROCM=${INSTALL_ROCM:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_ROCR_REPO_NAME)" +_ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" + if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the ROCM runtime libraries" @@ -135,58 +137,53 @@ task_cmake() { local Cfg=$1 local BuildDir local SrcDir + local AompCmake local -a MYCMAKEOPTS local -a _prefix_map SrcDir="$(get_src_dir)" BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" export PATH=/opt/rocm/llvm/bin:$PATH + # Settings common to every config. + MYCMAKEOPTS=(-DCMAKE_C_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang" + -DCMAKE_CXX_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" + -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" + -DIMAGE_SUPPORT=OFF + -DBUILD_SHARED_LIBS=On) + + # Variant-specific settings. if asan_config "$Cfg"; then - MYCMAKEOPTS=(-DCMAKE_C_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang" - -DCMAKE_CXX_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" - -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" - -DCMAKE_INSTALL_LIBDIR=lib/asan - -DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" - -DIMAGE_SUPPORT=OFF "${AOMP_ASAN_ORIGIN_RPATH[@]}" - -DBUILD_SHARED_LIBS=On - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + MYCMAKEOPTS+=(-DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_LIBDIR=lib/asan + -DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + "${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") elif debug_config "$Cfg"; then _prefix_map=(-fdebug-prefix-map="$SrcDir=$_ompd_src_dir/rocr") - MYCMAKEOPTS=(-DCMAKE_C_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang" - -DCMAKE_CXX_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" - -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" - -DCMAKE_BUILD_TYPE=Debug - "${AOMP_DEBUG_ORIGIN_RPATH[@]}" - -DCMAKE_INSTALL_LIBDIR=lib-debug - -DBUILD_SHARED_LIBS=On - -DIMAGE_SUPPORT=OFF - -DTARGET_DEVICES="gfx900;gfx90a;gfx942;gfx1010;gfx1030;gfx1100;gfx1200" - -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")" - -DCMAKE_CXX_FLAGS="$(cmquot -g "${_prefix_map[@]}")") + MYCMAKEOPTS+=(-DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_BUILD_TYPE=Debug + "${AOMP_DEBUG_ORIGIN_RPATH[@]}" + -DCMAKE_INSTALL_LIBDIR=lib-debug + -DTARGET_DEVICES="gfx900;gfx90a;gfx942;gfx1010;gfx1030;gfx1100;gfx1200" + -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot -g "${_prefix_map[@]}")") else - MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_ROCM)" - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib" - -DIMAGE_SUPPORT=OFF "${AOMP_ORIGIN_RPATH[@]}" - -DCMAKE_INSTALL_LIBDIR=lib - -DCMAKE_C_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang" - -DCMAKE_CXX_COMPILER="$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" - -DLLVM_DIR="$AOMP_INSTALL_DIR/lib/llvm/bin" - -DBUILD_SHARED_LIBS=On) + MYCMAKEOPTS+=(-DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_ROCM)" + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_LIBDIR=lib + "${AOMP_ORIGIN_RPATH[@]}") fi mkdir -p "$BuildDir" pushd "$BuildDir" >& /dev/null || exit echo " -----Running rocr $Cfg cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" + echo "$AompCmake" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$SrcDir"; then + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then echo "ERROR rocr $Cfg cmake failed. cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 From 9d539637545be445beee759b4ddd0b09ee622033 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 07:49:56 -0500 Subject: [PATCH 11/71] [AOMP] build_project.sh: route user env vars through cfgvar/cfgbool Read all user-supplied values through the cfgvar/cfgbool chokepoint: repo paths (AOMP_REPOS/AOMP_PROJECT_REPO_NAME/AOMP_ROCR_REPO_NAME via REPO_DIR/ROCR_REPO_DIR), AOMP, AOMP_CMAKE, AOMP_SUPP, BUILD_TYPE, AOMP_PROJECTS_LIST, GFXLIST, AOMP_VERSION_STRING, AOMP_CC/CXX_COMPILER, and the AOMP_USE_NINJA/AOMP_LEGACY_OPENMP/AOMP_SKIP_AMD_FLANGRT/ AOMP_BUILD_SANITIZER/AOMP_LIMIT_FLANG booleans. aomp_common_vars-derived values (AOMP_INSTALL_DIR, LLVM_INSTALL_LOC, AOMP_PROC, AOMP_NVPTX_TARGET, RPATH lists, CCACHE opts) remain direct references. The sanitizer cmake block was already separated from the common options. --- bin/build_project.sh | 154 ++++++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 60 deletions(-) diff --git a/bin/build_project.sh b/bin/build_project.sh index 76b76575c6..c1a14076ff 100755 --- a/bin/build_project.sh +++ b/bin/build_project.sh @@ -21,12 +21,8 @@ thisdir=$(dirname "$realpath") . "$thisdir/aomp_common_vars" # --- end standard header ---- -BUILD_TYPE=${BUILD_TYPE:-Release} -INSTALL_PROJECT=${INSTALL_PROJECT:-$LLVM_INSTALL_LOC} -WEBSITE="http\:\/\/github.com\/ROCm\/aomp" -ROCR_REPO_DIR=$AOMP_REPOS/$AOMP_ROCR_REPO_NAME -REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME - +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. cfgvar() { get_config_var_string project "$1" } @@ -35,12 +31,18 @@ cfgbool() { get_config_var_bool project "$1" } +BUILD_TYPE=${BUILD_TYPE:-Release} +INSTALL_PROJECT=${INSTALL_PROJECT:-$LLVM_INSTALL_LOC} +WEBSITE="http\:\/\/github.com\/ROCm\/aomp" +ROCR_REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_ROCR_REPO_NAME)" +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROJECT_REPO_NAME)" + if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi get_src_dir() { - echo "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm" + echo "$REPO_DIR/llvm" } # Print the build dir for a given config, passed as $1. @@ -48,7 +50,7 @@ get_build_dir() { local Cfg=$1 case "$Cfg" in "default") - echo -n "$(cfgvar BUILD_DIR)/$AOMP_PROJECT_REPO_NAME" + echo -n "$(cfgvar BUILD_DIR)/$(cfgvar AOMP_PROJECT_REPO_NAME)" ;; *) >&2 echo "Unknown config '$Cfg'" @@ -66,15 +68,16 @@ get_install_dir() { # string. This edits the (git-tracked) source file in place; task_install # reverts it with "git checkout". fixup_source_banner() { - local MONO_REPO_ID SOURCEID TEMPCLFILE ORIGCLFILE BUILDCLFILE - cd "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME" || exit + local MONO_REPO_ID SOURCEID TEMPCLFILE ORIGCLFILE BUILDCLFILE VersionString + VersionString="$(cfgvar AOMP_VERSION_STRING)" + cd "$REPO_DIR" || exit MONO_REPO_ID=$(git log | grep -m1 commit | cut -d" " -f2) - SOURCEID="Source ID:$AOMP_VERSION_STRING-$MONO_REPO_ID" + SOURCEID="Source ID:$VersionString-$MONO_REPO_ID" TEMPCLFILE="/tmp/clfile$$.cpp" - ORIGCLFILE="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/lib/Support/CommandLine.cpp" + ORIGCLFILE="$REPO_DIR/llvm/lib/Support/CommandLine.cpp" BUILDCLFILE=$ORIGCLFILE - if ! sed "s/LLVM (http:\/\/llvm\.org\/):/AOMP-${AOMP_VERSION_STRING} ($WEBSITE):\\\n $SOURCEID/" "$ORIGCLFILE" > "$TEMPCLFILE"; then + if ! sed "s/LLVM (http:\/\/llvm\.org\/):/AOMP-${VersionString} ($WEBSITE):\\\n $SOURCEID/" "$ORIGCLFILE" > "$TEMPCLFILE"; then echo "ERROR sed command to fix CommandLine.cpp failed." exit 1 fi @@ -96,8 +99,10 @@ fixup_source_banner() { task_precheck() { if "$(cfgbool AOMP_STANDALONE_BUILD)"; then - if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then - echo "ERROR: Directory $AOMP is a physical directory." + local Aomp + Aomp="$(cfgvar AOMP)" + if [ ! -L "$Aomp" ] && [ -d "$Aomp" ] ; then + echo "ERROR: Directory $Aomp is a physical directory." echo " It must be a symbolic link or not exist" exit 1 fi @@ -138,6 +143,15 @@ task_cmake() { local Cfg=$1 local BuildDir local SrcDir + local Repos + local AompCmake + local AompSupp + local BuildType + local ProjectsList + local VersionString + local CcComp + local CxxComp + local Gfxlist local standalone_word local TARGETS_TO_BUILD local LLVM_RUNTIMES @@ -151,14 +165,22 @@ task_cmake() { local -a MYCMAKEOPTS local -a MYLITOPTS - echo "LLVM PROJECTS TO BUILD:$AOMP_PROJECTS_LIST" - BuildDir="$(get_build_dir "$Cfg")" SrcDir="$(get_src_dir)" + Repos="$(cfgvar AOMP_REPOS)" + AompCmake="$(cfgvar AOMP_CMAKE)" + AompSupp="$(cfgvar AOMP_SUPP)" + BuildType="$(cfgvar BUILD_TYPE)" + ProjectsList="$(cfgvar AOMP_PROJECTS_LIST)" + VersionString="$(cfgvar AOMP_VERSION_STRING)" + CcComp="$(cfgvar AOMP_CC_COMPILER)" + CxxComp="$(cfgvar AOMP_CXX_COMPILER)" + + echo "LLVM PROJECTS TO BUILD:$ProjectsList" # Enable AMD-specific Fortran runtime extensions if not skipped _amdflangrtopt=(-DFLANG_RT_INCLUDE_AMD=ON) - if [ "$AOMP_SKIP_AMD_FLANGRT" == "1" ]; then + if "$(cfgbool AOMP_SKIP_AMD_FLANGRT)"; then _amdflangrtopt=() fi @@ -170,8 +192,8 @@ task_cmake() { -DCMAKE_CXX_COMPILER=/usr/bin/g++-7) TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}PowerPC" else - COMPILERS=(-DCMAKE_C_COMPILER="$AOMP_CC_COMPILER" - -DCMAKE_CXX_COMPILER="$AOMP_CXX_COMPILER") + COMPILERS=(-DCMAKE_C_COMPILER="$CcComp" + -DCMAKE_CXX_COMPILER="$CxxComp") if [ "$AOMP_PROC" == "aarch64" ] ; then TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64;SPIRV" _qmathopt=() @@ -200,13 +222,13 @@ task_cmake() { standalone_word="" fi - if [ "$AOMP_USE_NINJA" == 0 ] ; then + if ! "$(cfgbool AOMP_USE_NINJA)" ; then AOMP_SET_NINJA_GEN=() else AOMP_SET_NINJA_GEN=(-G Ninja) fi - if [ "$AOMP_LEGACY_OPENMP" != 0 ]; then + if "$(cfgbool AOMP_LEGACY_OPENMP)"; then LLVM_RUNTIMES="libcxx;libcxxabi;libunwind;compiler-rt" else LLVM_RUNTIMES="libcxx;libcxxabi;libunwind;openmp;offload;compiler-rt;flang-rt" @@ -214,22 +236,24 @@ task_cmake() { rocmdevicelib_loc_new=lib/llvm/lib/clang/$AOMP_MAJOR_VERSION/lib/amdgcn - GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') + Gfxlist="$(cfgvar GFXLIST)" + GFXSEMICOLONS=$(echo "$Gfxlist" | tr ' ' ';') - MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_INSTALL_PREFIX="$INSTALL_PROJECT" + # Settings common to every config. + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BuildType" + -DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_PROJECT)" -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" "${COMPILERS[@]}" - -DLLVM_VERSION_SUFFIX="_AOMP${standalone_word}_$AOMP_VERSION_STRING" - -DCLANG_VENDOR="AOMP${standalone_word}_$AOMP_VERSION_STRING" + -DLLVM_VERSION_SUFFIX="_AOMP${standalone_word}_$VersionString" + -DCLANG_VENDOR="AOMP${standalone_word}_$VersionString" "${LLVM_FORCE_VC_REVISION_OPT:-}" "${LLVM_FORCE_VC_REPOSITORY_OPT:-}" -DCLANG_DEFAULT_PIE_ON_LINUX=0 -DLLVM_ENABLE_ZLIB=ON -DBUG_REPORT_URL='https://github.com/ROCm/aomp' -DLLVM_ENABLE_BINDINGS=OFF - -DCMAKE_PREFIX_PATH="$BUILD_DIR/build/$AOMP_PROJECT_REPO_NAME/lib/cmake" + -DCMAKE_PREFIX_PATH="$BuildDir/lib/cmake" -DLLVM_INCLUDE_BENCHMARKS=OFF "${DO_TESTS_OPTS[@]}" "${AOMP_ORIGIN_RPATH[@]}" @@ -241,11 +265,11 @@ task_cmake() { -DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_LINK_LLVM_DYLIB=ON -DCLANG_LINK_CLANG_DYLIB=ON - -DLIBOMPTARGET_EXTERNAL_PROJECT_HSA_PATH="$AOMP_REPOS/$AOMP_ROCR_REPO_NAME" + -DLIBOMPTARGET_EXTERNAL_PROJECT_HSA_PATH="$ROCR_REPO_DIR" -DOFFLOAD_EXTERNAL_PROJECT_UNIFIED_ROCR=On - -DLIBOMPTARGET_EXTERNAL_PROJECT_ROCM_DEVICE_LIBS_PATH="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/device-libs" + -DLIBOMPTARGET_EXTERNAL_PROJECT_ROCM_DEVICE_LIBS_PATH="$REPO_DIR/amd/device-libs" -DLLVM_EXTERNAL_PROJECTS=SPIRV_TRANSLATOR - -DLLVM_EXTERNAL_SPIRV_TRANSLATOR_SOURCE_DIR="$AOMP_REPOS/SPIRV-LLVM-Translator" + -DLLVM_EXTERNAL_SPIRV_TRANSLATOR_SOURCE_DIR="$Repos/SPIRV-LLVM-Translator" -DROCM_DEVICE_LIBS_INSTALL_PREFIX_PATH="$AOMP_INSTALL_DIR" -DROCM_DEVICE_LIBS_BITCODE_INSTALL_LOC="$rocmdevicelib_loc_new" -DROCM_LLVM_BACKWARD_COMPAT_LINK="$AOMP_INSTALL_DIR/llvm" @@ -255,7 +279,7 @@ task_cmake() { -DLIBOMPTEST_INSTALL_COMPONENTS=ON -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" -DLIBOMP_USE_HWLOC=ON - -DLIBOMP_HWLOC_INSTALL_DIR="$AOMP_SUPP/hwloc" + -DLIBOMP_HWLOC_INSTALL_DIR="$AompSupp/hwloc" -DOPENMP_ENABLE_LIBOMPTARGET=1 -DLIBOMP_SHARED_LINKER_FLAGS="-Wl,--disable-new-dtags" -DLIBOMP_INSTALL_RPATH="$AOMP_ORIGIN_RPATH_LIST" @@ -264,7 +288,7 @@ task_cmake() { -DLIBOMPTARGET_BUILD_DEVICE_FORTRT=On -DCMAKE_EXPORT_COMPILE_COMMANDS=ON) - if [ -f "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/device/CMakeLists.txt" ]; then + if [ -f "$REPO_DIR/openmp/device/CMakeLists.txt" ]; then MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" -DLLVM_RUNTIME_TARGETS='default;amdgcn-amd-amdhsa' -DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES='compiler-rt;libc;libcxx;libcxxabi;flang-rt;openmp' @@ -277,7 +301,7 @@ task_cmake() { # clang-tools-extra added to LLVM_ENABLE_PROJECTS above. MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" "${AOMP_CCACHE_OPTS[@]}" - -DLLVM_ENABLE_PROJECTS="$AOMP_PROJECTS_LIST" + -DLLVM_ENABLE_PROJECTS="$ProjectsList" -DCLANG_ENABLE_AMDCLANG=ON -DLLVM_ENABLE_RUNTIMES="$LLVM_RUNTIMES" -DLIBCXX_ENABLE_STATIC=ON @@ -285,14 +309,14 @@ task_cmake() { -DLLVM_RUNTIME_TARGETS="default;amdgcn-amd-amdhsa" -DRUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBC_PROVIDER=llvm -DRUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBCXX_PROVIDER=llvm - -DRUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/compiler-rt/cmake/caches/AMDGPU.cmake;$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/libcxx/cmake/caches/AMDGPU.cmake" + -DRUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES="$REPO_DIR/compiler-rt/cmake/caches/AMDGPU.cmake;$REPO_DIR/libcxx/cmake/caches/AMDGPU.cmake" ) - # Enable Compiler-rt Sanitizer Build - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then + # Variant-specific settings: enable Compiler-rt Sanitizer Build. + if "$(cfgbool AOMP_BUILD_SANITIZER)"; then MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" -DSANITIZER_AMDGPU=1 - -DSANITIZER_HSA_INCLUDE_PATH="$AOMP_REPOS/$AOMP_ROCR_REPO_NAME/runtime/hsa-runtime/inc" - -DSANITIZER_COMGR_INCLUDE_PATH="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/comgr/include") + -DSANITIZER_HSA_INCLUDE_PATH="$ROCR_REPO_DIR/runtime/hsa-runtime/inc" + -DSANITIZER_COMGR_INCLUDE_PATH="$REPO_DIR/amd/comgr/include") fi # Fix the banner to print the AOMP version string. @@ -305,13 +329,13 @@ task_cmake() { echo echo " -----Running cmake ---- " MYLITOPTS=(-DLLVM_LIT_ARGS='-vv --show-unsupported --show-xfail -j 16') - echo "${AOMP_CMAKE}" "$(shquot "${MYLITOPTS[@]}")" \ - "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$SrcDir" + echo "$AompCmake" "$(shquot "${MYLITOPTS[@]}")" \ + "$(shquot "${MYCMAKEOPTS[@]}")" \ + "$SrcDir" - if ! ${AOMP_CMAKE} "${MYLITOPTS[@]}" \ - "${MYCMAKEOPTS[@]}" \ - "$SrcDir" 2>&1; then + if ! "$AompCmake" "${MYLITOPTS[@]}" \ + "${MYCMAKEOPTS[@]}" \ + "$SrcDir" 2>&1; then echo "ERROR cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 @@ -322,28 +346,32 @@ task_cmake() { task_build() { local Cfg=$1 local BuildDir + local AompCmake local Jobs + local FlangJobs BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" Jobs="$(cfgvar AOMP_JOB_THREADS)" pushd "$BuildDir" >& /dev/null || exit echo echo " -----Running make ---- " - if [ "$AOMP_LIMIT_FLANG" == "1" ] ; then + if "$(cfgbool AOMP_LIMIT_FLANG)"; then # Required for building flang on memory limited systems. - echo "${AOMP_CMAKE} --build . -- -j $Jobs clang lld compiler-rt" - ${AOMP_CMAKE} --build . -- -j "$Jobs" clang lld compiler-rt || true + FlangJobs="$(cfgvar AOMP_FLANG_THREADS)" + echo "$AompCmake --build . -- -j $Jobs clang lld compiler-rt" + "$AompCmake" --build . -- -j "$Jobs" clang lld compiler-rt || true - echo "${AOMP_CMAKE} --build . -- -j $AOMP_FLANG_THREADS flang" - ${AOMP_CMAKE} --build . -- -j "$AOMP_FLANG_THREADS" flang || true + echo "$AompCmake --build . -- -j $FlangJobs flang" + "$AompCmake" --build . -- -j "$FlangJobs" flang || true fi # Build llvm-project in one step echo "Running CMAKE in ${PWD}" - echo "${AOMP_CMAKE} --build . -j $Jobs" + echo "$AompCmake --build . -j $Jobs" - if ! ${AOMP_CMAKE} --build . -j "$Jobs"; then + if ! "$AompCmake" --build . -j "$Jobs"; then echo "ERROR make -j $Jobs failed" exit 1 fi @@ -354,6 +382,9 @@ task_install() { local Cfg=$1 local BuildDir local InstallDir + local AompCmake + local Aomp + local Repos local SED_AOMP_REPOS local i local config_file @@ -362,11 +393,14 @@ task_install() { BuildDir="$(get_build_dir "$Cfg")" InstallDir="$(get_install_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + Aomp="$(cfgvar AOMP)" + Repos="$(cfgvar AOMP_REPOS)" pushd "$BuildDir" >& /dev/null || exit echo " -----Installing to $InstallDir ---- " - if ! $SUDO "$AOMP_CMAKE" --install .; then + if ! $SUDO "$AompCmake" --install .; then echo "ERROR make install failed " exit 1 fi @@ -374,27 +408,27 @@ task_install() { if "$(cfgbool AOMP_STANDALONE_BUILD)"; then echo " " - echo "------ Linking $InstallDir to $AOMP -------" - if [ -L "$AOMP" ] ; then - $SUDO rm "$AOMP" + echo "------ Linking $InstallDir to $Aomp -------" + if [ -L "$Aomp" ] ; then + $SUDO rm "$Aomp" fi - $SUDO ln -sf "$AOMP_INSTALL_DIR" "$AOMP" + $SUDO ln -sf "$AOMP_INSTALL_DIR" "$Aomp" fi # add executables forgot by make install but needed for testing $SUDO cp -p "$BuildDir/bin/llvm-lit" "$LLVM_INSTALL_LOC/bin/llvm-lit" # update map_config and llvm_source_root paths in the copied llvm-lit file - SED_AOMP_REPOS=$(echo "$AOMP_REPOS" | sed -e 's/\//\\\\\//g') + SED_AOMP_REPOS=$(echo "$Repos" | sed -e 's/\//\\\\\//g') sed -ie "s/..\/..\/..\//$SED_AOMP_REPOS\//g" "$LLVM_INSTALL_LOC/bin/llvm-lit" $SUDO cp -p "$BuildDir/bin/FileCheck" "$LLVM_INSTALL_LOC/bin/FileCheck" $SUDO cp -p "$BuildDir/bin/count" "$LLVM_INSTALL_LOC/bin/count" $SUDO cp -p "$BuildDir/bin/not" "$LLVM_INSTALL_LOC/bin/not" $SUDO cp -p "$BuildDir/bin/yaml-bench" "$LLVM_INSTALL_LOC/bin/yaml-bench" - cd "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME" || exit + cd "$REPO_DIR" || exit git checkout llvm/lib/Support/CommandLine.cpp echo - echo "SUCCESSFUL INSTALL to $InstallDir with link to $AOMP" + echo "SUCCESSFUL INSTALL to $InstallDir with link to $Aomp" echo amd_compiler_symlinks=("amdclang" "amdclang++" "amdclang-cl" "amdclang-cpp" "amdflang" "amdlld") From 8948b894d3f2306834b958d024fa129980175e73 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 07:56:33 -0500 Subject: [PATCH 12/71] [AOMP] build_rocBLAS.sh: route user env vars through cfgvar/cfgbool Read user-supplied values through the cfgvar chokepoint: AOMP_REPOS (repo paths), AOMP_SUPP and AOMP (PATH export), ROCMLIBS_GFXLIST (GPU_TARGETS), and AOMP_CMAKE. aomp_common_vars-derived values (AOMP_INSTALL_DIR, LLVM_INSTALL_LOC and the CC/CXX/FC exports derived from it) stay direct. --- bin/rocmlibs/build_rocBLAS.sh | 44 +++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/bin/rocmlibs/build_rocBLAS.sh b/bin/rocmlibs/build_rocBLAS.sh index 47d6b7e06e..118959487d 100755 --- a/bin/rocmlibs/build_rocBLAS.sh +++ b/bin/rocmlibs/build_rocBLAS.sh @@ -21,31 +21,35 @@ thisdir=$(dirname "$realpath") . "$thisdir/../aomp_common_vars" # --- end standard header ---- -_repo_dir=$AOMP_REPOS/rocmlibs/rocBLAS -_tensile_repo_dir=$AOMP_REPOS/rocmlibs/Tensile +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocblas "$1" +} + +cfgbool() { + get_config_var_bool rocblas "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/rocBLAS" +_tensile_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/Tensile" AOMP_BUILD_TENSILE=${AOMP_BUILD_TENSILE:-1} ROCBLAS_USE_HIPBLASLT=${ROCBLAS_USE_HIPBLASLT:-0} +_aomp_supp="$(cfgvar AOMP_SUPP)" +_aomp="$(cfgvar AOMP)" export CC=$LLVM_INSTALL_LOC/bin/amdclang export CXX=$LLVM_INSTALL_LOC/bin/amdclang++ export FC=$LLVM_INSTALL_LOC/bin/amdflang export ROCM_DIR=$AOMP_INSTALL_DIR export ROCM_PATH=$AOMP_INSTALL_DIR -export PATH=$AOMP_SUPP/cmake/bin:$AOMP_INSTALL_DIR/bin:$AOMP/llvm/bin:$PATH +export PATH="$_aomp_supp/cmake/bin:$AOMP_INSTALL_DIR/bin:$_aomp/llvm/bin:$PATH" export HIP_USE_PERL_SCRIPTS=1 export USE_PERL_SCRIPTS=1 export CXXFLAGS="-I$AOMP_INSTALL_DIR/include -D__HIP_PLATFORM_AMD__=1" export LDFLAGS="-fPIC" -cfgvar() { - get_config_var_string rocblas "$1" -} - -cfgbool() { - get_config_var_bool rocblas "$1" -} - get_src_dir() { echo "$_repo_dir" } @@ -76,12 +80,14 @@ do_nocmake() { } task_precheck() { + local Aomp + Aomp="$(cfgvar AOMP)" if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then - echo "ERROR: Directory $AOMP is a physical directory." + if [ ! -L "$Aomp" ] && [ -d "$Aomp" ] ; then + echo "ERROR: Directory $Aomp is a physical directory." echo " It must be a symbolic link or not exist" exit 1 fi @@ -126,10 +132,14 @@ task_cmake() { local Cfg=$1 local BuildDir local SrcDir + local AompCmake + local Gfxlist local -a MYCMAKEOPTS BuildDir="$(get_build_dir "$Cfg")" SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" if ! "$(cfgbool AOMP_BUILD_TENSILE)"; then echo @@ -152,20 +162,20 @@ task_cmake() { -DCMAKE_BUILD_TYPE=Release -DTensile_CODE_OBJECT_VERSION=default -DTensile_LOGIC=asm_full - -DTensile_TEST_LOCAL_PATH="$AOMP_REPOS/rocmlibs/Tensile" + -DTensile_TEST_LOCAL_PATH="$_tensile_repo_dir" -DTensile_SEPARATE_ARCHITECTURES=ON -DTensile_LAZY_LIBRARY_LOADING=ON -DTensile_LIBRARY_FORMAT=msgpack -DBUILD_WITH_HIPBLASLT=OFF -DROCTX_PATH="$AOMP_INSTALL_DIR" - -DGPU_TARGETS="$ROCMLIBS_GFXLIST") + -DGPU_TARGETS="$Gfxlist") echo "Beginning cmake for rocblas..." mkdir -p "$BuildDir" pushd "$BuildDir" >& /dev/null || exit - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" + echo "$AompCmake" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$SrcDir"; then + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then echo "ERROR cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 From c98c7a15e916838e0346ce15479bc229fe6e86df Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:02:26 -0500 Subject: [PATCH 13/71] Taskify build_roct.sh Convert build_roct.sh to the taskified build pattern used by build_offload.sh and the other Phase 1 scripts: per-config task_* functions (default/asan/debug) driven by command_dispatcher, with common vs. variant-specific cmake options factored apart and the debug source-copy step moved to task_postinstall. User-controllable environment variables (AOMP_ROCT_REPO_NAME, INSTALL_ROCT, AOMP_CLANG_COMPILER, AOMP_CLANGXX_COMPILER) are read through the cfgvar/cfgbool wrappers; add them to the aomp_utils allowlists. --- bin/aomp_utils | 3 +- bin/build_roct.sh | 405 +++++++++++++++++++++++++++------------------- 2 files changed, 243 insertions(+), 165 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index ace5a1482e..bcf6f5e19f 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -296,7 +296,8 @@ get_config_var_string() { AOMP|AOMP_REPOS|AOMP_SUPP|AOMP_CMAKE|AOMP_PROJECT_REPO_NAME|\ AOMP_ROCR_REPO_NAME|AOMP_COMGR_REPO_NAME|AOMP_PROJECTS_LIST|GFXLIST|\ ROCMLIBS_GFXLIST|BUILD_TYPE|AOMP_VERSION_STRING|AOMP_CC_COMPILER|\ - AOMP_CXX_COMPILER|AOMP_FLANG_THREADS) + AOMP_CXX_COMPILER|AOMP_FLANG_THREADS|AOMP_CLANG_COMPILER|\ + AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_roct.sh b/bin/build_roct.sh index aa8379b991..7f537db7b8 100755 --- a/bin/build_roct.sh +++ b/bin/build_roct.sh @@ -3,20 +3,37 @@ # build_roct.sh: Script to build the ROCt thunk libraries. # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string roct "$1" +} + +cfgbool() { + get_config_var_bool roct "$1" +} + INSTALL_ROCT=${INSTALL_ROCT:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_ROCT_REPO_NAME)" +_ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the ROCt thunk libraries" - echo " It gets the source from: $AOMP_REPOS/$AOMP_ROCT_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/roct" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/roct" echo " It installs in: $INSTALL_ROCT" echo " " echo "Example commands and actions: " @@ -26,186 +43,246 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit + exit 0 fi -if [ ! -d "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_ROCT_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_ROCT_REPO_NAME set correctly?" - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR" +} -check_writable_installdir "$1" "$INSTALL_ROCT" +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" -patchrepo "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME" + case "$Cfg" in + "default") + echo -n "$BuildDir/roct" + ;; + "asan") + echo -n "$BuildDir/roct/asan" + ;; + "debug") + echo -n "$BuildDir/roct_debug" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} -#if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - #LDFLAGS=$(shquot '-fuse-ld=lld' "${ASAN_FLAGS[@]}") - #export LDFLAGS -#fi +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_ROCT +} -_ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" +asan_config() { + local Cfg=$1 + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/build_roct" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - - BUILDTYPE="Release" - echo "$SUDO rm -rf $BUILD_AOMP/build/roct" - $SUDO rm -rf "$BUILD_AOMP/build/roct" - declare -a MYCMAKEOPTS - MYCMAKEOPTS=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" - -DCMAKE_INSTALL_PREFIX="$INSTALL_ROCT" - -DCMAKE_BUILD_TYPE="$BUILDTYPE" - "${AOMP_ORIGIN_RPATH[@]}" - -DCMAKE_INSTALL_LIBDIR=lib) - mkdir -p "$BUILD_AOMP/build/roct" - cd "$BUILD_AOMP/build/roct" || exit - echo " -----Running roct cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME"; then - echo "ERROR roct cmake failed. cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" +debug_config() { + local Cfg=$1 + case "$Cfg" in + debug|debug+*) + return 0 + ;; + *) + ;; + esac + return 1 +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_ROCT_REPO_NAME set correctly?" exit 1 fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - mkdir -p "$BUILD_AOMP/build/roct/asan" - cd "$BUILD_AOMP/build/roct/asan" || exit - declare -a ASAN_CMAKE_OPTS - ASAN_CMAKE_OPTS=(-DCMAKE_C_COMPILER="$AOMP_CLANG_COMPILER" - -DCMAKE_CXX_COMPILER="$AOMP_CLANGXX_COMPILER" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake" - -DCMAKE_INSTALL_PREFIX="$INSTALL_ROCT" - -DCMAKE_BUILD_TYPE="$BUILDTYPE" - "${AOMP_ASAN_ORIGIN_RPATH[@]}" - -DCMAKE_INSTALL_LIBDIR="$AOMP_INSTALL_DIR/lib/asan") - echo " -----Running roct-asan cmake -----" - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME"; then - echo "ERROR roct-asan cmake failed.cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - echo "rm -rf $BUILD_AOMP/build/roct_debug" - [ -d "$BUILD_AOMP/build/roct_debug" ] && rm -rf "$BUILD_AOMP/build/roct_debug" - declare -a ROCT_CMAKE_OPTS - ROCT_CMAKE_OPTS=(-DCMAKE_C_COMPILER="$AOMP_CLANG_COMPILER" - -DCMAKE_CXX_COMPILER="$AOMP_CLANGXX_COMPILER" - -DCMAKE_INSTALL_PREFIX="$INSTALL_ROCT" - -DCMAKE_BUILD_TYPE=Debug - "${AOMP_DEBUG_ORIGIN_RPATH[@]}" - -DCMAKE_INSTALL_LIBDIR=lib-debug - -DBUILD_SHARED_LIBS=ON) - echo " -----Running roct_debug cmake -----" - mkdir -p "$BUILD_AOMP/build/roct_debug" - cd "$BUILD_AOMP/build/roct_debug" || exit - _prefix_map=(-fdebug-prefix-map="$AOMP_REPOS/$AOMP_ROCT_REPO_NAME/src=$_ompd_src_dir/roct/src") - echo "${AOMP_CMAKE}" "$(shquot "${ROCT_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot -g "${_prefix_map[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot -g "${_prefix_map[@]}")\"" \ - "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME" - - if ! ${AOMP_CMAKE} "${ROCT_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot -g "${_prefix_map[@]}")" \ - "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME"; then - echo "ERROR roct_debug cmake failed.cmake flags" - echo " $(shquot "${ROCT_CMAKE_OPTS[@]}")" - exit 1 - fi + check_writable_installdir "$1" "$(cfgvar INSTALL_ROCT)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "$SUDO rm -rf $(shquot "$BuildDir")" + $SUDO rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local ClangCC + local ClangCXX + local -a MYCMAKEOPTS + local -a _prefix_map + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + ClangCC="$(cfgvar AOMP_CLANG_COMPILER)" + ClangCXX="$(cfgvar AOMP_CLANGXX_COMPILER)" + + # Settings common to every config. + MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_ROCT)") + + # Variant-specific settings. + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DCMAKE_C_COMPILER="$ClangCC" + -DCMAKE_CXX_COMPILER="$ClangCXX" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake" + -DCMAKE_BUILD_TYPE=Release + "${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DCMAKE_INSTALL_LIBDIR="$AOMP_INSTALL_DIR/lib/asan" + -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + elif debug_config "$Cfg"; then + _prefix_map=(-fdebug-prefix-map="$SrcDir/src=$_ompd_src_dir/roct/src") + MYCMAKEOPTS+=(-DCMAKE_C_COMPILER="$ClangCC" + -DCMAKE_CXX_COMPILER="$ClangCXX" + -DCMAKE_BUILD_TYPE=Debug + "${AOMP_DEBUG_ORIGIN_RPATH[@]}" + -DCMAKE_INSTALL_LIBDIR=lib-debug + -DBUILD_SHARED_LIBS=ON + -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot -g "${_prefix_map[@]}")") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" + -DCMAKE_BUILD_TYPE=Release + "${AOMP_ORIGIN_RPATH[@]}" + -DCMAKE_INSTALL_LIBDIR=lib) fi -fi -if [ "$1" = "cmake" ]; then - exit 0 -fi + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running roct $Cfg cmake ---- " + echo "$AompCmake" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" -cd "$BUILD_AOMP/build/roct" || exit -echo -echo " -----Running make for roct ---- " + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR roct $Cfg cmake failed. cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 + fi + popd >& /dev/null || exit +} -if ! make -j "$AOMP_JOB_THREADS"; then +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for roct $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/roct" + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" echo " make" exit 1 -fi + fi + popd >& /dev/null || exit +} -if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - echo - echo " ----- Running make for roct-asan ----- " +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" - if ! make -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/roct/asan " - echo " make" - exit 1 + pushd "$BuildDir" >& /dev/null || exit + if asan_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib/asan ----- " + elif debug_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib-debug ----- " + else + echo " -----Installing to $InstallDir/lib ----- " fi -fi -if [ "$AOMP_BUILD_DEBUG" == 1 ] ; then - cd "$BUILD_AOMP/build/roct_debug" || exit - echo - echo " ----- Running make for roct_debug ----- " - - if ! make -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/roct_debug" - echo " make" - exit 1 + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 fi -fi + popd >& /dev/null || exit +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP/build/roct" || exit - echo " -----Installing to $INSTALL_ROCT/lib ----- " - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_AOMP/build/roct/asan" || exit - echo " -----Installing to $INSTALL_ROCT/lib/asan ----- " - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - fi - if [ "$AOMP_BUILD_DEBUG" == 1 ] ; then - cd "$BUILD_AOMP/build/roct_debug" || exit - echo " -----Installing to $INSTALL_ROCT/lib-debug ----- " - if ! $SUDO make install; then - echo "ERROR make install for roct failed " - exit 1 - fi - $SUDO mkdir -p "$_ompd_src_dir/roct" - echo "$SUDO cp -r $AOMP_REPOS/$AOMP_ROCT_REPO_NAME/src $_ompd_src_dir/roct" - $SUDO cp -r "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME/src" "$_ompd_src_dir/roct" - fi - - removepatch "$AOMP_REPOS/$AOMP_ROCT_REPO_NAME" -fi +task_postinstall() { + local Cfg=$1 + local SrcDir + SrcDir="$(get_src_dir)" + + # copy roct sources into the installation for runtime source debugging + $SUDO mkdir -p "$_ompd_src_dir/roct" + echo "$SUDO cp -r $SrcDir/src $_ompd_src_dir/roct" + $SUDO cp -r "$SrcDir/src" "$_ompd_src_dir/roct" +} + +do_list_configs() { + echo "default" + if "$(cfgbool AOMP_BUILD_SANITIZER)"; then + echo "asan" + fi + if "$(cfgbool AOMP_BUILD_DEBUG)"; then + echo "debug" + fi +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + case "$Cfg" in + debug) + echo "postinstall" + ;; + *) + ;; + esac + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From f8829bbde4bc4b83620ba300f453328e847fa171 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:04:27 -0500 Subject: [PATCH 14/71] Taskify build_rocminfo.sh Convert build_rocminfo.sh to the taskified build pattern. rocminfo has a single (default) config, so it uses one set of task_* functions driven by command_dispatcher. Route the user-controllable environment variables AOMP_RINFO_REPO_NAME and INSTALL_RINFO through cfgvar and add them to the aomp_utils allowlist. --- bin/aomp_utils | 3 +- bin/build_rocminfo.sh | 239 ++++++++++++++++++++++++++++-------------- 2 files changed, 165 insertions(+), 77 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index bcf6f5e19f..dd0bc8c80b 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -297,7 +297,8 @@ get_config_var_string() { AOMP_ROCR_REPO_NAME|AOMP_COMGR_REPO_NAME|AOMP_PROJECTS_LIST|GFXLIST|\ ROCMLIBS_GFXLIST|BUILD_TYPE|AOMP_VERSION_STRING|AOMP_CC_COMPILER|\ AOMP_CXX_COMPILER|AOMP_FLANG_THREADS|AOMP_CLANG_COMPILER|\ - AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT) + AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT|\ + AOMP_RINFO_REPO_NAME|INSTALL_RINFO) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_rocminfo.sh b/bin/build_rocminfo.sh index 6be1de87e2..5a7e33442b 100755 --- a/bin/build_rocminfo.sh +++ b/bin/build_rocminfo.sh @@ -28,20 +28,30 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -RINFO_REPO_DIR=$AOMP_REPOS/$AOMP_RINFO_REPO_NAME - -BUILD_DIR=${BUILD_AOMP} +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocminfo "$1" +} -BUILDTYPE="Release" +cfgbool() { + get_config_var_bool rocminfo "$1" +} INSTALL_RINFO=${INSTALL_RINFO:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_RINFO_REPO_NAME)" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -50,90 +60,167 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_rocminfo.sh nocmake NO cmake, make, NO install " echo " ./build_rocminfo.sh install NO Cmake, make install " echo " " - exit -fi - -if [ ! -d "$RINFO_REPO_DIR" ] ; then - echo "ERROR: Missing repository $RINFO_REPO_DIR/" - exit 1 + exit 0 fi -if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then - echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" - echo " Build the AOMP llvm compiler in $AOMP first" - echo " This is needed to build the device libraries" - echo " " - exit 1 -fi - -check_writable_installdir "$1" "$INSTALL_RINFO" - -patchrepo "$AOMP_REPOS/$AOMP_RINFO_REPO_NAME" +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/rocminfo" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_RINFO +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" + exit 1 + fi -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ -d "$BUILD_DIR/build/rocminfo" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/rocminfo" - rm -rf "$BUILD_DIR/build/rocminfo" - fi + if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then + echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" + echo " Build the AOMP llvm compiler in $AOMP first" + echo " This is needed to build the device libraries" + echo " " + exit 1 + fi - declare -a MYCMAKEOPTS - - MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" -DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DCMAKE_INSTALL_PREFIX="$INSTALL_RINFO" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DROCRTST_BLD_TYPE="$BUILDTYPE" - -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON - -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" - -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') - - mkdir -p "$BUILD_DIR/build/rocminfo" - cd "$BUILD_DIR/build/rocminfo" || exit - echo - echo " -----Running rocminfo cmake ---- " - echo "${AOMP_CMAKE} $(shquot "${MYCMAKEOPTS[@]}") $RINFO_REPO_DIR" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$RINFO_REPO_DIR"; then - echo "ERROR rocminfo cmake failed. Cmake flags" + check_writable_installdir "$1" "$(cfgvar INSTALL_RINFO)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_RINFO)" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" + -DROCRTST_BLD_TYPE=Release + -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON + -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" + -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running rocminfo $Cfg cmake ---- " + echo "$AompCmake" "$(shquot "${MYCMAKEOPTS[@]}")" "$SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR rocminfo $Cfg cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_DIR/build/rocminfo" || exit -echo -echo " -----Running make for rocminfo ---- " - -if ! make -j "$AOMP_JOB_THREADS"; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocminfo $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/rocminfo" + echo " cd $BuildDir" echo " make " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install rocminfo component run this command:" - echo " $0 install" - echo - fi -fi + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/rocminfo" || exit - echo - echo " -----Installing to $INSTALL_RINFO ----- " + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " if ! $SUDO make install; then echo "ERROR make install failed " exit 1 fi - removepatch "$AOMP_REPOS/$AOMP_RINFO_REPO_NAME" -fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 70fa9681192210b2152cbcff81d66c140c3f2ff8 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:06:06 -0500 Subject: [PATCH 15/71] Taskify build_xio.sh Convert build_xio.sh to the taskified build pattern. xio has a single (default) config. The git clone/pull of the rocm-xio source becomes an init task_fetch so it no longer runs on -h/help. The script now also sources aomp_utils (previously only aomp_common_vars). Route the user-controllable INSTALL_XIO through cfgvar and add it to the aomp_utils allowlist. --- bin/aomp_utils | 2 +- bin/build_xio.sh | 266 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 181 insertions(+), 87 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index dd0bc8c80b..9d4bea5abb 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -298,7 +298,7 @@ get_config_var_string() { ROCMLIBS_GFXLIST|BUILD_TYPE|AOMP_VERSION_STRING|AOMP_CC_COMPILER|\ AOMP_CXX_COMPILER|AOMP_FLANG_THREADS|AOMP_CLANG_COMPILER|\ AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT|\ - AOMP_RINFO_REPO_NAME|INSTALL_RINFO) + AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_xio.sh b/bin/build_xio.sh index 2662a138df..5d11543681 100755 --- a/bin/build_xio.sh +++ b/bin/build_xio.sh @@ -28,33 +28,31 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -XIO_REPO_DIR=$AOMP_REPOS/rocm-xio -echo "INFO: Getting latest sources for rocm-xio in dir \"$XIO_REPO_DIR\"" -if [ -d "$XIO_REPO_DIR" ] ; then - echo cd "$XIO_REPO_DIR" - cd "$XIO_REPO_DIR" || exit - echo git pull https://github.com/ROCm/rocm-xio.git - git pull https://github.com/ROCm/rocm-xio.git -else - echo cd "$AOMP_REPOS" - cd "$AOMP_REPOS" || exit - echo git clone https://github.com/ROCm/rocm-xio.git - git clone https://github.com/ROCm/rocm-xio.git - cd "$XIO_REPO_DIR" || exit -fi - -BUILD_DIR=${BUILD_AOMP} +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string xio "$1" +} -BUILDTYPE="Release" +cfgbool() { + get_config_var_bool xio "$1" +} # Install XIO in the compiler directory of ROCm INSTALL_XIO=${INSTALL_XIO:-$AOMP_INSTALL_DIR}/lib/llvm +REPO_DIR="$(cfgvar AOMP_REPOS)/rocm-xio" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -63,88 +61,184 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_xio.sh nocmake NO cmake, make, NO install " echo " ./build_xio.sh install NO Cmake, make install " echo " " - exit + exit 0 fi -if [ ! -d "$XIO_REPO_DIR" ] ; then - echo "ERROR: Missing repository $XIO_REPO_DIR/" - exit 1 -fi - -if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then - echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" - echo " Build the AOMP llvm compiler in $AOMP first" - echo " This is needed to build the xio libraries" - echo " " - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/rocm-xio" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_XIO +} + +task_fetch() { + local SrcDir + SrcDir="$(get_src_dir)" + echo "INFO: Getting latest sources for rocm-xio in dir \"$SrcDir\"" + if [ -d "$SrcDir" ] ; then + echo cd "$SrcDir" + cd "$SrcDir" || exit + echo git pull https://github.com/ROCm/rocm-xio.git + git pull https://github.com/ROCm/rocm-xio.git + else + echo cd "$(cfgvar AOMP_REPOS)" + cd "$(cfgvar AOMP_REPOS)" || exit + echo git clone https://github.com/ROCm/rocm-xio.git + git clone https://github.com/ROCm/rocm-xio.git + fi +} -check_writable_installdir "$1" "$INSTALL_XIO" +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" -patchrepo "$AOMP_REPOS/rocm-xio" + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" + exit 1 + fi -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ -d "$BUILD_DIR/build/rocm-xio" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/rocm-xio" - rm -rf "$BUILD_DIR/build/rocm-xio" - fi + if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then + echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" + echo " Build the AOMP llvm compiler in $AOMP first" + echo " This is needed to build the xio libraries" + echo " " + exit 1 + fi - declare -a MYCMAKEOPTS - - MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" -DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DCMAKE_INSTALL_PREFIX="$INSTALL_XIO" - -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON - -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" - -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') - - mkdir -p "$BUILD_DIR/build/rocm-xio" - cd "$BUILD_DIR/build/rocm-xio" || exit - echo - echo " -----Running ${AOMP_CMAKE} for xio ---- " - echo "${AOMP_CMAKE} -B . $(shquot "${MYCMAKEOPTS[@]}") -S $XIO_REPO_DIR" - - if ! ${AOMP_CMAKE} -B . "${MYCMAKEOPTS[@]}" -S "$XIO_REPO_DIR" ; then - echo "ERROR xio cmake failed. Cmake flags" + check_writable_installdir "$1" "$(cfgvar INSTALL_XIO)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_XIO)" + -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON + -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" + -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $AompCmake for xio $Cfg ---- " + echo "$AompCmake -B . $(shquot "${MYCMAKEOPTS[@]}") -S $SrcDir" + + if ! "$AompCmake" -B . "${MYCMAKEOPTS[@]}" -S "$SrcDir" ; then + echo "ERROR xio $Cfg cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_DIR/build/rocm-xio" || exit -echo -echo " -----Running $AOMP_CMAKE -j $AOMP_JOB_THREADS for xio ---- " - -if ! ${AOMP_CMAKE} --build . --target all -j "$AOMP_JOB_THREADS" ; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local AompCmake + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $AompCmake --build -j $Jobs for xio $Cfg ---- " + if ! "$AompCmake" --build . --target all -j "$Jobs" ; then echo " " - echo "ERROR: ${AOMP_CMAKE} -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: $AompCmake -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/rocm-xio" - echo " $AOMP_CMAKE " + echo " cd $BuildDir" + echo " $AompCmake " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install xio component run this command:" - echo " $0 install" - echo - fi -fi + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/rocm-xio" || exit - echo - echo " -----Installing to $INSTALL_XIO ----- " + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " if ! $SUDO make install; then echo "ERROR make install failed " exit 1 fi - removepatch "$AOMP_REPOS/rocm-xio" -fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "fetch" + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From d18793ed635a06b62ee4a439097e328e96dc1f35 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:08:25 -0500 Subject: [PATCH 16/71] Taskify build_emissary.sh Convert build_emissary.sh to the taskified build pattern. The flavour (mpi/hdf5) is still selected from the invoking symlink name and drives the source/build subdirs and extra cmake options; the build itself runs through a single (default) config of task_* functions. The git clone/pull becomes an init task_fetch so it no longer runs on -h/help, and the script now sources aomp_utils. Route the user-controllable INSTALL_EMISSARY through cfgvar and add it to the aomp_utils allowlist. --- bin/aomp_utils | 2 +- bin/build_emissary.sh | 285 +++++++++++++++++++++++++++--------------- 2 files changed, 185 insertions(+), 102 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 9d4bea5abb..9e18e149b9 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -298,7 +298,7 @@ get_config_var_string() { ROCMLIBS_GFXLIST|BUILD_TYPE|AOMP_VERSION_STRING|AOMP_CC_COMPILER|\ AOMP_CXX_COMPILER|AOMP_FLANG_THREADS|AOMP_CLANG_COMPILER|\ AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT|\ - AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO) + AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_emissary.sh b/bin/build_emissary.sh index bea946e1a0..74889d202a 100755 --- a/bin/build_emissary.sh +++ b/bin/build_emissary.sh @@ -26,49 +26,49 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string emissary "$1" +} + +cfgbool() { + get_config_var_bool emissary "$1" +} + +# The emissary flavour (mpi/hdf5) is selected by the name of the symlink used +# to invoke this script. _sname=${0##*/} -BUILD_DIR=${BUILD_AOMP} declare -a extra_cmake_opts=() - -if [ "$_sname" == "build_emissary_mpi.sh" ] ; then - EMISSARY_REPO_DIR=$AOMP_REPOS/emissary/MPI +if [ "$_sname" == "build_emissary_mpi.sh" ] ; then + EMISSARY_SRC_SUBDIR=MPI + EMISSARY_BUILD_SUBDIR=emissary_mpi extra_cmake_opts+=("-DLLVM_EXTERNAL_EMISSARY_MPI_INSTALL=$HOME/local/rocmopenmpi") - BUILD_EMISSARY_DIR="$BUILD_DIR/build/emissary_mpi" -elif [ "$_sname" == "build_emissary_hdf5.sh" ] ; then - EMISSARY_REPO_DIR=$AOMP_REPOS/emissary/HDF5 - BUILD_EMISSARY_DIR="$BUILD_DIR/build/emissary_hdf5" +elif [ "$_sname" == "build_emissary_hdf5.sh" ] ; then + EMISSARY_SRC_SUBDIR=HDF5 + EMISSARY_BUILD_SUBDIR=emissary_hdf5 else echo "ERROR: You must run build_emissary_mpi.sh" echo " or build_emissary_hdf5.sh" - exit -fi -echo "BUILD_EMISSARY_DIR=$BUILD_EMISSARY_DIR" - -echo "INFO: Getting latest sources for emissary in dir \"$EMISSARY_REPO_DIR\"" -if [ -d "$EMISSARY_REPO_DIR" ] ; then - echo cd "$EMISSARY_REPO_DIR" - cd "$EMISSARY_REPO_DIR" || exit - echo git pull - git pull -else - echo cd "$AOMP_REPOS" - cd "$AOMP_REPOS" || exit - echo git clone git@github.com:rocm/emissary - git clone git@github.com:rocm/emissary - cd "$EMISSARY_REPO_DIR" || exit + exit 1 fi - -BUILDTYPE="Release" - # Install EMISSARY in the compiler directory of ROCm INSTALL_EMISSARY=${INSTALL_EMISSARY:-$AOMP_INSTALL_DIR}/lib/llvm +REPO_DIR="$(cfgvar AOMP_REPOS)/emissary" +export OPENMPI_DIR=$HOME/local/rocmopenmpi if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -77,97 +77,180 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_emissary_mpi.sh nocmake NO cmake, make, NO install " echo " ./build_emissary_mpi.sh install NO Cmake, make install " echo " " - exit + exit 0 fi -if [ ! -d "$EMISSARY_REPO_DIR" ] ; then - echo "ERROR: Missing repository $EMISSARY_REPO_DIR/" - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR/$EMISSARY_SRC_SUBDIR" +} -if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then - echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" - echo " Build the AOMP llvm compiler in $AOMP first" - echo " This is needed to build the emissary libraries" - echo " " - exit 1 -fi +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" -check_writable_installdir "$1" "$INSTALL_EMISSARY" + case "$Cfg" in + "default") + echo -n "$BuildDir/$EMISSARY_BUILD_SUBDIR" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} -export OPENMPI_DIR=$HOME/local/rocmopenmpi +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_EMISSARY +} -patchrepo "$AOMP_REPOS/emissary" +task_fetch() { + echo "INFO: Getting latest sources for emissary in dir \"$REPO_DIR\"" + if [ -d "$REPO_DIR" ] ; then + echo cd "$REPO_DIR" + cd "$REPO_DIR" || exit + echo git pull + git pull + else + echo cd "$(cfgvar AOMP_REPOS)" + cd "$(cfgvar AOMP_REPOS)" || exit + echo git clone git@github.com:rocm/emissary + git clone git@github.com:rocm/emissary + fi +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ -d "$BUILD_EMISSARY_DIR" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_EMISSARY_DIR" - rm -rf "$BUILD_EMISSARY_DIR" - fi +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" - declare -a MYCMAKEOPTS - -# MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" -DCMAKE_BUILD_TYPE="$BUILDTYPE" -# -DCMAKE_INSTALL_PREFIX="$INSTALL_EMISSARY" -# -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -# -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" -# -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') - - MYCMAKEOPTS=( - -DCMAKE_BUILD_TYPE="$BUILDTYPE" - "${extra_cmake_opts[@]}" - "-DLLVM_MAIN_SRC_DIR=$AOMP_REPOS/llvm-project" - -DCMAKE_INSTALL_PREFIX="$INSTALL_EMISSARY") - - - mkdir -p "$BUILD_EMISSARY_DIR" - cd "$BUILD_EMISSARY_DIR" || exit - echo - echo " ---- Running ${AOMP_CMAKE} for emissary ---- " - echo "${AOMP_CMAKE}" -B . "${MYCMAKEOPTS[@]}" -S "$EMISSARY_REPO_DIR" - - if ! ${AOMP_CMAKE} -B . "${MYCMAKEOPTS[@]}" -S "$EMISSARY_REPO_DIR" ; then - echo "ERROR emissary cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" exit 1 - fi -fi + fi -if [ "$1" = "cmake" ]; then - exit 0 -fi + if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then + echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" + echo " Build the AOMP llvm compiler in $AOMP first" + echo " This is needed to build the emissary libraries" + echo " " + exit 1 + fi + + check_writable_installdir "$1" "$(cfgvar INSTALL_EMISSARY)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} -cd "$BUILD_EMISSARY_DIR" || exit -echo -echo " ---- Running $AOMP_CMAKE -j $AOMP_JOB_THREADS for emissary ---- " +task_unpatch() { + removepatch "$REPO_DIR" +} -if ! ${AOMP_CMAKE} --build . --target all -j "$AOMP_JOB_THREADS" ; then +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE=Release + "${extra_cmake_opts[@]}" + "-DLLVM_MAIN_SRC_DIR=$(cfgvar AOMP_REPOS)/llvm-project" + -DCMAKE_INSTALL_PREFIX="$(cfgvar INSTALL_EMISSARY)") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " ---- Running $AompCmake for emissary $Cfg ---- " + echo "$AompCmake -B . $(shquot "${MYCMAKEOPTS[@]}") -S $SrcDir" + + if ! "$AompCmake" -B . "${MYCMAKEOPTS[@]}" -S "$SrcDir" ; then + echo "ERROR emissary $Cfg cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local AompCmake + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " ---- Running $AompCmake --build -j $Jobs for emissary $Cfg ---- " + if ! "$AompCmake" --build . --target all -j "$Jobs" ; then echo " " - echo "ERROR: ${AOMP_CMAKE} -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: $AompCmake -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_EMISSARY_DIR" - echo " $AOMP_CMAKE " + echo " cd $BuildDir" + echo " $AompCmake " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install emissary component run this command:" - echo " $0 install" - echo - fi -fi + fi + popd >& /dev/null || exit +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_EMISSARY_DIR" || exit - echo - echo " -----Installing to $INSTALL_EMISSARY ----- " +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " if ! $SUDO make install; then echo "ERROR make install failed " exit 1 fi - removepatch "$AOMP_REPOS/emissary" -fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "fetch" + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 61d3ccdb8618a3f23d033ce4ef3d480a18e04feb Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:11:12 -0500 Subject: [PATCH 17/71] Taskify build_libdevice.sh Convert build_libdevice.sh to the taskified build pattern with a single (default) config. The optional test step (gated by SKIPTEST) is folded into task_build so it still runs on the build/nocmake paths. Route the user-controllable AOMP_LIBDEVICE_REPO_NAME, INSTALL_LIBDEVICE and SKIPTEST through cfgvar and add them to the aomp_utils allowlist. --- bin/aomp_utils | 3 +- bin/build_libdevice.sh | 283 ++++++++++++++++++++++++++--------------- 2 files changed, 184 insertions(+), 102 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 9e18e149b9..7d70aff6b3 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -298,7 +298,8 @@ get_config_var_string() { ROCMLIBS_GFXLIST|BUILD_TYPE|AOMP_VERSION_STRING|AOMP_CC_COMPILER|\ AOMP_CXX_COMPILER|AOMP_FLANG_THREADS|AOMP_CLANG_COMPILER|\ AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT|\ - AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY) + AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY|\ + AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_libdevice.sh b/bin/build_libdevice.sh index a1693e67b5..6da81ef837 100755 --- a/bin/build_libdevice.sh +++ b/bin/build_libdevice.sh @@ -4,126 +4,207 @@ # build the rocm-device-libs libraries in $AOMP/lib/libdevice # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string libdevice "$1" +} + +cfgbool() { + get_config_var_bool libdevice "$1" +} + # We now pickup HSA from the AOMP install directory because it is built -# with build_roct.sh and build_rocr.sh . +# with build_roct.sh and build_rocr.sh . HSA_DIR=${HSA_DIR:-$AOMP} SKIPTEST=${SKIPTEST:-"YES"} +INSTALL_LIBDEVICE=${INSTALL_LIBDEVICE:-$AOMP_INSTALL_DIR} -INSTALL_ROOT_DIR=${INSTALL_LIBDEVICE:-$AOMP_INSTALL_DIR} -INSTALL_DIR=$INSTALL_ROOT_DIR +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROJECT_REPO_NAME)/amd/$(cfgvar AOMP_LIBDEVICE_REPO_NAME)" export LLVM_DIR=$AOMP_INSTALL_DIR export LLVM_BUILD=$AOMP_INSTALL_DIR - -REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_LIBDEVICE_REPO_NAME - -declare -a MYCMAKEOPTS - -MYCMAKEOPTS=(-DLLVM_DIR="$LLVM_DIR" -DCMAKE_INSTALL_LIBDIR=lib) - -if [ ! -d "$AOMP_INSTALL_DIR/lib" ]; then - echo "ERROR: Directory $AOMP/lib is missing" - echo " AOMP must be installed in $AOMP_INSTALL_DIR to continue" - exit 1 -fi - -export LLVM_BUILD HSA_DIR +export HSA_DIR export PATH="$LLVM_BUILD/bin":$PATH -patchrepo "$REPO_DIR" - -if [ "$1" != "install" ] && [ "$1" != "nocmake" ]; then - - builddir_libdevice=$BUILD_DIR/build/libdevice - if [ -d "$builddir_libdevice" ]; then - echo rm -rf "$builddir_libdevice" - # need SUDO because a previous make install was done with sudo - $SUDO rm -rf "$builddir_libdevice" - fi - mkdir -p "$builddir_libdevice" - cd "$builddir_libdevice" || exit - echo - echo "DOING BUILD in Directory $builddir_libdevice" - echo - - CC="$LLVM_BUILD/bin/clang" - export CC - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - "-DCMAKE_INSTALL_PREFIX=$INSTALL_DIR" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_LIBDEVICE_REPO_NAME" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/$AOMP_LIBDEVICE_REPO_NAME"; then - echo "ERROR cmake failed command was:" - echo " ${AOMP_CMAKE} $(shquot "${MYCMAKEOPTS[@]}") -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR $BUILD_DIR/$AOMP_LIBDEVICE_REPO_NAME" - exit 1 - fi +if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then + echo " " + echo "Example commands and actions: " + echo " ./build_libdevice.sh cmake, make, NO Install " + echo " ./build_libdevice.sh nocmake NO cmake, make, NO install " + echo " ./build_libdevice.sh install NO Cmake, make install " + echo " " + exit 0 fi -if [ "$1" = "cmake" ]; then - removepatch "$REPO_DIR" - exit 0 -fi - -if [ "$1" != "install" ]; then - echo "make -j $AOMP_JOB_THREADS" +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/libdevice" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_LIBDEVICE +} + +task_precheck() { + if [ ! -d "$AOMP_INSTALL_DIR/lib" ]; then + echo "ERROR: Directory $AOMP/lib is missing" + echo " AOMP must be installed in $AOMP_INSTALL_DIR to continue" + exit 1 + fi +} - if ! make -j "$AOMP_JOB_THREADS"; then - echo "ERROR make failed " - exit 1 - fi +task_patch() { + patchrepo "$REPO_DIR" +} - echo +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + # need SUDO because a previous make install was done with sudo + $SUDO rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local InstallDir + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + InstallDir="$(cfgvar INSTALL_LIBDEVICE)" + + MYCMAKEOPTS=(-DLLVM_DIR="$LLVM_DIR" + -DCMAKE_INSTALL_LIBDIR=lib + -DCMAKE_INSTALL_PREFIX="$InstallDir") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo "DOING BUILD in Directory $BuildDir" + CC="$LLVM_BUILD/bin/clang" + export CC + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed command was:" + echo " $AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + exit 1 + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo "make -j $Jobs" + if ! make -j "$Jobs"; then + echo "ERROR make failed " + exit 1 + fi + echo echo " Done with all makes" - echo " Please run ./build_libdevice.sh install " - echo - - if [ "$SKIPTEST" != "YES" ] ; then - builddir_libdevice=$BUILD_DIR/build/libdevice - cd "$builddir_libdevice" || exit - echo "running tests in $builddir_libdevice" - make test - echo + + if [ "$(cfgvar SKIPTEST)" != "YES" ] ; then + echo "running tests in $BuildDir" + make test + echo echo "# done with all tests" - echo + echo fi -fi - -if [ "$1" == "install" ] ; then - - echo - echo mkdir -p "$INSTALL_DIR/include" - $SUDO mkdir -p "$INSTALL_DIR/include" - $SUDO mkdir -p "$INSTALL_DIR/lib" - builddir_libdevice=$BUILD_DIR/build/libdevice - echo "running make install from $builddir_libdevice" - cd "$builddir_libdevice" || exit - echo "$SUDO make -j $AOMP_JOB_THREADS install" - $SUDO make -j "$AOMP_JOB_THREADS" install - - # rocm-device-lib cmake installs to lib dir, move all bc files up one level - # and cleanup unused oclc_isa_version bc files and link correct one - #echo - #echo "POST-INSTALL REORG OF SUBDIRECTORIES $INSTALL_DIR" - #echo "--" - #echo "-- $INSTALL_DIR" - #echo "-- MOVING bc FILES FROM lib DIRECTORY UP ONE LEVEL" - #$SUDO mv $INSTALL_DIR/lib/*.bc $INSTALL_DIR - #$SUDO rm -rf $INSTALL_DIR/lib/cmake - #$SUDO rmdir $INSTALL_DIR/lib - - # END OF POST-INSTALL REORG - - echo - echo " $0 Installation complete into $INSTALL_DIR" - echo - removepatch "$REPO_DIR" -fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + echo + echo mkdir -p "$InstallDir/include" + $SUDO mkdir -p "$InstallDir/include" + $SUDO mkdir -p "$InstallDir/lib" + pushd "$BuildDir" >& /dev/null || exit + echo "running make install from $BuildDir" + echo "$SUDO make -j $Jobs install" + $SUDO make -j "$Jobs" install + echo + echo " Installation complete into $InstallDir" + echo + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 54445dd300c6d0300e624c3279c8b0ef6691c6f9 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:12:51 -0500 Subject: [PATCH 18/71] Taskify build_rocm-cmake.sh Convert build_rocm-cmake.sh to the taskified build pattern. rocm-cmake has no make step, so its single (default) config exposes only clean/cmake/install tasks and no patching. Route the user-controllable AOMP_ROCMCMAKE_REPO_NAME through cfgvar and add it to the aomp_utils allowlist. --- bin/aomp_utils | 3 +- bin/build_rocm-cmake.sh | 169 +++++++++++++++++++++++++++++----------- 2 files changed, 125 insertions(+), 47 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 7d70aff6b3..9e68243ef1 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -299,7 +299,8 @@ get_config_var_string() { AOMP_CXX_COMPILER|AOMP_FLANG_THREADS|AOMP_CLANG_COMPILER|\ AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT|\ AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY|\ - AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST) + AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ + AOMP_ROCMCMAKE_REPO_NAME) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_rocm-cmake.sh b/bin/build_rocm-cmake.sh index cd67067f5c..c0597ddef3 100755 --- a/bin/build_rocm-cmake.sh +++ b/bin/build_rocm-cmake.sh @@ -28,14 +28,29 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -BUILD_DIR=${BUILD_AOMP} +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocm-cmake "$1" +} + +cfgbool() { + get_config_var_bool rocm-cmake "$1" +} + +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_ROCMCMAKE_REPO_NAME)" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -43,61 +58,123 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_rocm-cmake.sh cmake, make, NO Install " echo " ./build_rocm-cmake.sh install NO Cmake, make install " echo " " - exit + exit 0 fi -echo "checking for $AOMP_REPOS/$AOMP_ROCMCMAKE_REPO_NAME" -if [ ! -d "$AOMP_REPOS/$AOMP_ROCMCMAKE_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_ROCMCMAKE_REPO_NAME" - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR" +} -check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ -d "$BUILD_DIR/build/rocm-cmake" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo rm -rf "$BUILD_DIR/build/rocm-cmake" - rm -rf "$BUILD_DIR/build/rocm-cmake" - fi - - declare -a MYCMAKEOPTS - - export CMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR" - MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR") - - mkdir -p "$BUILD_DIR/build/rocm-cmake" - cd "$BUILD_DIR/build/rocm-cmake" || exit - echo - echo " -----Running rocm-cmake cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$AOMP_REPOS/$AOMP_ROCMCMAKE_REPO_NAME" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_ROCMCMAKE_REPO_NAME"; then - echo "ERROR rocm-cmake cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" + case "$Cfg" in + "default") + echo -n "$BuildDir/rocm-cmake" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + echo "checking for $SrcDir" + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" exit 1 - fi -fi + fi -if [ "$1" = "cmake" ]; then - exit 0 -fi + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} -cd "$BUILD_DIR/build/rocm-cmake" || exit +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS -# ----------- no make for this component + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/rocm-cmake" || exit - echo - echo " -----Installing to $AOMP_INSTALL_DIR ----- " + export CMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR" + MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running rocm-cmake $Cfg cmake ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR rocm-cmake $Cfg cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " if ! $SUDO make install; then echo "ERROR make install failed " exit 1 fi -fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. rocm-cmake has no make step. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 43d365fb6a413d870ada6354011b9cd55c19c561 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:14:29 -0500 Subject: [PATCH 19/71] Taskify build_rocm_smi_lib.sh Convert build_rocm_smi_lib.sh to the taskified build pattern with a single (default) config. The repo name and install prefix are fixed values, so no new cfgvar allowlist entries are required. --- bin/build_rocm_smi_lib.sh | 244 ++++++++++++++++++++++++++------------ 1 file changed, 166 insertions(+), 78 deletions(-) diff --git a/bin/build_rocm_smi_lib.sh b/bin/build_rocm_smi_lib.sh index 7927ade7d6..44ee9875d2 100755 --- a/bin/build_rocm_smi_lib.sh +++ b/bin/build_rocm_smi_lib.sh @@ -28,18 +28,29 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -RSMILIB_REPO_DIR=$AOMP_REPOS/rocm_smi_lib +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocm_smi_lib "$1" +} -BUILD_DIR=${BUILD_AOMP} +cfgbool() { + get_config_var_bool rocm_smi_lib "$1" +} -BUILDTYPE="Release" +REPO_DIR="$(cfgvar AOMP_REPOS)/rocm_smi_lib" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -48,88 +59,165 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_rocm_smi_lib.sh nocmake NO cmake, make, NO install " echo " ./build_rocm_smi_lib.sh install NO Cmake, make install " echo " " - exit -fi - -if [ ! -d "$RSMILIB_REPO_DIR" ] ; then - echo "ERROR: Missing repository $RSMILIB_REPO_DIR/" - exit 1 + exit 0 fi -if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then - echo "ERROR: Missing file $AOMP/bin/clang" - echo " Build the AOMP llvm compiler in $AOMP first" - echo " This is needed to build the device libraries" - echo " " - exit 1 -fi - -check_writable_installdir "$1" "$AOMP_INSTALL_DIR" - -patchrepo "$AOMP_REPOS/rocm_smi_lib" - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ -d "$BUILD_DIR/build/rocm_smi_lib" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/rocm_smi_lib" - rm -rf "$BUILD_DIR/build/rocm_smi_lib" - fi - - declare -a MYCMAKEOPTS - - MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" -DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" - -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON - -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" - -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') - - mkdir -p "$BUILD_DIR/build/rocm_smi_lib" - cd "$BUILD_DIR/build/rocm_smi_lib" || exit - echo - echo " -----Running rocm_smi_lib cmake ---- " - echo "${AOMP_CMAKE} $(shquot "${MYCMAKEOPTS[@]}") $RSMILIB_REPO_DIR" +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/rocm_smi_lib" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" + exit 1 + fi - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$RSMILIB_REPO_DIR"; then - echo "ERROR rocm_smi_lib cmake failed. Cmake flags" + if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then + echo "ERROR: Missing file $AOMP/bin/clang" + echo " Build the AOMP llvm compiler in $AOMP first" + echo " This is needed to build the device libraries" + echo " " + exit 1 + fi + + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON + -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" + -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running rocm_smi_lib $Cfg cmake ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR rocm_smi_lib $Cfg cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_DIR/build/rocm_smi_lib" || exit -echo -echo " -----Running make for rocm_smi_lib ---- " - -if ! make -j "$AOMP_JOB_THREADS"; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocm_smi_lib $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/rocm_smi_lib" + echo " cd $BuildDir" echo " make " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install rocm_smi_lib component run this command:" - echo " $0 install" - echo + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" fi -fi +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/rocm_smi_lib" || exit - echo - echo " -----Installing to $AOMP_INSTALL_DIR ----- " - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - removepatch "$AOMP_REPOS/rocm_smi_lib" -fi +command_dispatcher "$@" From aac4fee4d5eae652ebb4a6d21a5bddafa5cbf634 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:15:29 -0500 Subject: [PATCH 20/71] Taskify build_amdsmi.sh Convert build_amdsmi.sh to the taskified build pattern with a single (default) config. The repo name and install prefix are fixed values, so no new cfgvar allowlist entries are required. --- bin/build_amdsmi.sh | 243 ++++++++++++++++++++++++++++++-------------- 1 file changed, 166 insertions(+), 77 deletions(-) diff --git a/bin/build_amdsmi.sh b/bin/build_amdsmi.sh index 9a515b969b..5a8774db2a 100755 --- a/bin/build_amdsmi.sh +++ b/bin/build_amdsmi.sh @@ -28,18 +28,29 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -RSMILIB_REPO_DIR=$AOMP_REPOS/amdsmi +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string amdsmi "$1" +} -BUILD_DIR=${BUILD_AOMP} +cfgbool() { + get_config_var_bool amdsmi "$1" +} -BUILDTYPE="Release" +REPO_DIR="$(cfgvar AOMP_REPOS)/amdsmi" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -48,87 +59,165 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_amdsmi.sh nocmake NO cmake, make, NO install " echo " ./build_amdsmi.sh install NO Cmake, make install " echo " " - exit -fi - -if [ ! -d "$RSMILIB_REPO_DIR" ] ; then - echo "ERROR: Missing repository $RSMILIB_REPO_DIR/" - exit 1 -fi - -if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then - echo "ERROR: Missing file $AOMP/bin/clang" - echo " Build the AOMP llvm compiler in $AOMP first" - echo " This is needed to build the device libraries" - echo " " - exit 1 + exit 0 fi -check_writable_installdir "$1" "$AOMP_INSTALL_DIR" - -patchrepo "$AOMP_REPOS/amdsmi" - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ -d "$BUILD_DIR/build/amdsmi" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/amdsmi" - rm -rf "$BUILD_DIR/build/amdsmi" - fi +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/amdsmi" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" + exit 1 + fi - declare -a MYCMAKEOPTS - - MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" -DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" - -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON - -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" - -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') - - mkdir -p "$BUILD_DIR/build/amdsmi" - cd "$BUILD_DIR/build/amdsmi" || exit - echo - echo " -----Running amdsmi cmake ---- " - echo "${AOMP_CMAKE} $(shquot "${MYCMAKEOPTS[@]}") $RSMILIB_REPO_DIR" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$RSMILIB_REPO_DIR"; then - echo "ERROR amdsmi cmake failed. Cmake flags" + if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then + echo "ERROR: Missing file $AOMP/bin/clang" + echo " Build the AOMP llvm compiler in $AOMP first" + echo " This is needed to build the device libraries" + echo " " + exit 1 + fi + + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=("${AOMP_ORIGIN_RPATH[@]}" + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON + -DCMAKE_INSTALL_RPATH="\$ORIGIN/../lib" + -DCMAKE_EXE_LINKER_FLAGS='-Wl,--disable-new-dtags') + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running amdsmi $Cfg cmake ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR amdsmi $Cfg cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_DIR/build/amdsmi" || exit -echo -echo " -----Running make for amdsmi ---- " - -if ! make -j "$AOMP_JOB_THREADS"; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for amdsmi $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/amdsmi" + echo " cd $BuildDir" echo " make " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install amdsmi component run this command:" - echo " $0 install" - echo + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" fi -fi +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/amdsmi" || exit - echo - echo " -----Installing to $AOMP_INSTALL_DIR ----- " - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - removepatch "$AOMP_REPOS/amdsmi" -fi +command_dispatcher "$@" From 588fe3c9573a25cbee955f52885163abf9582e16 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:17:34 -0500 Subject: [PATCH 21/71] Taskify build_extras.sh Convert build_extras.sh to the taskified build pattern. extras has no cmake/make: its "build" stage copies the utility scripts into the build dir and patches their install-path placeholders with sed, and the install stage copies them into bin (plus the standalone gpurun symlink). Route the user-controllable AOMP_REPO_NAME and INSTALL_EXTRAS through cfgvar (and AOMP_STANDALONE_BUILD through cfgbool); add the new string vars to the aomp_utils allowlist. --- bin/aomp_utils | 2 +- bin/build_extras.sh | 207 ++++++++++++++++++++++++++++++-------------- 2 files changed, 142 insertions(+), 67 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 9e68243ef1..c49c14137a 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -300,7 +300,7 @@ get_config_var_string() { AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT|\ AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY|\ AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ - AOMP_ROCMCMAKE_REPO_NAME) + AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_extras.sh b/bin/build_extras.sh index d949065fdd..79ce1595d6 100755 --- a/bin/build_extras.sh +++ b/bin/build_extras.sh @@ -29,21 +29,33 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -AOMP_REPO_DIR=$AOMP_REPOS/$AOMP_REPO_NAME +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string extras "$1" +} -BUILD_DIR=${BUILD_AOMP} +cfgbool() { + get_config_var_bool extras "$1" +} INSTALL_EXTRAS=${INSTALL_EXTRAS:-$LLVM_INSTALL_LOC} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_REPO_NAME)" export LLVM_DIR=$LLVM_INSTALL_LOC -if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then +if [ "$(cfgbool AOMP_STANDALONE_BUILD)" == "true" ] ; then install_list="gpurun rebundle_hip_lib.sh raja_build.sh kokkos_build.sh aompversion blt.patch raja.patch modulefile" else install_list="gpurun" @@ -55,70 +67,133 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_extras.sh copy to build location, NO Install " echo " ./build_extras.sh install install " echo " " - exit + exit 0 fi -# Make sure we can update the install directory -check_writable_installdir "$1" "$INSTALL_EXTRAS" - -if [ "$1" != "install" ] ; then - if [ -d "$BUILD_DIR/build/extras" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/extras" - rm -rf "$BUILD_DIR/build/extras" - fi - - if [ "$AOMP_STANDALONE_BUILD" == 0 ] ; then - export AOMP_VERSION_STRING=$ROCM_VERSION - fi - - mkdir -p "$BUILD_DIR/build/extras" - cd "$BUILD_DIR/build/extras" || exit - - if [ "$AOMP_STANDALONE_BUILD" == 0 ] ; then - SED_INSTALL_DIR=$(echo /opt/rocm/llvm | sed -e 's,/,\\/,g') +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/extras" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_EXTRAS +} + +task_precheck() { + check_writable_installdir "$1" "$(cfgvar INSTALL_EXTRAS)" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +# extras has no cmake/make; the "build" stage copies utility scripts into the +# build directory and patches their install path placeholders with sed. +task_build() { + local Cfg=$1 + local BuildDir + local SrcDir + local SED_INSTALL_DIR + local util + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + + if [ "$(cfgbool AOMP_STANDALONE_BUILD)" == "false" ] ; then + export AOMP_VERSION_STRING=$ROCM_VERSION + fi + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + + if [ "$(cfgbool AOMP_STANDALONE_BUILD)" == "false" ] ; then + SED_INSTALL_DIR=$(echo /opt/rocm/llvm | sed -e 's,/,\\/,g') + else + SED_INSTALL_DIR="$(cfgvar INSTALL_EXTRAS)" + SED_INSTALL_DIR="${SED_INSTALL_DIR//\//\\/}" + fi + export SED_INSTALL_DIR + + echo "----- Copy util scripts to $BuildDir -----" + cp "$SrcDir"/utils/* "$BuildDir" + cp "$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROJECT_REPO_NAME)"/offload/utils/gpurun "$BuildDir" + + for util in $install_list; do + if [ "$util" == "rebundle_hip_lib.sh" ]; then + /bin/sed -i -e "s/X\\.Y\\-Z/${AOMP_VERSION_STRING}/g" -e "s/_LLVM_INSTALL_DIR_/${SED_INSTALL_DIR}/g" "$util" + else + /bin/sed -i -e "s/X\\.Y\\-Z/${AOMP_VERSION_STRING}/g" -e "s/_AOMP_INSTALL_DIR_/${SED_INSTALL_DIR}/g" "$util" + fi + done + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local util + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir/bin ----- " + for util in $install_list; do + echo "-- Installing: $InstallDir/bin/$util" + cp "$BuildDir/$util" "$InstallDir"/bin + echo "$InstallDir/bin/$util" >> install_manifest.txt + done + if [ "$(cfgbool AOMP_STANDALONE_BUILD)" == "true" ] ; then + if [ -f "$LLVM_INSTALL_LOC/bin/gpurun" ] && [ ! -h "$AOMP_INSTALL_DIR/bin/gpurun" ]; then + echo "Creating gpurun symlink: ${AOMP_INSTALL_DIR}/bin/gpurun -> ${LLVM_INSTALL_LOC}/bin/gpurun" + ln -s ../lib/llvm/bin/gpurun "$AOMP_INSTALL_DIR"/bin/gpurun + fi + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. extras has no cmake step. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "build" + echo "install" else - SED_INSTALL_DIR="${INSTALL_EXTRAS//\//\\/}" + echo "Unknown config '$Cfg'" fi +} - export SED_INSTALL_DIR - - echo "----- Copy util scripts to $BUILD_DIR/build/extras -----" - cp "$AOMP_REPO_DIR"/utils/* "$BUILD_DIR"/build/extras - cp "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME"/offload/utils/gpurun "$BUILD_DIR"/build/extras - - for util in $install_list; do - if [ "$util" == "rebundle_hip_lib.sh" ]; then - /bin/sed -i -e "s/X\\.Y\\-Z/${AOMP_VERSION_STRING}/g" -e "s/_LLVM_INSTALL_DIR_/${SED_INSTALL_DIR}/g" "$util" - else - /bin/sed -i -e "s/X\\.Y\\-Z/${AOMP_VERSION_STRING}/g" -e "s/_AOMP_INSTALL_DIR_/${SED_INSTALL_DIR}/g" "$util" - fi - done -fi - -cd "$BUILD_DIR/build/extras" || exit -echo -if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install extras component run this command:" - echo " $0 install" - echo -fi - -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/extras" || exit - echo " -----Installing to $INSTALL_EXTRAS/bin ----- " - for util in $install_list; do - echo "-- Installing: $INSTALL_EXTRAS/bin/$util" - cp "$BUILD_DIR"/build/extras/"$util" "$INSTALL_EXTRAS"/bin - echo "$INSTALL_EXTRAS/bin/$util" >> install_manifest.txt - done - if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then - if [ -f "$LLVM_INSTALL_LOC/bin/gpurun" ] && [ ! -h "$AOMP_INSTALL_DIR/bin/gpurun" ]; then - echo "Creating gpurun symlink: ${AOMP_INSTALL_DIR}/bin/gpurun -> ${LLVM_INSTALL_LOC}/bin/gpurun" - ln -s ../lib/llvm/bin/gpurun "$AOMP_INSTALL_DIR"/bin/gpurun - fi - fi -fi +command_dispatcher "$@" From 462cc2adb37e1115664b36b8badcde53edbe8e95 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:25:08 -0500 Subject: [PATCH 22/71] Taskify build_hipcc.sh Convert build_hipcc.sh to the taskified build pattern with a single (default) config and no patching. Drop a stray empty export of SED_INSTALL_DIR that had been copied in from another script. Route the user-controllable INSTALL_HIPCC through cfgvar and add it to the aomp_utils allowlist. --- bin/aomp_utils | 2 +- bin/build_hipcc.sh | 229 ++++++++++++++++++++++++++++++--------------- 2 files changed, 154 insertions(+), 77 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index c49c14137a..a053c95b0b 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -300,7 +300,7 @@ get_config_var_string() { AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT|\ AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY|\ AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ - AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS) + AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_hipcc.sh b/bin/build_hipcc.sh index eb23af4b85..c658895c46 100755 --- a/bin/build_hipcc.sh +++ b/bin/build_hipcc.sh @@ -23,20 +23,30 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -HIPCC_REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/amd/hipcc - -BUILD_DIR=${BUILD_AOMP} +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string hipcc "$1" +} -BUILDTYPE="Release" +cfgbool() { + get_config_var_bool hipcc "$1" +} INSTALL_HIPCC=${INSTALL_HIPCC:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROJECT_REPO_NAME)/amd/hipcc" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -45,85 +55,152 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_hipcc.sh nocmake NO cmake, make, NO install " echo " ./build_hipcc.sh install NO Cmake, make install " echo " " - exit -fi - -if [ ! -d "$HIPCC_REPO_DIR" ] ; then - echo "ERROR: Missing repository $HIPCC_REPO_DIR/" - exit 1 -fi - -if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then - echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" - echo " Build and install the AOMP clang compiler in $AOMP first" - echo " This is needed to build hipcc " - echo " " - exit 1 + exit 0 fi -check_writable_installdir "$1" "$INSTALL_HIPCC" - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - - if [ -d "$BUILD_DIR/build/hipcc" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/hipcc" - rm -rf "$BUILD_DIR/build/hipcc" - fi - - declare -a MYCMAKEOPTS - - MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR") - - mkdir -p "$BUILD_DIR/build/hipcc" - cd "$BUILD_DIR/build/hipcc" || exit - - export SED_INSTALL_DIR - echo - echo " -----Running cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" "$HIPCC_REPO_DIR" +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/hipcc" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_HIPCC +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" + exit 1 + fi - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$HIPCC_REPO_DIR"; then - echo "ERROR hipcc cmake failed. Cmake flags" + if [ ! -f "$LLVM_INSTALL_LOC/bin/clang" ] ; then + echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" + echo " Build and install the AOMP clang compiler in $AOMP first" + echo " This is needed to build hipcc " + echo " " + exit 1 + fi + + check_writable_installdir "$1" "$(cfgvar INSTALL_HIPCC)" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for hipcc $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR hipcc $Cfg cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_DIR/build/hipcc" || exit -echo -echo " -----Running make for hipcc ---- " - -if ! make -j "$AOMP_JOB_THREADS"; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for hipcc $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/hipcc" + echo " cd $BuildDir" echo " make " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install hipcc component run this command:" - echo " $0 install" - echo + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" fi -fi - -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/hipcc" || exit - echo - echo " -----Installing to $INSTALL_HIPCC ----- " +} - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi -fi +command_dispatcher "$@" From a0b28b10a831e931d47fa47ee95311fac249e202 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:28:00 -0500 Subject: [PATCH 23/71] Taskify build_hipamd.sh Convert build_hipamd.sh to the taskified build pattern with default/asan/debug configs. Both the hipamd and clr repos are patched in task_patch/task_unpatch, the debug config builds only the amdhip64 target, the debug source-copy is handled in task_postinstall, and the installed hipcc/hipvars.pm path fix-ups run as the default config's postinstall. The repos and install prefix are fixed paths, so no new cfgvar allowlist entries are required. --- bin/build_hipamd.sh | 524 ++++++++++++++++++++++++-------------------- 1 file changed, 284 insertions(+), 240 deletions(-) diff --git a/bin/build_hipamd.sh b/bin/build_hipamd.sh index ad79fb56d8..21271fda1b 100755 --- a/bin/build_hipamd.sh +++ b/bin/build_hipamd.sh @@ -27,21 +27,34 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -export HIPAMD_DIR=$AOMP_REPOS/clr -export HIP_DIR=$AOMP_REPOS/hip -export ROCclr_DIR=$AOMP_REPOS/clr/rocclr -export OPENCL_DIR=$AOMP_REPOS/clr/opencl -[[ ! -d $HIPAMD_DIR ]] && echo "ERROR: Missing $HIPAMD_DIR" && exit 1 -[[ ! -d $HIP_DIR ]] && echo "ERROR: Missing $HIP_DIR" && exit 1 -[[ ! -d $ROCclr_DIR ]] && echo "ERROR: Missing $ROCclr_DIR" && exit 1 -[[ ! -d $OPENCL_DIR ]] && echo "ERROR: Missing $OPENCL_DIR" && exit 1 +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string hipamd "$1" +} + +cfgbool() { + get_config_var_bool hipamd "$1" +} + +_repos="$(cfgvar AOMP_REPOS)" +export HIPAMD_DIR=$_repos/clr +export HIP_DIR=$_repos/hip +export ROCclr_DIR=$_repos/clr/rocclr +export OPENCL_DIR=$_repos/clr/opencl export HSA_PATH=$AOMP_INSTALL_DIR export ROCM_PATH=$AOMP_INSTALL_DIR @@ -49,8 +62,7 @@ export HIP_CLANG_PATH=$AOMP_INSTALL_DIR/bin export DEVICE_LIB_PATH=$AOMP_INSTALL_DIR/lib export LLVM_DIR=$LLVM_INSTALL_LOC -BUILD_DIR=${BUILD_AOMP} -BUILDTYPE="Release" +_ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -59,278 +71,310 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_hipamd.sh nocmake NO cmake, make, NO install " echo " ./build_hipamd.sh install NO Cmake, make install " echo " " - exit + exit 0 fi -check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +get_src_dir() { + echo "$HIPAMD_DIR" +} -patchrepo "$AOMP_REPOS/hipamd" -patchrepo "$AOMP_REPOS/clr" +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/hipamd" + ;; + "asan") + echo -n "$BuildDir/hipamd/asan" + ;; + "debug") + echo -n "$BuildDir/hipamd_debug" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} -#if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - #LDFLAGS=$(shquot '-fuse-ld=lld' "${ASAN_FLAGS[@]}")" - #export LDFLAGS -#fi +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} -_ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" +asan_config() { + local Cfg=$1 + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then +debug_config() { + local Cfg=$1 + case "$Cfg" in + debug|debug+*) + return 0 + ;; + *) + ;; + esac + return 1 +} - if [ -d "$BUILD_DIR/build/hipamd" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo rm -rf "$BUILD_DIR/build/hipamd" - rm -rf "$BUILD_DIR/build/hipamd" - fi +edit_installed_hip_file() { + local installed_file_to_edit="$1" + if [ -f "$installed_file_to_edit" ] ; then + # In hipvars.pm HIP_PATH is determined by parent directory of hipcc location. + # Set ROCM_PATH using HIP_PATH + $SUDO sed -i -e "s/\"\/opt\/rocm\"/\"\$HIP_PATH\"/" "$installed_file_to_edit" + # Set HIP_CLANG_PATH using ROCM_PATH/bin + $SUDO sed -i -e "s/\"\$ROCM_PATH\/llvm\/bin\"/\"\$ROCM_PATH\/bin\"/" "$installed_file_to_edit" + fi +} - declare -a MYCMAKEOPTS - - MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" - -DHIP_COMMON_DIR="$HIP_DIR" - -DHIP_PLATFORM=amd - -DHIP_COMPILER=clang - -DCMAKE_HIP_ARCHITECTURES=OFF - -DCLR_BUILD_HIP=ON -DCLR_BUILD_OCL=ON - -DHIPCC_BIN_DIR="$BUILD_DIR/build/hipcc" - -DROCM_PATH="$ROCM_PATH" - -DBUILD_ICD=ON) - - # If this machine does not have an actvie amd GPU, tell hipamd - # to use first in GFXLIST or gfx90a if no GFXLIST - if [ -f "$LLVM_INSTALL_LOC/bin/amdgpu-arch" ] ; then - if ! "$LLVM_INSTALL_LOC/bin/amdgpu-arch" >/dev/null; then - if [ -n "$GFXLIST" ] ; then - amdgpu=$(echo "$GFXLIST" | cut -d" " -f1) - else - amdgpu=gfx90a - fi - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" "-DOFFLOAD_ARCH_STR=$amdgpu") - fi - fi +task_precheck() { + [[ ! -d $HIPAMD_DIR ]] && echo "ERROR: Missing $HIPAMD_DIR" && exit 1 + [[ ! -d $HIP_DIR ]] && echo "ERROR: Missing $HIP_DIR" && exit 1 + [[ ! -d $ROCclr_DIR ]] && echo "ERROR: Missing $ROCclr_DIR" && exit 1 + [[ ! -d $OPENCL_DIR ]] && echo "ERROR: Missing $OPENCL_DIR" && exit 1 - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - ASAN_FLAGS=("${ASAN_FLAGS[@]}" -I"$SANITIZER_COMGR_INCLUDE_PATH" -Wno-error=deprecated-declarations) - ASAN_CMAKE_OPTS=("${MYCMAKEOPTS[@]}" "${AOMP_ASAN_ORIGIN_RPATH[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BUILD_DIR/build/hipamd/opencl/khronos/icd" - -DCMAKE_INSTALL_LIBDIR=lib/asan - -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - -DHIP_LLVM_ROOT="$LLVM_INSTALL_LOC") - fi + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" + return 0 +} - if [ "$AOMP_BUILD_DEBUG" == 1 ]; then - HIPAMD_DEBUG_CMAKE_OPTS=("${MYCMAKEOPTS[@]}" - "${AOMP_DEBUG_ORIGIN_RPATH[@]}" - -DCMAKE_BUILD_TYPE=DEBUG - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BUILD_DIR/build/hipamd/opencl/khronos/icd" - -DCMAKE_INSTALL_LIBDIR=lib-debug - -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - -DHIP_LLVM_ROOT="$LLVM_INSTALL_LOC") - fi +task_patch() { + patchrepo "$_repos/hipamd" + patchrepo "$_repos/clr" +} - HIPAMD_CMAKE_OPTS=("${MYCMAKEOPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BUILD_DIR/build/hipamd/opencl/khronos/icd" - -DCMAKE_INSTALL_LIBDIR=lib - -DCMAKE_CXX_FLAGS=-I"${AOMP_INSTALL_DIR}/include/amd_comgr" - -DCMAKE_CXX_FLAGS=-Wno-error=deprecated-declarations - -DCMAKE_C_FLAGS=-Wno-error=deprecated-declarations - -DHIP_LLVM_ROOT="$LLVM_INSTALL_LOC" - "${AOMP_ORIGIN_RPATH[@]}") - - echo "mkdir -p $BUILD_DIR/build/hipamd" - mkdir -p "$BUILD_DIR/build/hipamd" - echo "cd $BUILD_DIR/build/hipamd" - cd "$BUILD_DIR/build/hipamd" || exit - echo - echo " -----Running hipamd cmake ---- " - echo "${AOMP_CMAKE}" "${HIPAMD_CMAKE_OPTS[@]}" "$HIPAMD_DIR" - - if ! ${AOMP_CMAKE} "${HIPAMD_CMAKE_OPTS[@]}" "$HIPAMD_DIR"; then - echo "ERROR hipamd cmake failed. Cmake flags" - echo " $(shquot "${HIPAMD_CMAKE_OPTS[@]}")" - exit 1 - fi +task_unpatch() { + removepatch "$_repos/hipamd" + removepatch "$_repos/clr" +} - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - export ROCM_RPATH="$AOMP_ORIGIN_RPATH_LIST" - echo "mkdir -p $BUILD_DIR/build/hipamd/asan" - mkdir -p "$BUILD_DIR/build/hipamd/asan" - echo "cd $BUILD_DIR/build/hipamd/asan" - cd "$BUILD_DIR/build/hipamd/asan" || exit - echo - echo " -----Running hipamd-asan cmake -----" - echo "${AOMP_CMAKE}" "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_CXX_FLAGS=\""$(cmquot "${ASAN_FLAGS[@]}")\"" - "$HIPAMD_DIR" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - "$HIPAMD_DIR"; then - echo "ERROR hipamd-asan cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - if [ "$AOMP_BUILD_DEBUG" == 1 ]; then - if [ -d "$BUILD_DIR/build/hipamd_debug" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/hipamd_debug" - rm -rf "$BUILD_DIR/build/hipamd_debug" - fi - - echo "mkdir -p $BUILD_DIR/build/hipamd_debug" - mkdir -p "$BUILD_DIR/build/hipamd_debug" - echo "cd $BUILD_DIR/build/hipamd_debug" - cd "$BUILD_DIR/build/hipamd_debug" || exit - echo - echo " -----Running hipamd-debug cmake -----" - _prefix_map=(-fdebug-prefix-map="$HIPAMD_DIR=$_ompd_src_dir/clr") - echo "${AOMP_CMAKE}" "${HIPAMD_DEBUG_CMAKE_OPTS[@]}" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot -g "${_prefix_map[@]}")\"" \ - -DCMAKE_C_FLAGS="\"$(cmquot -g "${_prefix_map[@]}")\"" \ - "$HIPAMD_DIR" - - if ! ${AOMP_CMAKE} "${HIPAMD_DEBUG_CMAKE_OPTS[@]}" \ - -DCMAKE_CXX_FLAGS="$(cmquot -g "${_prefix_map[@]}")" \ - -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")" \ - "$HIPAMD_DIR"; then - echo "ERROR hipamd-debug cmake failed. Cmake flags" - echo " $(shquot "${HIPAMD_DEBUG_CMAKE_OPTS[@]}")" - exit 1 - fi - fi -fi +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} -if [ "$1" = "cmake" ]; then - exit 0 -fi +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local BuildRoot + local Gfx + local amdgpu + local -a MYCMAKEOPTS + local -a CMAKEOPTS + local -a _flags + local -a _prefix_map + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + BuildRoot="$(cfgvar BUILD_DIR)" + Gfx="$(cfgvar GFXLIST)" + + # Settings common to every config. + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DHIP_COMMON_DIR="$HIP_DIR" + -DHIP_PLATFORM=amd + -DHIP_COMPILER=clang + -DCMAKE_HIP_ARCHITECTURES=OFF + -DCLR_BUILD_HIP=ON -DCLR_BUILD_OCL=ON + -DHIPCC_BIN_DIR="$BuildRoot/hipcc" + -DROCM_PATH="$ROCM_PATH" + -DBUILD_ICD=ON) + + # If this machine does not have an active amd GPU, tell hipamd + # to use first in GFXLIST or gfx90a if no GFXLIST + if [ -f "$LLVM_INSTALL_LOC/bin/amdgpu-arch" ] ; then + if ! "$LLVM_INSTALL_LOC/bin/amdgpu-arch" >/dev/null; then + if [ -n "$Gfx" ] ; then + amdgpu=$(echo "$Gfx" | cut -d" " -f1) + else + amdgpu=gfx90a + fi + MYCMAKEOPTS+=("-DOFFLOAD_ARCH_STR=$amdgpu") + fi + fi -cd "$BUILD_DIR/build/hipamd" || exit + # Variant-specific settings. + if asan_config "$Cfg"; then + _flags=("${ASAN_FLAGS[@]}" -I"$SANITIZER_COMGR_INCLUDE_PATH" -Wno-error=deprecated-declarations) + export ROCM_RPATH="$AOMP_ORIGIN_RPATH_LIST" + CMAKEOPTS=("${MYCMAKEOPTS[@]}" + "${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" + -DCMAKE_INSTALL_LIBDIR=lib/asan + -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DHIP_LLVM_ROOT="$LLVM_INSTALL_LOC" + -DCMAKE_CXX_FLAGS="$(cmquot "${_flags[@]}")") + elif debug_config "$Cfg"; then + _prefix_map=(-fdebug-prefix-map="$HIPAMD_DIR=$_ompd_src_dir/clr") + CMAKEOPTS=("${MYCMAKEOPTS[@]}" + "${AOMP_DEBUG_ORIGIN_RPATH[@]}" + -DCMAKE_BUILD_TYPE=DEBUG + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" + -DCMAKE_INSTALL_LIBDIR=lib-debug + -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DHIP_LLVM_ROOT="$LLVM_INSTALL_LOC" + -DCMAKE_CXX_FLAGS="$(cmquot -g "${_prefix_map[@]}")" + -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")") + else + CMAKEOPTS=("${MYCMAKEOPTS[@]}" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" + -DCMAKE_INSTALL_LIBDIR=lib + -DCMAKE_CXX_FLAGS=-I"${AOMP_INSTALL_DIR}/include/amd_comgr" + -DCMAKE_CXX_FLAGS=-Wno-error=deprecated-declarations + -DCMAKE_C_FLAGS=-Wno-error=deprecated-declarations + -DHIP_LLVM_ROOT="$LLVM_INSTALL_LOC" + "${AOMP_ORIGIN_RPATH[@]}") + fi -echo -echo " -----Running make for hipamd ---- " + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running hipamd $Cfg cmake ---- " + echo "$AompCmake $(shquot "${CMAKEOPTS[@]}") $SrcDir" -if ! make -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_DIR/build/hipamd" - echo " make " + if ! "$AompCmake" "${CMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR hipamd $Cfg cmake failed. Cmake flags" + echo " $(shquot "${CMAKEOPTS[@]}")" exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install hipamd component run this command:" - echo " $0 install" - echo - fi -fi - -if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/hipamd/asan" || exit - echo - echo " -----Running make for hipamd-asan ----- " + fi + popd >& /dev/null || exit +} - if ! make -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd restart:" - echo " make " - exit 1 - else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install hipamd-asan component run this command:" - echo " $0 install" - echo - fi +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + local -a MakeArgs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + # The debug config only builds the amdhip64 target. + MakeArgs=(-j "$Jobs") + if debug_config "$Cfg"; then + MakeArgs+=(amdhip64) fi -fi -if [ "$AOMP_BUILD_DEBUG" == 1 ] ; then - cd "$BUILD_DIR/build/hipamd_debug" || exit - echo - echo " -----Running make for hipamd-debug ----- " - if ! make -j "$AOMP_JOB_THREADS" amdhip64; then + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for hipamd $Cfg ---- " + echo "make ${MakeArgs[*]}" + if ! make "${MakeArgs[@]}"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd restart:" + echo " cd $BuildDir" echo " make " exit 1 - else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install hipamd-debug component run this command:" - echo " $0 install" - echo - fi fi -fi - -function edit_installed_hip_file(){ - local installed_file_to_edit="$1" - if [ -f "$installed_file_to_edit" ] ; then - # In hipvars.pm HIP_PATH is determined by parent directory of hipcc location. - # Set ROCM_PATH using HIP_PATH - $SUDO sed -i -e "s/\"\/opt\/rocm\"/\"\$HIP_PATH\"/" "$installed_file_to_edit" - # Set HIP_CLANG_PATH using ROCM_PATH/bin - $SUDO sed -i -e "s/\"\$ROCM_PATH\/llvm\/bin\"/\"\$ROCM_PATH\/bin\"/" "$installed_file_to_edit" - fi + popd >& /dev/null || exit } -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/hipamd" || exit - echo - echo " -----Installing to $AOMP_INSTALL_DIR ----- " +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + if asan_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib/asan ----- " + elif debug_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib-debug ----- " + else + echo " -----Installing to $InstallDir ----- " + fi + echo "$SUDO make install " if ! $SUDO make install; then echo "ERROR make install failed " exit 1 fi + popd >& /dev/null || exit +} - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/hipamd/asan" || exit - echo - echo " -----Installing to $AOMP_INSTALL_DIR/lib/asan" +task_postinstall() { + local Cfg=$1 - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - fi - if [ "$AOMP_BUILD_DEBUG" == 1 ] ; then - cd "$BUILD_DIR/build/hipamd_debug" || exit - echo - echo " -----Installing to $AOMP_INSTALL_DIR/lib-debug" - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi + if debug_config "$Cfg"; then + # copy hipamd sources into the installation for runtime source debugging $SUDO mkdir -p "$_ompd_src_dir" - echo "cp -r $HIPAMD_DIR/hipamd $_ompd_src_dir" + echo "cp -r $HIPAMD_DIR/hipamd $_ompd_src_dir" $SUDO cp -r "$HIPAMD_DIR/hipamd" "$_ompd_src_dir" - echo "cp -r $HIPAMD_DIR/opencl $_ompd_src_dir" + echo "cp -r $HIPAMD_DIR/opencl $_ompd_src_dir" $SUDO cp -r "$HIPAMD_DIR/opencl" "$_ompd_src_dir" - echo cp -r "$HIPAMD_DIR/rocclr" "$_ompd_src_dir" + echo "cp -r $HIPAMD_DIR/rocclr $_ompd_src_dir" $SUDO cp -r "$HIPAMD_DIR/rocclr" "$_ompd_src_dir" + return 0 fi - removepatch "$AOMP_REPOS/hipamd" - removepatch "$AOMP_REPOS/clr" - - # The hip perl scripts have /opt/rocm hardcoded, so fix them after then are installed - # but only if not installing to rocm. + # The hip perl scripts have /opt/rocm hardcoded, so fix them after they are + # installed but only if not installing to rocm. if [ "$AOMP_INSTALL_DIR" != "/opt/rocm/llvm" ] ; then edit_installed_hip_file "$AOMP_INSTALL_DIR/bin/hipcc" edit_installed_hip_file "$AOMP_INSTALL_DIR/bin/hipvars.pm" # nothing to change in hipconfig but in case something is added in future, try to fix it edit_installed_hip_file "$AOMP_INSTALL_DIR/bin/hipconfig" fi -fi +} + +do_list_configs() { + echo "default" + if "$(cfgbool AOMP_BUILD_SANITIZER)"; then + echo "asan" + fi + if "$(cfgbool AOMP_BUILD_DEBUG)"; then + echo "debug" + fi +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + case "$Cfg" in + default|debug) + echo "postinstall" + ;; + *) + ;; + esac + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 9a428cb5877a73f97af93dd36dae381a0308c01e Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:29:28 -0500 Subject: [PATCH 24/71] Taskify build_hipify.sh Convert build_hipify.sh to the taskified build pattern with a single (default) config and no patching. The inline install-dir writability check is replaced by check_writable_installdir in task_precheck. Route the user-controllable INSTALL_HIPIFY through cfgvar and add it to the aomp_utils allowlist. --- bin/aomp_utils | 3 +- bin/build_hipify.sh | 233 +++++++++++++++++++++++++++++--------------- 2 files changed, 155 insertions(+), 81 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index a053c95b0b..4750946a28 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -300,7 +300,8 @@ get_config_var_string() { AOMP_CLANGXX_COMPILER|AOMP_ROCT_REPO_NAME|INSTALL_ROCT|\ AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY|\ AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ - AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC) + AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ + INSTALL_HIPIFY) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_hipify.sh b/bin/build_hipify.sh index a925bcab1d..c87de223c3 100755 --- a/bin/build_hipify.sh +++ b/bin/build_hipify.sh @@ -23,20 +23,30 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -HIPIFY_REPO_DIR=$AOMP_REPOS/hipify - -BUILD_DIR=${BUILD_AOMP} +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string hipify "$1" +} -BUILDTYPE="Release" +cfgbool() { + get_config_var_bool hipify "$1" +} INSTALL_HIPIFY=${INSTALL_HIPIFY:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/hipify" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -45,92 +55,155 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_hipify.sh nocmake NO cmake, make, NO install " echo " ./build_hipify.sh install NO Cmake, make install " echo " " - exit -fi - -if [ ! -d "$HIPIFY_REPO_DIR" ] ; then - echo "ERROR: Missing repository $HIPIFY_REPO_DIR/" - exit 1 -fi - -if [ ! -f "$LLVM_INSTALL_LOC"/bin/clang ] ; then - echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" - echo " Build and install the AOMP clang compiler in $AOMP first" - echo " This is needed to build hipify " - echo " " - exit 1 + exit 0 fi -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p "$INSTALL_HIPIFY" - if ! $SUDO touch "$INSTALL_HIPIFY"/testfile; then - echo "ERROR: No update access to $INSTALL_HIPIFY" +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/hipify" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_HIPIFY +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" exit 1 fi - $SUDO rm "$INSTALL_HIPIFY"/testfile -fi - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - - if [ -d "$BUILD_DIR"/build/hipify ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/hipify" - rm -rf "$BUILD_DIR"/build/hipify - fi - declare -a MYCMAKEOPTS - - MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILDTYPE" - -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" - -DCMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC" - -DHIPIFY_INSTALL_CLANG_HEADERS=OFF - -DLLVM_EXTERNAL_LIT="$LLVM_INSTALL_LOC/bin/llvm-lit") - - mkdir -p "$BUILD_DIR"/build/hipify - cd "$BUILD_DIR"/build/hipify || exit + if [ ! -f "$LLVM_INSTALL_LOC"/bin/clang ] ; then + echo "ERROR: Missing file $LLVM_INSTALL_LOC/bin/clang" + echo " Build and install the AOMP clang compiler in $AOMP first" + echo " This is needed to build hipify " + echo " " + exit 1 + fi - echo - echo " -----Running cmake ---- " - echo "${AOMP_CMAKE}" "${MYCMAKEOPTS[@]}" "$HIPIFY_REPO_DIR" - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$HIPIFY_REPO_DIR"; then - echo "ERROR hipify cmake failed. Cmake flags" + check_writable_installdir "$1" "$(cfgvar INSTALL_HIPIFY)" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC" + -DHIPIFY_INSTALL_CLANG_HEADERS=OFF + -DLLVM_EXTERNAL_LIT="$LLVM_INSTALL_LOC/bin/llvm-lit") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for hipify $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR hipify $Cfg cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_DIR"/build/hipify || exit -echo -echo " -----Running make for hipify ---- " -if ! make -j "$AOMP_JOB_THREADS"; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for hipify $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/hipify" + echo " cd $BuildDir" echo " make " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install hipify component run this command:" - echo " $0 install" - echo + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" fi -fi +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR"/build/hipify || exit - echo - echo " -----Installing to $INSTALL_HIPIFY ----- " - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi -fi +command_dispatcher "$@" From f44cb3e76b752ee6ee3e87fd1b42a1d18de79125 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:31:30 -0500 Subject: [PATCH 25/71] Taskify build_hipfort.sh Convert build_hipfort.sh to the taskified build pattern with a single (default) config and patch/unpatch tasks. Route the user-controllable HIPFORT_INSTALL_DIR through cfgvar and add it to the aomp_utils allowlist. --- bin/aomp_utils | 2 +- bin/build_hipfort.sh | 250 +++++++++++++++++++++++++++++-------------- 2 files changed, 171 insertions(+), 81 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 4750946a28..d4e25382b8 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -301,7 +301,7 @@ get_config_var_string() { AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY|\ AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ - INSTALL_HIPIFY) + INSTALL_HIPIFY|HIPFORT_INSTALL_DIR) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_hipfort.sh b/bin/build_hipfort.sh index 58522ae753..4410491657 100755 --- a/bin/build_hipfort.sh +++ b/bin/build_hipfort.sh @@ -27,16 +27,30 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -REPO_DIR=$AOMP_REPOS/hipfort -BUILD_DIR=${BUILD_AOMP} +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string hipfort "$1" +} + +cfgbool() { + get_config_var_bool hipfort "$1" +} + HIPFORT_INSTALL_DIR=${HIPFORT_INSTALL_DIR:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/hipfort" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -45,92 +59,168 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_hipfort.sh nocmake NO cmake, make, NO install " echo " ./build_hipfort.sh install NO Cmake, make install " echo " " - exit -fi - -if [ ! -d "$REPO_DIR" ] ; then - echo "ERROR: Missing repository $REPO_DIR/" - exit 1 + exit 0 fi -if [ ! -f "$AOMP/bin/clang" ] ; then - if [ ! -f "$AOMP/lib/llvm/bin/clang" ] ; then - echo "ERROR: Missing file $AOMP/lib/llvm/bin/clang" - echo " " +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/hipfort" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar HIPFORT_INSTALL_DIR +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" exit 1 - fi -fi - -check_writable_installdir "$1" "$HIPFORT_INSTALL_DIR" - -patchrepo "$AOMP_REPOS/hipfort" + fi -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ -d "$BUILD_DIR/build/hipfort" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/hipfort" - rm -rf "$BUILD_DIR/build/hipfort" - fi - - declare -a MYCMAKEOPTS - - MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$HIPFORT_INSTALL_DIR" - -DCMAKE_BUILD_TYPE=Release - -DHIPFORT_COMPILER="$LLVM_INSTALL_LOC/bin/flang" - -DHIPFORT_COMPILER_FLAGS="-cpp" - -DCMAKE_Fortran_FLAGS_DEBUG="" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" - -DHIPFORT_AR="$LLVM_INSTALL_LOC/bin/llvm-ar" - -DHIPFORT_RANLIB="$LLVM_INSTALL_LOC/bin/llvm-ranlib") - - mkdir -p "$BUILD_DIR/build/hipfort" - cd "$BUILD_DIR/build/hipfort" || exit - echo - echo " -----Running hipfort cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" -DCMAKE_Fortran_FLAGS=\"-ffree-form -fPIC\" "$REPO_DIR" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - -DCMAKE_Fortran_FLAGS="-ffree-form -fPIC" \ - "$REPO_DIR"; then - echo "ERROR hipfort cmake failed. Cmake flags" + if [ ! -f "$AOMP/bin/clang" ] ; then + if [ ! -f "$AOMP/lib/llvm/bin/clang" ] ; then + echo "ERROR: Missing file $AOMP/lib/llvm/bin/clang" + echo " " + exit 1 + fi + fi + + check_writable_installdir "$1" "$(cfgvar HIPFORT_INSTALL_DIR)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$(cfgvar HIPFORT_INSTALL_DIR)" + -DCMAKE_BUILD_TYPE=Release + -DHIPFORT_COMPILER="$LLVM_INSTALL_LOC/bin/flang" + -DHIPFORT_COMPILER_FLAGS="-cpp" + -DCMAKE_Fortran_FLAGS_DEBUG="" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" + -DHIPFORT_AR="$LLVM_INSTALL_LOC/bin/llvm-ar" + -DHIPFORT_RANLIB="$LLVM_INSTALL_LOC/bin/llvm-ranlib" + -DCMAKE_Fortran_FLAGS="-ffree-form -fPIC") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running hipfort $Cfg cmake ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR hipfort $Cfg cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_DIR/build/hipfort" || exit -echo -echo " -----Running make for hipfort ---- " - -if ! make -j "$AOMP_JOB_THREADS"; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for hipfort $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/hipfort" + echo " cd $BuildDir" echo " make " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install hipfort component run this command:" - echo " $0 install" - echo + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" fi -fi +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/hipfort" || exit - echo - echo " -----Installing to $HIPFORT_INSTALL_DIR ----- " - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - removepatch "$AOMP_REPOS/hipfort" -fi +command_dispatcher "$@" From 79280bb8e4fa19035f1317ad76dc8ba51cb764b2 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:40:35 -0500 Subject: [PATCH 26/71] Taskify build_openmp.sh Convert build_openmp.sh (the legacy openmp-subdir build) to the taskified pattern, mirroring build_offload.sh. Variants use composite config names (default/asan/perf/perf+asan/debug/debug+asan) gated by AOMP_LEGACY_OPENMP/SANITIZER/AOMP_BUILD_PERF/DEBUG/SANITIZER. The former recursive self-invocation for the device runtime library pass is now modeled as a parallel set of "-devicertl" configs that build in the openmp-devicertl directory with the amdgcn default target triple, so a full run builds the host variants first and then the devicertl variants. The debug source-copy runs as the host debug config's postinstall. Route the user-controllable OPENMP_BUILD_DIR and ALTAOMP through cfgvar and add them to the aomp_utils allowlist. --- bin/aomp_utils | 2 +- bin/build_openmp.sh | 987 ++++++++++++++++++++++---------------------- 2 files changed, 498 insertions(+), 491 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index d4e25382b8..c73cc1a461 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -301,7 +301,7 @@ get_config_var_string() { AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY|\ AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ - INSTALL_HIPIFY|HIPFORT_INSTALL_DIR) + INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_openmp.sh b/bin/build_openmp.sh index 547c50840c..411c577a6e 100755 --- a/bin/build_openmp.sh +++ b/bin/build_openmp.sh @@ -4,276 +4,330 @@ # This script will install in location defined by AOMP env variable # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string openmp "$1" +} + +cfgbool() { + get_config_var_bool openmp "$1" +} + if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME _ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" -_ompd_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd" -OPENMP_BUILD_DEVICERTL=${OPENMP_BUILD_DEVICERTL:-0} OPENMP_BUILD_DIR=${OPENMP_BUILD_DIR:-"openmp"} +ALTAOMP=${ALTAOMP:-$LLVM_INSTALL_LOC} -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - CUDAH=$(find "$CUDAT" -type f,l -name "cuda.h" 2>/dev/null) - if [ "$CUDAH" == "" ] ; then - CUDAH=$(find "$CUDAINCLUDE" -type f,l -name "cuda.h" 2>/dev/null) +get_src_dir() { + echo "$REPO_DIR/openmp" +} + +# Return success if the config is a "device runtime library" pass, which builds +# the same set of variants in a separate build directory with the amdgcn +# default target triple. +devicertl_config() { + local Cfg=$1 + case "$Cfg" in + *-devicertl) + return 0 + ;; + *) + ;; + esac + return 1 +} + +asan_config() { + local Cfg=${1%-devicertl} + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} + +debug_config() { + local Cfg=${1%-devicertl} + case "$Cfg" in + debug|debug+*) + return 0 + ;; + *) + ;; + esac + return 1 +} + +perf_config() { + local Cfg=${1%-devicertl} + case "$Cfg" in + perf|perf+*) + return 0 + ;; + *) + ;; + esac + return 1 +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local Base=${Cfg%-devicertl} + local BuildDir + local DirBase + BuildDir="$(cfgvar BUILD_DIR)" + + if devicertl_config "$Cfg"; then + DirBase="openmp-devicertl" + else + DirBase="$(cfgvar OPENMP_BUILD_DIR)" fi - if [ "$CUDAH" == "" ] ; then - echo - echo "ERROR: THE cuda.h FILE WAS NOT FOUND WITH ARCH $AOMP_PROC" - echo " A CUDA installation is necessary to build libomptarget deviceRTLs" - echo " Please install CUDA to build openmp" - echo + + case "$Base" in + "default") + echo -n "$BuildDir/$DirBase" + ;; + "asan") + echo -n "$BuildDir/$DirBase/asan" + ;; + "perf") + echo -n "$BuildDir/${DirBase}_perf" + ;; + "perf+asan") + echo -n "$BuildDir/${DirBase}_perf/asan" + ;; + "debug") + echo -n "$BuildDir/${DirBase}_debug" + ;; + "debug+asan") + echo -n "$BuildDir/${DirBase}_debug/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$LLVM_INSTALL_LOC" +} + +# Print the LLVM_LIBDIR_SUFFIX for a given config. +libdir_suffix() { + local Cfg=${1%-devicertl} + case "$Cfg" in + default) + ;; + asan) + printf "%s" "/asan" + ;; + perf) + printf "%s" "-perf" + ;; + perf+asan) + printf "%s" "-perf/asan" + ;; + debug) + printf "%s" "-debug" + ;; + debug+asan) + printf "%s" "-debug/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +task_precheck() { + local SrcDir + local CUDAH + local CUDAVER + local CUDATop + local CUDAInclude + local CUDABin + local AOMPProc + + SrcDir="$(get_src_dir)" + + if [ ! -d "$REPO_DIR" ] ; then + echo "ERROR: Missing repository $REPO_DIR " + echo " Consider setting env variables AOMP_REPOS and/or AOMP_PROJECT_REPO_NAME " exit 1 fi - # I don't see now nvcc is called, but this eliminates the deprecated warnings - export CUDAFE_FLAGS="-w" -fi -if [ ! -d "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_PROJECT_REPO_NAME " - echo " Consider setting env variables AOMP_REPOS and/or AOMP_PROJECT_REPO_NAME " - exit 1 -fi + check_writable_installdir "$1" "$LLVM_INSTALL_LOC" -check_writable_installdir "$1" "$LLVM_INSTALL_LOC" + if "$(cfgbool AOMP_BUILD_CUDA)"; then + CUDATop=$(cfgvar CUDAT) + CUDAH=$(find "$CUDATop" -type f,l -name "cuda.h" 2>/dev/null) + if [ "$CUDAH" == "" ] ; then + CUDAInclude=$(cfgvar CUDAINCLUDE) + CUDAH=$(find "$CUDAInclude" -type f,l -name "cuda.h" 2>/dev/null) + fi + if [ "$CUDAH" == "" ] ; then + AOMPProc=$(cfgvar AOMP_PROC) + echo + echo "ERROR: THE cuda.h FILE WAS NOT FOUND WITH ARCH $AOMPProc" + echo " A CUDA installation is necessary to build libomptarget deviceRTLs" + echo " Please install CUDA to build openmp" + echo + exit 1 + fi + # I don't see now nvcc is called, but this eliminates the deprecated warnings + export CUDAFE_FLAGS="-w" -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - if [ -f "$CUDABIN/nvcc" ] ; then - CUDAVER=$("$CUDABIN"/nvcc --version | grep compilation | cut -d" " -f5 | cut -d"." -f1) - echo "CUDA VERSION IS $CUDAVER" + CUDABin=$(cfgvar CUDABIN) + if [ -f "$CUDABin/nvcc" ] ; then + CUDAVER=$("$CUDABin"/nvcc --version | grep compilation | cut -d" " -f5 | cut -d"." -f1) + echo "CUDA VERSION IS $CUDAVER" + fi fi -fi - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN=() -else - AOMP_SET_NINJA_GEN=(-G Ninja) -fi - -export LLVM_DIR=$AOMP_INSTALL_DIR -GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') -ALTAOMP=${ALTAOMP:-$LLVM_INSTALL_LOC} -declare -a COMMON_CMAKE_OPTS -COMMON_CMAKE_OPTS=("${AOMP_SET_NINJA_GEN[@]}" -DOPENMP_ENABLE_LIBOMPTARGET=1 - -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" - -DOPENMP_TEST_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DOPENMP_TEST_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - -DCMAKE_C_COMPILER="$ALTAOMP/bin/clang" - -DCMAKE_CXX_COMPILER="$ALTAOMP/bin/clang++" - -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" - -DDEVICELIBS_ROOT="$DEVICELIBS_ROOT" - -DLIBOMP_COPY_EXPORTS=OFF - -DLIBOMPTARGET_ENABLE_DEBUG=ON - -DLIBOMPTEST_INSTALL_COMPONENTS=ON - -DLLVM_DIR="$LLVM_DIR") - -if [ "$OPENMP_BUILD_DEVICERTL" -eq 1 ]; then - if [ -f "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/device/CMakeLists.txt" ]; then - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_DEFAULT_TARGET_TRIPLE=amdgcn-amd-amdhsa) - fi -fi - -if [ "$AOMP_STANDALONE_BUILD" == 0 ]; then - # For static package builds, set BUILD_SHARED_LIBS to OFF - if [ "$STATIC_PKG_DEPS" == "ON" ]; then - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" -DBUILD_SHARED_LIBS=OFF) - fi - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_MAIN_INCLUDE_DIR="$LLVM_PROJECT_ROOT/llvm/include" - -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$LLVM_PROJECT_ROOT/llvm/include" - -DROCM_DIR="$ROCM_DIR" - -DAOMP_STANDALONE_BUILD="$AOMP_STANDALONE_BUILD") -else - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_MAIN_INCLUDE_DIR="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/include" - -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/include" - -DLIBOMP_USE_HWLOC=ON - -DLIBOMP_HWLOC_INSTALL_DIR="$AOMP_SUPP/hwloc") -fi - -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLIBOMPTARGET_NVPTX_ENABLE_BCLIB=ON - -DLIBOMPTARGET_NVPTX_CUDA_COMPILER="$AOMP/bin/clang++" - -DLIBOMPTARGET_NVPTX_BC_LINKER="$AOMP/bin/llvm-link" - -DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES="$NVPTXGPUS") -else -# Need to force CUDA off this way in case cuda is installed in this system - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCUDA_TOOLKIT_ROOT_DIR=OFF) -fi - -#if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - #LDFLAGS=$(shquot '-fuse-ld=lld' "${ASAN_FLAGS[@]}") - #export LDFLAGS -#fi - -# This is how we tell the hsa plugin where to find hsa -export HSA_RUNTIME_PATH=$ROCM_DIR - -#breaks build as it cant find rocm-path -#export HIP_DEVICE_LIB_PATH=$ROCM_DIR/lib - -# Patch llvm-project with ATD patch customized for amd-staging. -# WARNING: This patch (ATD_ASO_full.patch) rarely applies cleanly -# because of its size and constant trunk merges to amd-staging. -# This is why default is 0 (OFF). -if [ "$AOMP_APPLY_ATD_AMD_STAGING_PATCH" == 1 ] ; then - patchrepo "$REPO_DIR" -fi + return 0 +} + +task_patch() { + # Patch llvm-project with ATD patch customized for amd-staging. + # WARNING: This patch (ATD_ASO_full.patch) rarely applies cleanly + # because of its size and constant trunk merges to amd-staging. + # This is why default is 0 (OFF). + if "$(cfgbool AOMP_APPLY_ATD_AMD_STAGING_PATCH)" ; then + patchrepo "$REPO_DIR" + fi +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/openmp." - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - echo "rm -rf $BUILD_DIR/build/$OPENMP_BUILD_DIR" - rm -rf "$BUILD_DIR/build/$OPENMP_BUILD_DIR" - declare -a MYCMAKEOPTS - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" - -DCMAKE_BUILD_TYPE=Release - "${AOMP_ORIGIN_RPATH[@]}") - else - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$INSTALL_PREFIX/lib/cmake" - -DCMAKE_BUILD_TYPE=Release - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - - # XXX: Crude way to detect if we should enable building the mod files with flang. - # Is it preferrable to set it from the outside or based on branch name, some other in-tree file? - AOMP_BUILD_MODFILES_WITH_FLANG_NEW=0 - if [ -e "${LLVM_INSTALL_LOC}/bin/flang" ]; then - AOMP_BUILD_MODFILES_WITH_FLANG_NEW=1 - fi - - if [ "$AOMP_BUILD_MODFILES_WITH_FLANG_NEW" == 1 ]; then - echo "Building .mod files via: $LLVM_INSTALL_LOC/bin/flang" - echo "Installing .mod files to: $LLVM_INSTALL_LOC/include/flang/" - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" - -DLIBOMP_FORTRAN_MODULES_COMPILER="$LLVM_INSTALL_LOC/bin/flang" - -DLIBOMP_MODULES_INSTALL_PATH="$LLVM_INSTALL_LOC/include/flang/") - fi +task_unpatch() { + if "$(cfgbool AOMP_APPLY_ATD_AMD_STAGING_PATCH)" ; then + removepatch "$REPO_DIR" + fi +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local SrcDir + local BuildDir + local AompCmake + local UseNinja + local Standalone + local GFXSEMICOLONS + local LibdirSuffix + local -a AOMP_SET_NINJA_GEN + local -a MYCMAKEOPTS + local -a DEBUGCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + UseNinja="$(cfgbool AOMP_USE_NINJA)" + Standalone="$(cfgbool AOMP_STANDALONE_BUILD)" + + if "$UseNinja"; then + AOMP_SET_NINJA_GEN=(-G Ninja) fi - if [ "$AOMP_LEGACY_OPENMP" == "1" ] && [ "$SANITIZER" != 1 ]; then - echo " -----Running openmp cmake ---- " - mkdir -p "$BUILD_DIR/build/$OPENMP_BUILD_DIR" - cd "$BUILD_DIR/build/$OPENMP_BUILD_DIR" || exit - echo "${AOMP_CMAKE}" "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp"; then - echo "ERROR openmp cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 + export LLVM_DIR=$AOMP_INSTALL_DIR + GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') + + # This is how we tell the hsa plugin where to find hsa + export HSA_RUNTIME_PATH=$ROCM_DIR + + # Settings common to every config. + MYCMAKEOPTS=("${AOMP_SET_NINJA_GEN[@]}" + -DOPENMP_ENABLE_LIBOMPTARGET=1 + -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" + -DOPENMP_TEST_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DOPENMP_TEST_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DCMAKE_C_COMPILER="$ALTAOMP/bin/clang" + -DCMAKE_CXX_COMPILER="$ALTAOMP/bin/clang++" + -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" + -DDEVICELIBS_ROOT="$DEVICELIBS_ROOT" + -DLIBOMP_COPY_EXPORTS=OFF + -DLIBOMPTARGET_ENABLE_DEBUG=ON + -DLIBOMPTEST_INSTALL_COMPONENTS=ON + -DLLVM_DIR="$LLVM_DIR") + + # The device runtime library pass builds for the amdgcn default triple. + if devicertl_config "$Cfg"; then + if [ -f "$REPO_DIR/openmp/device/CMakeLists.txt" ]; then + MYCMAKEOPTS+=(-DLLVM_DEFAULT_TARGET_TRIPLE=amdgcn-amd-amdhsa) fi fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - declare -a ASAN_CMAKE_OPTS - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake/AMDDeviceLibs" - -DSANITIZER_AMDGPU=1 -DCMAKE_BUILD_TYPE=Release - "${AOMP_ASAN_ORIGIN_RPATH[@]}") - else - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH" - -DSANITIZER_AMDGPU=1 -DCMAKE_BUILD_TYPE=Release - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - fi - echo " -----Running openmp cmake for asan ---- " - mkdir -p "$BUILD_DIR/build/$OPENMP_BUILD_DIR/asan" - cd "$BUILD_DIR/build/$OPENMP_BUILD_DIR/asan" || exit - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DLLVM_LIBDIR_SUFFIX="/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DLLVM_LIBDIR_SUFFIX="/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp"; then - echo "ERROR openmp cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - - # Build a dedicatd "performance" version of libomptarget - if [ "$AOMP_BUILD_PERF" == "1" ]; then - echo "rm -rf $BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf" - rm -rf "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" -DLIBOMPTARGET_ENABLE_DEBUG=OFF - -DCMAKE_BUILD_TYPE=Release -DLIBOMPTARGET_PERF=ON - -DLLVM_LIBDIR_SUFFIX=-perf) - mkdir -p "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf" - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf" || exit - echo " -----Running openmp cmake for perf ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" \ - "$(shquot "${AOMP_ORIGIN_RPATH[@]}")" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" \ - "${AOMP_ORIGIN_RPATH[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp"; then - echo "error openmp cmake failed. cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - declare -a ASAN_CMAKE_OPTS - ASAN_CMAKE_OPTS=("${MYCMAKEOPTS[@]}" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DSANITIZER_AMDGPU=1) - echo " -----Running openmp cmake for perf-asan ---- " - mkdir -p "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf/asan" - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf/asan" || exit - echo "${AOMP_CMAKE}" "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake/AMDDeviceLibs" \ - "${AOMP_ASAN_ORIGIN_RPATH[@]}" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DLLVM_LIBDIR_SUFFIX="-perf/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake/AMDDeviceLibs" \ - "${AOMP_ASAN_ORIGIN_RPATH[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DLLVM_LIBDIR_SUFFIX="-perf/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp"; then - echo "error openmp cmake failed. cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - fi - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - echo "rm -rf $BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug" - rm -rf "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug" + if ! "$Standalone"; then + # For static package builds, set BUILD_SHARED_LIBS to OFF + if [ "$STATIC_PKG_DEPS" == "ON" ]; then + MYCMAKEOPTS+=(-DBUILD_SHARED_LIBS=OFF) + fi + MYCMAKEOPTS+=(-DLLVM_MAIN_INCLUDE_DIR="$LLVM_PROJECT_ROOT/llvm/include" + -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$LLVM_PROJECT_ROOT/llvm/include" + -DROCM_DIR="$ROCM_DIR" + -DAOMP_STANDALONE_BUILD="$(cfgvar AOMP_STANDALONE_BUILD)") + else + MYCMAKEOPTS+=(-DLLVM_MAIN_INCLUDE_DIR="$REPO_DIR/llvm/include" + -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$REPO_DIR/llvm/include" + -DLIBOMP_USE_HWLOC=ON + -DLIBOMP_HWLOC_INSTALL_DIR="$AOMP_SUPP/hwloc") + fi - declare -a DEBUGCMAKEOPTS + if "$(cfgbool AOMP_BUILD_CUDA)"; then + MYCMAKEOPTS+=(-DLIBOMPTARGET_NVPTX_ENABLE_BCLIB=ON + -DLIBOMPTARGET_NVPTX_CUDA_COMPILER="$AOMP/bin/clang++" + -DLIBOMPTARGET_NVPTX_BC_LINKER="$AOMP/bin/llvm-link" + -DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES="$NVPTXGPUS") + else + # Need to force CUDA off this way in case cuda is installed in this system + MYCMAKEOPTS+=(-DCUDA_TOOLKIT_ROOT_DIR=OFF) + fi + # Variant-specific settings. + if perf_config "$Cfg"; then + MYCMAKEOPTS+=(-DLIBOMPTARGET_ENABLE_DEBUG=OFF + -DCMAKE_BUILD_TYPE=Release + -DLIBOMPTARGET_PERF=ON) + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF + -DSANITIZER_AMDGPU=1 + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake/AMDDeviceLibs" + "${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" + "${AOMP_ORIGIN_RPATH[@]}") + fi + elif debug_config "$Cfg"; then DEBUGCMAKEOPTS=(-DLIBOMPTARGET_NVPTX_DEBUG=ON -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=Debug @@ -284,283 +338,236 @@ if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then -DLIBOMP_CPPFLAGS='-O0' -DLIBOMP_OMPD_SUPPORT=ON -DLIBOMP_OMPT_DEBUG=ON - -DOPENMP_SOURCE_DEBUG_MAP="-fdebug-prefix-map=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp=$_ompd_src_dir/openmp") + -DOPENMP_SOURCE_DEBUG_MAP="-fdebug-prefix-map=$REPO_DIR/openmp=$_ompd_src_dir/openmp") # The 'pip install --system' command is not supported on non-debian systems. This will disable # the system option if the debian_version file is not present. if [ ! -f /etc/debian_version ]; then echo "==> Non-Debian OS, disabling use of pip install --system" - DEBUGCMAKEOPTS=("${DEBUGCMAKEOPTS[@]}" -DDISABLE_SYSTEM_NON_DEBIAN=1) + DEBUGCMAKEOPTS+=(-DDISABLE_SYSTEM_NON_DEBIAN=1) fi # Redhat 7.6 does not have python36-devel package, which is needed for ompd compilation. # This is acquired through RH Software Collections. if [ -f /opt/rh/rh-python36/enable ]; then echo "==> Using python3.6 out of rh tools." - DEBUGCMAKEOPTS=("${DEBUGCMAKEOPTS[@]}" -DPython3_ROOT_DIR=/opt/rh/rh-python36/root/bin -DPYTHON_HEADERS=/opt/rh/rh-python36/root/usr/include/python3.6m) + DEBUGCMAKEOPTS+=(-DPython3_ROOT_DIR=/opt/rh/rh-python36/root/bin + -DPYTHON_HEADERS=/opt/rh/rh-python36/root/usr/include/python3.6m) fi - if [ "$SANITIZER" != 1 ]; then - echo - echo " -----Running openmp cmake for debug ---- " - mkdir -p "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug" - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug" || exit - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - PREFIX_PATH="-DCMAKE_PREFIX_PATH=$AOMP_INSTALL_DIR/lib/cmake" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - "${AOMP_DEBUG_ORIGIN_RPATH[@]}") + MYCMAKEOPTS+=("${DEBUGCMAKEOPTS[@]}") + + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF + -DSANITIZER_AMDGPU=1) + if "$Standalone"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake/AMDDeviceLibs" + "${AOMP_ASAN_ORIGIN_RPATH[@]}") else - PREFIX_PATH="-DCMAKE_PREFIX_PATH=$INSTALL_PREFIX/lib/cmake" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - fi - echo "${AOMP_CMAKE}" "${MYCMAKEOPTS[@]}" "$PREFIX_PATH" \ - -DCMAKE_C_FLAGS="$CFLAGS -g" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -g" \ - -DLLVM_LIBDIR_SUFFIX=-debug \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$PREFIX_PATH" \ - -DCMAKE_C_FLAGS="$CFLAGS -g" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -g" \ - -DLLVM_LIBDIR_SUFFIX=-debug \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp"; then - echo "ERROR openmp debug cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - declare -a ASAN_CMAKE_OPTS - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DSANITIZER_AMDGPU=1) - echo " -----Running openmp cmake for debug-asan ---- " - mkdir -p "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug/asan" - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug/asan" || exit - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake/AMDDeviceLibs" - "${AOMP_ASAN_ORIGIN_RPATH[@]}") + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + else + if "$Standalone"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" + "${AOMP_DEBUG_ORIGIN_RPATH[@]}") else - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH" - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$INSTALL_PREFIX/lib/cmake" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DLLVM_LIBDIR_SUFFIX="-debug/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DLLVM_LIBDIR_SUFFIX="-debug/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp"; then - echo "ERROR openmp debug cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -if [ "$1" != "install" ] ; then -if [ "$AOMP_LEGACY_OPENMP" == "1" ] && [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/$OPENMP_BUILD_DIR" || exit - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/$OPENMP_BUILD_DIR ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_DIR/build/$OPENMP_BUILD_DIR" - echo " $AOMP_NINJA_BIN" - exit 1 - fi -fi - -if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/$OPENMP_BUILD_DIR/asan" || exit - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/$OPENMP_BUILD_DIR/asan ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo " " - echo "ERROR: $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_DIR/build/$OPENMP_BUILD_DIR/asan" - echo " $AOMP_NINJA_BIN" - exit 1 - fi -fi - -if [ "$AOMP_BUILD_PERF" == "1" ] ; then - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf ---- " - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf/asan" || exit - echo - echo - echo " ----- Running $AOMP_NINJA_BIN for $BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf/asan ----- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$CFLAGS -g" + -DCMAKE_CXX_FLAGS="$CXXFLAGS -g") fi - fi -fi - -if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - if [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 + elif asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF + -DSANITIZER_AMDGPU=1 + -DCMAKE_BUILD_TYPE=Release) + if "$Standalone"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake/AMDDeviceLibs" + "${AOMP_ASAN_ORIGIN_RPATH[@]}") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi - fi - - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug/asan" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug/asan ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + else + MYCMAKEOPTS+=(-DCMAKE_BUILD_TYPE=Release) + if "$Standalone"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake" + "${AOMP_ORIGIN_RPATH[@]}") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$INSTALL_PREFIX/lib/cmake" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") + # XXX: Crude way to detect if we should enable building the mod files with flang. + if [ -e "${LLVM_INSTALL_LOC}/bin/flang" ]; then + echo "Building .mod files via: $LLVM_INSTALL_LOC/bin/flang" + echo "Installing .mod files to: $LLVM_INSTALL_LOC/include/flang/" + MYCMAKEOPTS+=(-DLIBOMP_FORTRAN_MODULES_COMPILER="$LLVM_INSTALL_LOC/bin/flang" + -DLIBOMP_MODULES_INSTALL_PATH="$LLVM_INSTALL_LOC/include/flang/") + fi fi fi -fi - - echo - echo "Successful build of ./build_openmp.sh . Please run:" - echo " ./build_openmp.sh install " - echo -fi - -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - if [ "$AOMP_LEGACY_OPENMP" == "1" ] && [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/$OPENMP_BUILD_DIR" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib ----- " - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi + # libdir suffix options + LibdirSuffix=$(libdir_suffix "$Cfg") + if [ -n "$LibdirSuffix" ]; then + MYCMAKEOPTS+=(-DLLVM_LIBDIR_SUFFIX="$LibdirSuffix") fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/$OPENMP_BUILD_DIR/asan" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib/asan ----- " + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running openmp $Cfg cmake ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR openmp $Cfg cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 fi - - if [ "$AOMP_BUILD_PERF" == "1" ]; then - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib-perf ----- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - # FIXME: llvm_dylib is not set anywhere! - #if [ ! -h "$AOMP_INSTALL_DIR/lib-perf/$llvm_dylib" ] && [ "$llvm_dylib" != "" ]; then - # cd "$AOMP_INSTALL_DIR/lib-perf" || exit - # ln -s "../lib/$llvm_dylib" "$llvm_dylib" - #fi - - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_perf/asan" || exit - echo - echo " ----- Installing to $LLVM_INSTALL_LOC/lib-perf/asan ----- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local NinjaBin + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + NinjaBin="$(cfgvar AOMP_NINJA_BIN)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $NinjaBin for $BuildDir ---- " + if ! $NinjaBin -j "$Jobs"; then + echo " " + echo "ERROR: $NinjaBin -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" + echo " $NinjaBin" + exit 1 fi - - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - if [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib-debug ---- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - # FIXME: llvm_dylib is not set anywhere! - #if [ ! -h "$AOMP_INSTALL_DIR/lib-debug/$llvm_dylib" ] && [ "$llvm_dylib" != "" ]; then - # cd "$AOMP_INSTALL_DIR/lib-debug" || exit - # ln -s "../lib/$llvm_dylib" "$llvm_dylib" - #fi - fi - - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/${OPENMP_BUILD_DIR}_debug/asan" || exit - echo " -----Installing to $LLVM_INSTALL_LOC/lib-debug/asan ---- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - fi - - if [[ "$DEVEL_PACKAGE" =~ "devel" ]]; then - AOMP_INSTALL_DIR="$AOMP_INSTALL_DIR/""$DEVEL_PACKAGE" - echo "Request for devel package found." - fi - - # Copy selected debugable runtime sources into the installation $ompd_src_dir/src directory - # to satisfy the above -fdebug-prefix-map. - $SUDO mkdir -p "$_ompd_src_dir/openmp/runtime" - $SUDO mkdir -p "$_ompd_src_dir/openmp/libompd" - $SUDO mkdir -p "$_ompd_src_dir/openmp/device" - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - $SUDO cp -rp "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/runtime/src" "$_ompd_src_dir/openmp/runtime" - $SUDO cp -rp "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/libompd/src" "$_ompd_src_dir/openmp/libompd" - $SUDO cp -rp "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/device/src" "$_ompd_src_dir/openmp/device" - else - $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/runtime/src" "$_ompd_src_dir/openmp/runtime" - $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/libompd/src" "$_ompd_src_dir/openmp/libompd" - $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/device/src" "$_ompd_src_dir/openmp/device" - fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local NinjaBin + local Jobs + local LibdirSuffix + BuildDir="$(get_build_dir "$Cfg")" + NinjaBin="$(cfgvar AOMP_NINJA_BIN)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + LibdirSuffix=$(libdir_suffix "$Cfg") + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $LLVM_INSTALL_LOC/lib${LibdirSuffix} ----- " + + if ! $SUDO "$NinjaBin" -j "$Jobs" install; then + echo "ERROR $NinjaBin install failed " + exit 1 fi - - if [ "$AOMP_APPLY_ATD_AMD_STAGING_PATCH" == 1 ] ; then - removepatch "$REPO_DIR" + popd >& /dev/null || exit +} + +task_postinstall() { + local Cfg=$1 + local Standalone + Standalone="$(cfgbool AOMP_STANDALONE_BUILD)" + + # Copy selected debugable runtime sources into the installation + # $_ompd_src_dir directory to satisfy the above -fdebug-prefix-map. + $SUDO mkdir -p "$_ompd_src_dir/openmp/runtime" + $SUDO mkdir -p "$_ompd_src_dir/openmp/libompd" + $SUDO mkdir -p "$_ompd_src_dir/openmp/device" + if "$Standalone"; then + $SUDO cp -rp "$REPO_DIR/openmp/runtime/src" "$_ompd_src_dir/openmp/runtime" + $SUDO cp -rp "$REPO_DIR/openmp/libompd/src" "$_ompd_src_dir/openmp/libompd" + $SUDO cp -rp "$REPO_DIR/openmp/device/src" "$_ompd_src_dir/openmp/device" + else + $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/runtime/src" "$_ompd_src_dir/openmp/runtime" + $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/libompd/src" "$_ompd_src_dir/openmp/libompd" + $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/device/src" "$_ompd_src_dir/openmp/device" fi +} + +do_list_configs() { + local Sanitizer + local LegacyOpenMP + local BuildSanitizer + local BuildPerf + local BuildDebug + local -a cfgs + local c + + Sanitizer="$(cfgbool SANITIZER)" + LegacyOpenMP="$(cfgbool AOMP_LEGACY_OPENMP)" + BuildSanitizer="$(cfgbool AOMP_BUILD_SANITIZER)" + BuildPerf="$(cfgbool AOMP_BUILD_PERF)" + BuildDebug="$(cfgbool AOMP_BUILD_DEBUG)" + + cfgs=() + if ! "$Sanitizer" && "$LegacyOpenMP" ; then + cfgs+=("default") + fi + if "$BuildSanitizer"; then + cfgs+=("asan") + fi + if "$BuildPerf"; then + cfgs+=("perf") + if "$BuildSanitizer"; then + cfgs+=("perf+asan") + fi + fi + if "$BuildDebug" ; then + if ! "$Sanitizer"; then + cfgs+=("debug") + fi + if "$BuildSanitizer"; then + cfgs+=("debug+asan") + fi + fi -fi + # First build/install every variant in the host build dir, then repeat the + # whole set as a device runtime library pass in the openmp-devicertl dir. + for c in "${cfgs[@]}"; do + echo "$c" + done + for c in "${cfgs[@]}"; do + echo "$c-devicertl" + done +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + case "$Cfg" in + debug) + echo "postinstall" + ;; + *) + ;; + esac + else + echo "Unknown config '$Cfg'" + fi +} -if [ "$1" != "install" ] && [ "$OPENMP_BUILD_DEVICERTL" == 0 ] ; then - OPENMP_BUILD_DIR="openmp-devicertl" OPENMP_BUILD_DEVICERTL=1 $thisdir/build_openmp.sh -fi -if [ "$1" == "install" ] && [ "$OPENMP_BUILD_DEVICERTL" == 0 ]; then - OPENMP_BUILD_DIR="openmp-devicertl" OPENMP_BUILD_DEVICERTL=1 $thisdir/build_openmp.sh install -fi +command_dispatcher "$@" From 5ba1e7b0c936b298cf93b4d56e0fe97dac7eef0a Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 08:46:02 -0500 Subject: [PATCH 27/71] Taskify build_llvm-classic.sh Convert build_llvm-classic.sh to the taskified build pattern with a single (default) config that is built but not installed (clean/cmake/ build only, ninja). The early skip when flang-classic sources are absent is preserved as a top-level guard; AOMP_BUILD_FLANG_CLASSIC is computed by aomp_common_vars so it is read directly rather than via cfgbool. Route the user-controllable AOMP_LFL_DIR and AOMP_FLANG_REPO_NAME through cfgvar and add them to the aomp_utils allowlist. --- bin/aomp_utils | 3 +- bin/build_llvm-classic.sh | 273 ++++++++++++++++++++++++-------------- 2 files changed, 175 insertions(+), 101 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index c73cc1a461..ef7ff0967f 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -301,7 +301,8 @@ get_config_var_string() { AOMP_RINFO_REPO_NAME|INSTALL_RINFO|INSTALL_XIO|INSTALL_EMISSARY|\ AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ - INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP) + INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP|\ + AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_llvm-classic.sh b/bin/build_llvm-classic.sh index cc319e978a..330a02c568 100755 --- a/bin/build_llvm-classic.sh +++ b/bin/build_llvm-classic.sh @@ -13,50 +13,28 @@ # These libs/headers are not installed and will picked up from the build # tree for flang-classic. # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -if [ "$AOMP_BUILD_FLANG_CLASSIC" == 0 ] ; then - if [ "$1" != "install" ] ; then - echo "WARNING: ROCM install for $AOMP_FLANG_CLASSIC_REL/llvm-classic not found." - echo " This build will skip build of flang-classic." - echo " The flang will link to the clang driver." - fi - exit -fi -TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string llvm-classic "$1" +} -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN=() -else - AOMP_SET_NINJA_GEN=(-G Ninja) -fi -osversion=$(grep -e ^VERSION_ID < /etc/os-release) -if [[ $osversion =~ \"7\. ]] || [[ $osversion =~ \"8\. ]]; then - _cxx_flag=(-DCMAKE_CXX_FLAGS='-D_GLIBCXX_USE_CXX11_ABI=0') -else - _cxx_flag=() -fi - -# Legacy Flang dosen't support building of compiler-rt so it -# utilizes the clang runtime libraries build/install using build_project.sh. -# The LLVM_VERSION_MAJOR of classic flang driver has to match with the clang -# binaries generated from build_project.sh. -LLVM_VERSION_MAJOR=$("${LLVM_INSTALL_LOC}"/bin/clang --version | grep -oP '(?<=clang version )[0-9]+') - -# We need a version of ROCM llvm that supports flang-classic -# via the link from flang to clang. rocm 5.5 would be best. -# This will enable removal of flang-classic driver support -# from clang to make way for flang. - -# Options for llvm-classic cmake. -TARGETS_TO_BUILD="AMDGPU;X86" +cfgbool() { + get_config_var_bool llvm-classic "$1" +} # Do not change the AOMP_LFL_DIR default because it is the subdirectory # from where we build the flang-classic driver binary. This is the @@ -65,85 +43,180 @@ TARGETS_TO_BUILD="AMDGPU;X86" # AOMP_LFL_DIR to "/" would build flang-classic with the original # ROCm 5.6 sources. AOMP_LFL_DIR=${AOMP_LFL_DIR:-"17.0-4"} -# comment out above line and uncomment next line for new LFL -#AOMP_LFL_DIR=${AOMP_LFL_DIR:-17.0-4} - -declare -a LLVMCMAKEOPTS - -LLVMCMAKEOPTS=(-DLLVM_ENABLE_PROJECTS=clang - -DCMAKE_BUILD_TYPE=Release - -DLLVM_ENABLE_ASSERTIONS=ON - -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" - -DCLANG_DEFAULT_LINKER=lld - -DLLVM_VERSION_MAJOR="$LLVM_VERSION_MAJOR" - -DLLVM_INCLUDE_BENCHMARKS=0 - -DLLVM_INCLUDE_RUNTIMES=0 - -DLLVM_INCLUDE_EXAMPLES=0 - -DLLVM_INCLUDE_TESTS=0 - -DLLVM_INCLUDE_DOCS=0 - -DLLVM_INCLUDE_UTILS=0 - -DCLANG_DEFAULT_PIE_ON_LINUX=0 - -DLLVM_ENABLE_ZSTD=OFF - "${_cxx_flag[@]}" - "${AOMP_SET_NINJA_GEN[@]}") + +# AOMP_BUILD_FLANG_CLASSIC is computed by aomp_common_vars (from the presence +# of the llvm-classic source), not a user-controllable variable, so it is read +# directly rather than through cfgbool. +if [ "$AOMP_BUILD_FLANG_CLASSIC" == 0 ] ; then + if [ "$1" != "install" ] ; then + echo "WARNING: ROCM install for $AOMP_FLANG_CLASSIC_REL/llvm-classic not found." + echo " This build will skip build of flang-classic." + echo " The flang will link to the clang driver." + fi + exit 0 +fi if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi -if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then - if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 +get_src_dir() { + echo "$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_FLANG_REPO_NAME)/flang-classic/$(cfgvar AOMP_LFL_DIR)/llvm-classic/llvm" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/flang-classic/$(cfgvar AOMP_LFL_DIR)/llvm-classic" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. llvm-classic is not +# installed; its libs/headers are picked up from the build tree. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +task_precheck() { + if [ "$(cfgbool AOMP_STANDALONE_BUILD)" == "true" ] ; then + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" + exit 1 + fi fi -fi -check_writable_installdir "$1" "$AOMP_INSTALL_DIR" - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - rm -rf "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR/llvm-classic" - mkdir -p "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" - mkdir -p "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR/llvm-classic" -else - if [ ! -d "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR does not exist" - echo " run $0 without nocmake or install options. " - exit 1 + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local SrcDir + local BuildDir + local AompCmake + local UseNinja + local LLVM_VERSION_MAJOR + local osversion + local TARGETS_TO_BUILD + local -a AOMP_SET_NINJA_GEN + local -a _cxx_flag + local -a LLVMCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + UseNinja="$(cfgbool AOMP_USE_NINJA)" + + if "$UseNinja"; then + AOMP_SET_NINJA_GEN=(-G Ninja) fi -fi -# Cmake for llvm classic (ROCm 5.5). -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - cd "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR/llvm-classic" || exit - echo " -----Running cmake ---- " - echo "${AOMP_CMAKE}" "${LLVMCMAKEOPTS[@]}" "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME/flang-classic/$AOMP_LFL_DIR/llvm-classic/llvm" + osversion=$(grep -e ^VERSION_ID < /etc/os-release) + if [[ $osversion =~ \"7\. ]] || [[ $osversion =~ \"8\. ]]; then + _cxx_flag=(-DCMAKE_CXX_FLAGS='-D_GLIBCXX_USE_CXX11_ABI=0') + fi - if ! ${AOMP_CMAKE} "${LLVMCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME/flang-classic/$AOMP_LFL_DIR/llvm-classic/llvm" 2>&1; then + # Legacy Flang dosen't support building of compiler-rt so it + # utilizes the clang runtime libraries build/install using build_project.sh. + # The LLVM_VERSION_MAJOR of classic flang driver has to match with the clang + # binaries generated from build_project.sh. + LLVM_VERSION_MAJOR=$("${LLVM_INSTALL_LOC}"/bin/clang --version | grep -oP '(?<=clang version )[0-9]+') + + TARGETS_TO_BUILD="AMDGPU;X86" + + LLVMCMAKEOPTS=(-DLLVM_ENABLE_PROJECTS=clang + -DCMAKE_BUILD_TYPE=Release + -DLLVM_ENABLE_ASSERTIONS=ON + -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" + -DCLANG_DEFAULT_LINKER=lld + -DLLVM_VERSION_MAJOR="$LLVM_VERSION_MAJOR" + -DLLVM_INCLUDE_BENCHMARKS=0 + -DLLVM_INCLUDE_RUNTIMES=0 + -DLLVM_INCLUDE_EXAMPLES=0 + -DLLVM_INCLUDE_TESTS=0 + -DLLVM_INCLUDE_DOCS=0 + -DLLVM_INCLUDE_UTILS=0 + -DCLANG_DEFAULT_PIE_ON_LINUX=0 + -DLLVM_ENABLE_ZSTD=OFF + "${_cxx_flag[@]}" + "${AOMP_SET_NINJA_GEN[@]}") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running llvm-classic $Cfg cmake ---- " + echo "$AompCmake $(shquot "${LLVMCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${LLVMCMAKEOPTS[@]}" "$SrcDir" 2>&1; then echo "ERROR cmake failed. Cmake flags" echo " $(shquot "${LLVMCMAKEOPTS[@]}")" exit 1 fi echo -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -# Build llvm classic. -echo " --- Running $AOMP_NINJA_BIN for $BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR/llvm-classic ---- " -cd "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR/llvm-classic" || exit - -if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local NinjaBin + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + NinjaBin="$(cfgvar AOMP_NINJA_BIN)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " --- Running $NinjaBin for $BuildDir ---- " + if ! $NinjaBin -j "$Jobs"; then echo " " - echo "ERROR: $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: $NinjaBin -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR/llvm-classic" - echo " $AOMP_NINJA_BIN" + echo " cd $BuildDir" + echo " $NinjaBin" exit 1 -fi + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. llvm-classic is built but not installed. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From c4483e639c50764a65b3200a83c742ea484f3633 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:00:11 -0500 Subject: [PATCH 28/71] Taskify build_flang-classic.sh Convert build_flang-classic.sh to the taskified build pattern with a single (default) config. task_clean preserves the shared llvm-classic subdir (built first by build_llvm-classic.sh), and install uses cmake --build --target install. The flang-classic enable guard is kept at the top (AOMP_BUILD_FLANG_CLASSIC is computed, read directly). No new cfgvar allowlist entries are required. --- bin/build_flang-classic.sh | 289 +++++++++++++++++++++++-------------- 1 file changed, 184 insertions(+), 105 deletions(-) diff --git a/bin/build_flang-classic.sh b/bin/build_flang-classic.sh index b656ef4b51..68ff588189 100755 --- a/bin/build_flang-classic.sh +++ b/bin/build_flang-classic.sh @@ -13,40 +13,28 @@ # These libs/headers are not installed and will picked up from the build # tree for flang-classic. # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -if [ "$AOMP_BUILD_FLANG_CLASSIC" == 0 ] ; then - if [ "$1" != "install" ] ; then - echo "WARNING: ROCM install for $AOMP_FLANG_CLASSIC_REL/llvm-classic not found." - echo " This build will skip build of flang-classic." - echo " The flang will link to the clang driver." - fi - exit -fi - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN=() -else - AOMP_SET_NINJA_GEN=(-G Ninja) -fi -osversion=$(grep -e ^VERSION_ID < /etc/os-release) -if [[ $osversion =~ \"7\. ]] || [[ $osversion =~ \"8\. ]]; then - _cxx_flag=(-DCMAKE_CXX_FLAGS='-D_GLIBCXX_USE_CXX11_ABI=0') -else - _cxx_flag=() -fi +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string flang-classic "$1" +} -# We need a version of ROCM llvm that supports flang-classic -# via the link from flang to clang. rocm 5.5 would be best. -# This will enable removal of flang-classic driver support -# from clang to make way for flang +cfgbool() { + get_config_var_bool flang-classic "$1" +} # Do not change the AOMP_LFL_DIR default because it is the subdirectory # from where we build the flang-classic driver binary. This is the @@ -55,111 +43,202 @@ fi # AOMP_LFL_DIR to "/" would build flang-classic with the original # ROCm 5.6 sources. AOMP_LFL_DIR=${AOMP_LFL_DIR:-"17.0-4"} -# comment out above line and uncomment next line for new LFL -#AOMP_LFL_DIR=${AOMP_LFL_DIR:-17.0-4} - -declare -a MYCMAKEOPTS - -MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - "${_cxx_flag[@]}" - -DCMAKE_CXX_STANDARD=17 - -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" - "${AOMP_SET_NINJA_GEN[@]}") - -if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" -DBUILD_SHARED_LIBS=ON - "${AOMP_ORIGIN_RPATH[@]}") -else - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" -DBUILD_SHARED_LIBS=OFF - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") -fi +# AOMP_BUILD_FLANG_CLASSIC is computed by aomp_common_vars (from the presence +# of the llvm-classic source), not a user-controllable variable, so it is read +# directly rather than through cfgbool. +if [ "$AOMP_BUILD_FLANG_CLASSIC" == 0 ] ; then + if [ "$1" != "install" ] ; then + echo "WARNING: ROCM install for $AOMP_FLANG_CLASSIC_REL/llvm-classic not found." + echo " This build will skip build of flang-classic." + echo " The flang will link to the clang driver." + fi + exit 0 +fi if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi -if [ "$AOMP_STANDALONE_BUILD" == 1 ] ; then - if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" +get_src_dir() { + echo "$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_FLANG_REPO_NAME)/flang-classic/$(cfgvar AOMP_LFL_DIR)" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/flang-classic/$(cfgvar AOMP_LFL_DIR)" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +task_precheck() { + if [ "$(cfgbool AOMP_STANDALONE_BUILD)" == "true" ] ; then + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" + exit 1 + fi + fi + + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + + # The flang-classic build dir is shared with llvm-classic (built first by + # build_llvm-classic.sh); remove everything except the llvm-classic subdir. + if [ -d "$BuildDir" ]; then + local Entry + for Entry in "${BuildDir:?}"/* "${BuildDir:?}"/.[!.]*; do + [ -e "$Entry" ] || continue + case "$(basename "$Entry")" in + llvm-classic) ;; + *) echo "rm -rf $Entry"; rm -rf "$Entry" ;; + esac + done + else + echo "ERROR: Build llvm-classic before flang-classic." exit 1 fi -fi +} + +task_cmake() { + local Cfg=$1 + local SrcDir + local BuildDir + local AompCmake + local UseNinja + local Standalone + local osversion + local -a AOMP_SET_NINJA_GEN + local -a _cxx_flag + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + UseNinja="$(cfgbool AOMP_USE_NINJA)" + Standalone="$(cfgbool AOMP_STANDALONE_BUILD)" + + if "$UseNinja"; then + AOMP_SET_NINJA_GEN=(-G Ninja) + fi -check_writable_installdir "$1" "$AOMP_INSTALL_DIR" + osversion=$(grep -e ^VERSION_ID < /etc/os-release) + if [[ $osversion =~ \"7\. ]] || [[ $osversion =~ \"8\. ]]; then + _cxx_flag=(-DCMAKE_CXX_FLAGS='-D_GLIBCXX_USE_CXX11_ABI=0') + fi -# Allow extglobs -- seems like this must be set before bash starts parsing -# the 'if' block below. -shopt -s extglob + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + "${_cxx_flag[@]}" + -DCMAKE_CXX_STANDARD=17 + -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" + "${AOMP_SET_NINJA_GEN[@]}") -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - if [ -d "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" ]; then - # This needs extglob enabled, as set above. - rm -rf "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR"/!("llvm-classic") + if "$Standalone" ; then + MYCMAKEOPTS+=(-DBUILD_SHARED_LIBS=ON "${AOMP_ORIGIN_RPATH[@]}") else - echo "ERROR: Build llvm-classic before flang-classic." - exit 1 - fi -else - if [ ! -d "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR does not exist" - echo " run $0 without nocmake or install options. " - exit 1 + MYCMAKEOPTS+=(-DBUILD_SHARED_LIBS=OFF "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi -fi -echo -# Cmake flang-classic. -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - cd "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" || exit - echo " -----Running cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME/flang-classic/$AOMP_LFL_DIR" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running flang-classic $Cfg cmake ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME/flang-classic/$AOMP_LFL_DIR" 2>&1; then + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir" 2>&1; then echo "ERROR cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -echo - -# Build flang-classic. -echo " --- Running $AOMP_NINJA_BIN for $BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR ---- " -cd "$BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" || exit - -if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local NinjaBin + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + NinjaBin="$(cfgvar AOMP_NINJA_BIN)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " --- Running $NinjaBin for $BuildDir ---- " + if ! $NinjaBin -j "$Jobs"; then echo " " - echo "ERROR: $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: $NinjaBin -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/flang-classic/$AOMP_LFL_DIR" - echo " $AOMP_NINJA_BIN" + echo " cd $BuildDir" + echo " $NinjaBin" exit 1 -fi - -if [ "$1" == "install" ] ; then + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local AompCmake + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit echo " -----Installing to $AOMP_INSTALL_DIR ---- " - - if ! $SUDO "${AOMP_CMAKE}" --build . -j "$AOMP_JOB_THREADS" --target install; then + if ! $SUDO "$AompCmake" --build . -j "$Jobs" --target install; then echo "ERROR make install failed " exit 1 fi echo echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" echo -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 4d8511add30f0dc2050890c820229f58e397c937 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:06:00 -0500 Subject: [PATCH 29/71] Taskify build_flang.sh Convert build_flang.sh to the taskified build pattern with default and asan configs (asan listed when AOMP_BUILD_SANITIZER is set). Common cmake options are factored out and the asan variant adds the sanitizer prefix path, rpath, libdir, and flags. User-controllable variables are routed through cfgvar/cfgbool; INSTALL_FLANG is added to the aomp_utils string allowlist. --- bin/aomp_utils | 2 +- bin/build_flang.sh | 362 +++++++++++++++++++++++++-------------------- 2 files changed, 205 insertions(+), 159 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index ef7ff0967f..d2dc48c5e3 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -302,7 +302,7 @@ get_config_var_string() { AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP|\ - AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME) + AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_flang.sh b/bin/build_flang.sh index 23219d4f51..791dcb5217 100755 --- a/bin/build_flang.sh +++ b/bin/build_flang.sh @@ -3,195 +3,241 @@ # build_flang.sh: Script to build the flang component of the AOMP compiler. # # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string flang "$1" +} + +cfgbool() { + get_config_var_bool flang "$1" +} + INSTALL_FLANG=${INSTALL_FLANG:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_FLANG_REPO_NAME)" +COMP_INC_DIR="$REPO_DIR/runtime/libpgmath/lib/common" if [ "$AOMP_PROC" == "ppc64le" ] ; then TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}PowerPC" +elif [ "$AOMP_PROC" == "aarch64" ] ; then + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64" else - if [ "$AOMP_PROC" == "aarch64" ] ; then - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64" - else - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86" - fi -fi - -REPO_DIR=$AOMP_REPOS/$AOMP_FLANG_REPO_NAME -COMP_INC_DIR=$REPO_DIR/runtime/libpgmath/lib/common - -declare -a MYCMAKEOPTS - -MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" - -DLLVM_ENABLE_ASSERTIONS=ON - -DLLVM_CONFIG="$LLVM_INSTALL_LOC/bin/llvm-config" - -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DCMAKE_Fortran_COMPILER=gfortran - -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" - -DFLANG_OPENMP_GPU_AMD=ON - -DFLANG_OPENMP_GPU_NVIDIA=ON - -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON - -DFLANG_INCLUDE_TESTS=OFF) - -declare -a ASAN_CMAKE_OPTS - -if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - ASAN_FLAGS=("${ASAN_FLAGS[@]}" "-I$COMP_INC_DIR") - ASAN_CMAKE_OPTS=("${MYCMAKEOPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake" - "${AOMP_ASAN_ORIGIN_RPATH[@]}" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DCMAKE_INSTALL_LIBDIR=lib/asan) - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" -DCMAKE_INSTALL_BINDIR=bin/asan) - fi -fi - -if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" "${AOMP_ORIGIN_RPATH[@]}") -else - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86" fi -MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" "-DCMAKE_PREFIX_PATH=$AOMP/lib/cmake") - if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi -check_writable_installdir "$1" "$INSTALL_FLANG" - -# Skip synchronization from git repos if nocmake or install are specified -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/$AOMP_FLANG_REPO_NAME" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - rm -rf "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME" - mkdir -p "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME" - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - mkdir -p "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME/asan" - fi -else - if [ ! -d "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME" ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/$AOMP_FLANG_REPO_NAME does not exist" - echo " run $0 without nocmake or install options. " +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)/$(cfgvar AOMP_FLANG_REPO_NAME)" + + case "$Cfg" in + "default") + echo -n "$BuildDir" + ;; + "asan") + echo -n "$BuildDir/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_FLANG +} + +asan_config() { + local Cfg=$1 + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_FLANG_REPO_NAME set correctly?" exit 1 fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] && [ ! -d "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME/asan" ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/$AOMP_FLANG_REPO_NAME/asan does not exist" - echo " run $0 without nocmake or install options. " - exit 1 - fi -fi -cd "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME" || exit - -# Need llvm-config to come from previous LLVM build -export PATH=$AOMP_INSTALL_DIR/bin:$PATH - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ "$SANITIZER" != 1 ]; then - echo - echo " -----Running cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - -DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - -DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME" 2>&1; then - echo "ERROR cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 + check_writable_installdir "$1" "$(cfgvar INSTALL_FLANG)" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + # Settings common to every config. + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" + -DLLVM_ENABLE_ASSERTIONS=ON + -DLLVM_CONFIG="$LLVM_INSTALL_LOC/bin/llvm-config" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DCMAKE_Fortran_COMPILER=gfortran + -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" + -DFLANG_OPENMP_GPU_AMD=ON + -DFLANG_OPENMP_GPU_NVIDIA=ON + -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON + -DFLANG_INCLUDE_TESTS=OFF) + + # Variant-specific settings. + if asan_config "$Cfg"; then + local -a _asan_flags + _asan_flags=("${ASAN_FLAGS[@]}" "-I$COMP_INC_DIR") + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake" + "${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF + -DCMAKE_INSTALL_LIBDIR=lib/asan) + if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then + MYCMAKEOPTS+=(-DCMAKE_INSTALL_BINDIR=bin/asan) fi - fi - - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - cd "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME/asan" || exit - echo - echo " ----Running cmake for flang-asan ----- " - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$CFLAGS $(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$CXXFLAGS $(cmquot "${ASAN_FLAGS[@]}")\"" \ - "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME" - - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$CFLAGS $(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS $(cmquot "${ASAN_FLAGS[@]}")" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME" 2>&1; then - echo "ERROR flang-asan cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$CFLAGS $(cmquot "${_asan_flags[@]}")" + -DCMAKE_CXX_FLAGS="$CXXFLAGS $(cmquot "${_asan_flags[@]}")") + else + if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then + MYCMAKEOPTS+=("${AOMP_ORIGIN_RPATH[@]}") + else + MYCMAKEOPTS+=("${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP/lib/cmake" + -DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" + -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR") fi -fi -if [ "$1" = "cmake" ]; then - exit 0 -fi + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for flang $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" -echo -if [ "$SANITIZER" != 1 ]; then - echo " ----- Running make ---- " - cd "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME" || exit - echo "make -j $AOMP_JOB_THREADS" - - if ! make -j "$AOMP_JOB_THREADS"; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR flang $Cfg cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi - -if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - cd "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME/asan" || exit - echo - echo " ----- Running make for flang-asan ---- " - echo "make -j $AOMP_JOB_THREADS" - - if ! make -j "$AOMP_JOB_THREADS"; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + # Need llvm-config to come from previous LLVM build + export PATH=$AOMP_INSTALL_DIR/bin:$PATH + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for flang $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then + echo " " + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" + echo " make" exit 1 fi -fi - -if [ "$1" == "install" ] ; then - if [ "$SANITIZER" != 1 ]; then - cd "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME" || exit - echo " -----Installing to $INSTALL_FLANG ---- " + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + if asan_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib/asan ----- " + else + echo " -----Installing to $InstallDir ----- " + fi + echo "$SUDO make install " - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - echo "SUCCESSFUL INSTALL to $INSTALL_FLANG " + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 fi + popd >& /dev/null || exit +} - echo - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - cd "$BUILD_DIR/build/$AOMP_FLANG_REPO_NAME/asan" || exit - echo " -----Installing to $INSTALL_FLANG/lib/asan ---- " +do_list_configs() { + echo "default" + if "$(cfgbool AOMP_BUILD_SANITIZER)"; then + echo "asan" + fi +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - echo "SUCCESSFUL INSTALL to $INSTALL_FLANG/lib/asan" - fi -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi +command_dispatcher "$@" From e52b9c0e9fc35692279cc01bddeea7841ffc15c0 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:09:21 -0500 Subject: [PATCH 30/71] Taskify build_flang_runtime.sh Convert build_flang_runtime.sh to the taskified build pattern with default and asan configs. The openmp runtime source used for OPENMP_BUILD_DIR is computed per config via get_openmp_runtime_src, and the asan variant reproduces the standalone vs non-standalone cmake prefix path, rpath, libdir, and -DSANITIZER handling. User-controllable variables are routed through cfgvar/cfgbool; no new allowlist entries are required. --- bin/build_flang_runtime.sh | 431 +++++++++++++++++++++---------------- 1 file changed, 243 insertions(+), 188 deletions(-) diff --git a/bin/build_flang_runtime.sh b/bin/build_flang_runtime.sh index ab2b2dab96..4b9a5cbb14 100755 --- a/bin/build_flang_runtime.sh +++ b/bin/build_flang_runtime.sh @@ -3,234 +3,289 @@ # build_flang_runtime.sh: Script to build the flang runtime component of the AOMP compiler. # # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string flang_runtime "$1" +} + +cfgbool() { + get_config_var_bool flang_runtime "$1" +} + INSTALL_FLANG=${INSTALL_FLANG:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_FLANG_REPO_NAME)" +COMP_INC_DIR="$REPO_DIR/runtime/libpgmath/lib/common" if [ "$AOMP_PROC" == "ppc64le" ] ; then TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}PowerPC" +elif [ "$AOMP_PROC" == "aarch64" ] ; then + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64" else - if [ "$AOMP_PROC" == "aarch64" ] ; then - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64" - else - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86" - fi + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86" fi -COMP_INC_DIR=$(ls -d "$AOMP_INSTALL_DIR"/lib/llvm/lib/clang/*/include ) +if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then + help_build_aomp +fi -REPO_DIR=$AOMP_REPOS/$AOMP_FLANG_REPO_NAME -COMP_INC_DIR=$REPO_DIR/runtime/libpgmath/lib/common +get_src_dir() { + echo "$REPO_DIR" +} -if [ "$AOMP_STANDALONE_BUILD" == 0 ]; then - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - openmp_build_runtime_src=$BUILD_DIR/build/openmp/asan/runtime/src - CMAKE_PREFIX_PATH=$BUILD_DIR/build/pgmath/asan - else - openmp_build_runtime_src=$BUILD_DIR/build/openmp/runtime/src - CMAKE_PREFIX_PATH=$BUILD_DIR/build/pgmath - fi -else - if [ -d "$BUILD_DIR/build/openmp/runtime/src" ] ; then - openmp_build_runtime_src="$BUILD_DIR/build/openmp/runtime/src" - else - openmp_build_runtime_src="$BUILD_DIR/build/llvm-project/runtimes/runtimes-bins/openmp/runtime/src" - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] && [ -d "$BUILD_DIR/build/openmp/asan/runtime/src" ]; then - openmp_build_runtime_src="$BUILD_DIR/build/openmp/asan/runtime/src" - fi -fi +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)/flang_runtime" -declare -a MYCMAKEOPTS - -MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" - -DLLVM_ENABLE_ASSERTIONS=ON - -DLLVM_CONFIG="$LLVM_INSTALL_LOC/bin/llvm-config" - -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DCMAKE_Fortran_COMPILER="$LLVM_INSTALL_LOC/bin/flang-classic" - -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" - -DLLVM_INSTALL_RUNTIME=ON - -DFLANG_BUILD_RUNTIME=ON - -DOPENMP_BUILD_DIR="$openmp_build_runtime_src" - -DFLANG_INCLUDE_TESTS=OFF) - -# Note this variable is used only for AOMP ASan-ROCm builds don't remove it. -# This is not used for AOMP-ASan standalone build. -if [ "$SANITIZER" == 1 ]; then - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" -DSANITIZER="$SANITIZER") -fi + case "$Cfg" in + "default") + echo -n "$BuildDir" + ;; + "asan") + echo -n "$BuildDir/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} -declare -a ASAN_CMAKE_OPTS +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_FLANG +} -if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - ASAN_FLAGS=("${ASAN_FLAGS[@]}" -I"$COMP_INC_DIR") - ASAN_CMAKE_OPTS=("${MYCMAKEOPTS[@]}" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DCMAKE_INSTALL_BINDIR=bin/asan - -DCMAKE_INSTALL_LIBDIR=lib/asan) - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake;$AOMP/lib/asan" - "${AOMP_ASAN_ORIGIN_RPATH[@]}") +asan_config() { + local Cfg=$1 + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} + +# Print the openmp runtime source directory used to drive OPENMP_BUILD_DIR, +# which depends on the config and on whether this is a standalone build. +get_openmp_runtime_src() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + if [ "$AOMP_STANDALONE_BUILD" == 0 ]; then + if asan_config "$Cfg"; then + echo -n "$BuildDir/openmp/asan/runtime/src" + else + echo -n "$BuildDir/openmp/runtime/src" + fi else - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH;$INSTALL_PREFIX/lib/asan/cmake" - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}" - -DOPENMP_EXTRAS_SHARED_LINKER_FLAGS="$(cmquot "${OPENMP_EXTRAS_SHARED_LINKER_FLAGS[@]}")") + local Src + if [ -d "$BuildDir/openmp/runtime/src" ] ; then + Src="$BuildDir/openmp/runtime/src" + else + Src="$BuildDir/llvm-project/runtimes/runtimes-bins/openmp/runtime/src" + fi + if asan_config "$Cfg" && [ -d "$BuildDir/openmp/asan/runtime/src" ]; then + Src="$BuildDir/openmp/asan/runtime/src" + fi + echo -n "$Src" fi -fi +} -if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP/lib/cmake;$AOMP_INSTALL_DIR/lib" - "${AOMP_ORIGIN_RPATH[@]}") -else - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" - -DCMAKE_PREFIX_PATH="$INSTALL_PREFIX/lib/asan/cmake" - -DOPENMP_EXTRAS_SHARED_LINKER_FLAGS="$(cmquot "${OPENMP_EXTRAS_SHARED_LINKER_FLAGS[@]}")" - -DAOMP_BUILD_SANITIZER="$AOMP_BUILD_SANITIZER" - -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") -fi +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" -if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then - help_build_aomp -fi - -check_writable_installdir "$1" "$INSTALL_FLANG" - -# Skip synchronization from git repos if nocmake or install are specified -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/flang_runtime" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - rm -rf "$BUILD_DIR/build/flang_runtime" - mkdir -p "$BUILD_DIR/build/flang_runtime" - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - mkdir -p "$BUILD_DIR/build/flang_runtime/asan" - fi -else - if [ ! -d "$BUILD_DIR/build/flang_runtime" ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/flang_runtime does not exist" - echo " run $0 without nocmake or install options. " - exit 1 - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] && [ ! -d "$BUILD_DIR/build/flang_runtime/asan" ]; then - echo "ERROR: The build directory $BUILD_DIR/build/flang_runtime/asan does not exist" - echo " run $0 without nocmake or install options. " + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_FLANG_REPO_NAME set correctly?" exit 1 fi -fi -# Need llvm-config to come from previous LLVM build -export PATH="$AOMP_INSTALL_DIR/bin":$PATH -# Old CMAKE uses FC env variable to find fortran compiler -export FC="$AOMP_INSTALL_DIR/bin/flang" - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ "$SANITIZER" != 1 ]; then - cd "$BUILD_DIR/build/flang_runtime" || exit - echo - echo " -----Running cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - -DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - -DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME" 2>&1; then - echo "ERROR cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 + check_writable_installdir "$1" "$(cfgvar INSTALL_FLANG)" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local OpenmpRuntimeSrc + local PgmathPrefix + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + OpenmpRuntimeSrc="$(get_openmp_runtime_src "$Cfg")" + + # Settings common to every config. + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" + -DLLVM_ENABLE_ASSERTIONS=ON + -DLLVM_CONFIG="$LLVM_INSTALL_LOC/bin/llvm-config" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DCMAKE_Fortran_COMPILER="$LLVM_INSTALL_LOC/bin/flang-classic" + -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD" + -DLLVM_INSTALL_RUNTIME=ON + -DFLANG_BUILD_RUNTIME=ON + -DOPENMP_BUILD_DIR="$OpenmpRuntimeSrc" + -DFLANG_INCLUDE_TESTS=OFF) + + # Variant-specific settings. + if asan_config "$Cfg"; then + local -a _asan_flags + _asan_flags=("${ASAN_FLAGS[@]}" -I"$COMP_INC_DIR") + + # Note this variable is used only for AOMP ASan-ROCm builds, don't remove + # it. This is not used for AOMP-ASan standalone build. + if [ "$AOMP_STANDALONE_BUILD" == 0 ]; then + MYCMAKEOPTS+=(-DSANITIZER=1) fi - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - cd "$BUILD_DIR/build/flang_runtime/asan" || exit - echo - echo " -----Running cmake flang_runtime-asan ---- " - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$CFLAGS $(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$CXXFLAGS $(cmquot "${ASAN_FLAGS[@]}")\"" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$CFLAGS $(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS $(cmquot "${ASAN_FLAGS[@]}")" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME" 2>&1; then - echo "ERROR flang_runtime-asan cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 + MYCMAKEOPTS+=(-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF + -DCMAKE_INSTALL_BINDIR=bin/asan + -DCMAKE_INSTALL_LIBDIR=lib/asan) + if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake;$AOMP/lib/asan" + "${AOMP_ASAN_ORIGIN_RPATH[@]}") + else + PgmathPrefix="$(cfgvar BUILD_DIR)/pgmath/asan" + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$PgmathPrefix;$INSTALL_PREFIX/lib/asan/cmake" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}" + -DOPENMP_EXTRAS_SHARED_LINKER_FLAGS="$(cmquot "${OPENMP_EXTRAS_SHARED_LINKER_FLAGS[@]}")") + fi + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$CFLAGS $(cmquot "${_asan_flags[@]}")" + -DCMAKE_CXX_FLAGS="$CXXFLAGS $(cmquot "${_asan_flags[@]}")") + else + if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP/lib/cmake;$AOMP_INSTALL_DIR/lib" + "${AOMP_ORIGIN_RPATH[@]}") + else + PgmathPrefix="$(cfgvar BUILD_DIR)/pgmath" + MYCMAKEOPTS+=(-DOPENMP_EXTRAS_SHARED_LINKER_FLAGS="$(cmquot "${OPENMP_EXTRAS_SHARED_LINKER_FLAGS[@]}")" + -DAOMP_BUILD_SANITIZER="$AOMP_BUILD_SANITIZER" + -DCMAKE_PREFIX_PATH="$PgmathPrefix" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" + -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR") fi -fi -if [ "$1" = "cmake" ]; then - exit 0 -fi - -echo -if [ "$SANITIZER" != 1 ]; then - echo " -----Running make ---- " - cd "$BUILD_DIR/build/flang_runtime" || exit - echo make -j "$AOMP_JOB_THREADS" + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for flang_runtime $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" - if ! make -j "$AOMP_JOB_THREADS"; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR flang_runtime $Cfg cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" -if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - echo - echo " -----Running make ---- " - cd "$BUILD_DIR/build/flang_runtime/asan" || exit - echo make -j "$AOMP_JOB_THREADS" + # Need llvm-config to come from previous LLVM build + export PATH="$AOMP_INSTALL_DIR/bin":$PATH + # Old CMAKE uses FC env variable to find fortran compiler + export FC="$AOMP_INSTALL_DIR/bin/flang" - if ! make -j "$AOMP_JOB_THREADS"; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for flang_runtime $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then + echo " " + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" + echo " make" exit 1 fi -fi + popd >& /dev/null || exit +} -if [ "$1" == "install" ] ; then - if [ "$SANITIZER" != 1 ]; then - cd "$BUILD_DIR/build/flang_runtime" || exit - echo " -----Installing to $INSTALL_FLANG ---- " +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - echo "SUCCESSFUL INSTALL to $INSTALL_FLANG " - echo + pushd "$BuildDir" >& /dev/null || exit + if asan_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib/asan ----- " + else + echo " -----Installing to $InstallDir ----- " fi + echo "$SUDO make install " - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - cd "$BUILD_DIR/build/flang_runtime/asan" || exit - echo " -----Installing to $INSTALL_FLANG/lib/asan ---- " - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - echo "SUCCESSFUL INSTALL to $INSTALL_FLANG/lib/asan " - echo + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 fi -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" + if "$(cfgbool AOMP_BUILD_SANITIZER)"; then + echo "asan" + fi +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From b51b22e904f15a7a004a60bdb800928e176c32c8 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:14:36 -0500 Subject: [PATCH 31/71] Taskify build_pgmath.sh Convert build_pgmath.sh to the taskified build pattern with default and asan configs. Common cmake options keep the ppc64le vs other-arch split, and the asan variant adds the sanitizer prefix path, rpath, bindir, libdir, and flags. COMP_INC_DIR (resolved via ls of the installed clang headers) is computed inside task_cmake so introspection commands work before the compiler is installed. No new allowlist entries are required. --- bin/build_pgmath.sh | 371 +++++++++++++++++++++++++------------------- 1 file changed, 212 insertions(+), 159 deletions(-) diff --git a/bin/build_pgmath.sh b/bin/build_pgmath.sh index ec03dc469d..040cc6e9fc 100755 --- a/bin/build_pgmath.sh +++ b/bin/build_pgmath.sh @@ -3,197 +3,250 @@ # build_pgmath.sh: Script to build the pgmath component of the AOMP compiler. # # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -INSTALL_FLANG=${INSTALL_FLANG:-$AOMP_INSTALL_DIR} - -if [ "$AOMP_PROC" == "ppc64le" ] ; then - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}PowerPC" -else - if [ "$AOMP_PROC" == "aarch64" ] ; then - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64" - else - TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86" - fi -fi +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string pgmath "$1" +} -COMP_INC_DIR=$(ls -d "$AOMP_INSTALL_DIR"/lib/clang/*/include ) +cfgbool() { + get_config_var_bool pgmath "$1" +} -declare -a MYCMAKEOPTS +INSTALL_FLANG=${INSTALL_FLANG:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_FLANG_REPO_NAME)" if [ "$AOMP_PROC" == "ppc64le" ] ; then - MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" - -DLLVM_ENABLE_ASSERTIONS=ON - -DCMAKE_Fortran_COMPILER="$LLVM_INSTALL_LOC/bin/flang" - -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD") -else - MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" - -DLLVM_ENABLE_ASSERTIONS=ON - -DLLVM_CONFIG="$LLVM_INSTALL_LOC/bin/llvm-config" - -DCMAKE_CXX_COMPILER=clang++ - -DCMAKE_C_COMPILER=clang - -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD") -fi - -declare -a ASAN_CMAKE_OPTS - -if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - ASAN_FLAGS=("${ASAN_FLAGS[@]}" "-I$COMP_INC_DIR") - ASAN_CMAKE_OPTS=("${MYCMAKEOPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DCMAKE_INSTALL_BINDIR=bin/asan - -DCMAKE_INSTALL_LIBDIR=lib/asan) - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" "${AOMP_ASAN_ORIGIN_RPATH[@]}") - else - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - fi -fi - -if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" "${AOMP_ORIGIN_RPATH[@]}") + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}PowerPC" +elif [ "$AOMP_PROC" == "aarch64" ] ; then + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}AArch64" else - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") + TARGETS_TO_BUILD="AMDGPU;${AOMP_NVPTX_TARGET}X86" fi -MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" -DCMAKE_PREFIX_PATH="$AOMP/lib/cmake") - if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi -check_writable_installdir "$1" "$INSTALL_FLANG" - -# Skip synchronization from git repos if nocmake or install are specified -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/pgmath" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - rm -rf "$BUILD_DIR/build/pgmath" - mkdir -p "$BUILD_DIR/build/pgmath" - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - mkdir -p "$BUILD_DIR/build/pgmath/asan" - fi -else - if [ ! -d "$BUILD_DIR/build/pgmath" ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/pgmath does not exist" - echo " run $0 without nocmake or install options. " +get_src_dir() { + echo "$REPO_DIR/runtime/libpgmath" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)/pgmath" + + case "$Cfg" in + "default") + echo -n "$BuildDir" + ;; + "asan") + echo -n "$BuildDir/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_FLANG +} + +asan_config() { + local Cfg=$1 + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_FLANG_REPO_NAME set correctly?" exit 1 fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] && [ ! -d "$BUILD_DIR/build/pgmath/asan" ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/pgmath/asan does not exist" - echo " run $0 without nocmake or install options. " - exit 1 - fi -fi -# Need llvm-config to come from previous LLVM build -export PATH="$LLVM_INSTALL_LOC/bin":$PATH - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ "$SANITIZER" != 1 ]; then - echo - cd "$BUILD_DIR/build/pgmath" || exit - echo " -----Running cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - -DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME/runtime/libpgmath" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - -DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME/runtime/libpgmath" 2>&1; then - echo "ERROR cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 - fi + check_writable_installdir "$1" "$(cfgvar INSTALL_FLANG)" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local COMP_INC_DIR + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + COMP_INC_DIR=$(ls -d "$AOMP_INSTALL_DIR"/lib/clang/*/include ) + + # Settings common to every config (architecture dependent). + if [ "$AOMP_PROC" == "ppc64le" ] ; then + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" + -DLLVM_ENABLE_ASSERTIONS=ON + -DCMAKE_Fortran_COMPILER="$LLVM_INSTALL_LOC/bin/flang" + -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD") + else + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" + -DLLVM_ENABLE_ASSERTIONS=ON + -DLLVM_CONFIG="$LLVM_INSTALL_LOC/bin/llvm-config" + -DCMAKE_CXX_COMPILER=clang++ + -DCMAKE_C_COMPILER=clang + -DLLVM_TARGETS_TO_BUILD="$TARGETS_TO_BUILD") fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - echo - cd "$BUILD_DIR/build/pgmath/asan" || exit - echo " -----Running cmake pgmath-asan ---- " - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$CFLAGS $(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$CXXFLAGS $(cmquot "${ASAN_FLAGS[@]}")\"" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME/runtime/libpgmath" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$CFLAGS $(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS $(cmquot "${ASAN_FLAGS[@]}")" \ - "$AOMP_REPOS/$AOMP_FLANG_REPO_NAME/runtime/libpgmath" 2>&1; then - echo "ERROR pgmath-asan cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 + # Variant-specific settings. + if asan_config "$Cfg"; then + local -a _asan_flags + _asan_flags=("${ASAN_FLAGS[@]}" "-I$COMP_INC_DIR") + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP/lib/asan/cmake" + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF + -DCMAKE_INSTALL_BINDIR=bin/asan + -DCMAKE_INSTALL_LIBDIR=lib/asan) + if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then + MYCMAKEOPTS+=("${AOMP_ASAN_ORIGIN_RPATH[@]}") + else + MYCMAKEOPTS+=("${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") + fi + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$CFLAGS $(cmquot "${_asan_flags[@]}")" + -DCMAKE_CXX_FLAGS="$CXXFLAGS $(cmquot "${_asan_flags[@]}")") + else + if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then + MYCMAKEOPTS+=("${AOMP_ORIGIN_RPATH[@]}") + else + MYCMAKEOPTS+=("${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP/lib/cmake" + -DCMAKE_C_FLAGS="$CFLAGS -I$COMP_INC_DIR" + -DCMAKE_CXX_FLAGS="$CXXFLAGS -I$COMP_INC_DIR") fi -fi -if [ "$1" = "cmake" ]; then - exit 0 -fi + # Need llvm-config to come from previous LLVM build + export PATH="$LLVM_INSTALL_LOC/bin":$PATH -if [ "$SANITIZER" != 1 ]; then - echo - cd "$BUILD_DIR/build/pgmath" || exit - echo " -----Running make ---- " - echo make -j "$AOMP_JOB_THREADS" + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for pgmath $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" - if ! make -j "$AOMP_JOB_THREADS"; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR pgmath $Cfg cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi - -if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - echo - cd "$BUILD_DIR/build/pgmath/asan" || exit - echo " -----Running make ---- " - echo "make -j $AOMP_JOB_THREADS" - - if ! make -j "$AOMP_JOB_THREADS"; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + # Need llvm-config to come from previous LLVM build + export PATH="$LLVM_INSTALL_LOC/bin":$PATH + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for pgmath $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then + echo " " + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" + echo " make" exit 1 fi -fi - -if [ "$1" == "install" ] ; then - if [ "$SANITIZER" != 1 ]; then - cd "$BUILD_DIR/build/pgmath" || exit - echo " -----Installing to $INSTALL_FLANG ---- " - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - echo "SUCCESSFUL INSTALL to $INSTALL_FLANG " - echo + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + if asan_config "$Cfg"; then + echo " -----Installing to $InstallDir/lib/asan ----- " + else + echo " -----Installing to $InstallDir ----- " fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - cd "$BUILD_DIR/build/pgmath/asan" || exit - echo " -----Installing to $INSTALL_FLANG/lib/asan ---- " + echo "$SUDO make install " - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - echo "SUCCESSFUL INSTALL to $INSTALL_FLANG/lib/asan" - echo + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 fi -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" + if "$(cfgbool AOMP_BUILD_SANITIZER)"; then + echo "asan" + fi +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 1820fa0db23034311f0e35544105b28d392db7a8 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:20:07 -0500 Subject: [PATCH 32/71] Taskify build_bolt.sh Convert build_bolt.sh to the taskified build pattern with a single (default) config and patch/unpatch init/fini steps. The precheck keeps the bolt repo and AOMP clang existence checks. User-controllable variables are routed through cfgvar/cfgbool; BOLT_INSTALL_DIR is added to the aomp_utils string allowlist. --- bin/aomp_utils | 2 +- bin/build_bolt.sh | 266 +++++++++++++++++++++++++++++++--------------- 2 files changed, 179 insertions(+), 89 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index d2dc48c5e3..c4003f4a1d 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -302,7 +302,7 @@ get_config_var_string() { AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP|\ - AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG) + AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG|BOLT_INSTALL_DIR) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_bolt.sh b/bin/build_bolt.sh index 511791d0a4..715634fb16 100755 --- a/bin/build_bolt.sh +++ b/bin/build_bolt.sh @@ -27,16 +27,30 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -REPO_DIR=$AOMP_REPOS/bolt -BUILD_DIR=${BUILD_AOMP} +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string bolt "$1" +} + +cfgbool() { + get_config_var_bool bolt "$1" +} + BOLT_INSTALL_DIR=${BOLT_INSTALL_DIR:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/bolt" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " @@ -45,99 +59,175 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " ./build_bolt.sh nocmake NO cmake, make, NO install " echo " ./build_bolt.sh install NO Cmake, make install " echo " " - exit -fi - -if [ ! -d "$REPO_DIR" ] ; then - echo "ERROR: Missing repository $REPO_DIR/" - echo " Try these commands till bolt is part of the AOMP manifest:" - echo - echo " cd $AOMP_REPOS" - echo " git clone https://github.com/pmodels/bolt" - echo - exit 1 -fi - -if [ ! -f "$AOMP/bin/clang" ] ; then - echo "ERROR: Missing file $AOMP/bin/clang" - echo " Build the AOMP llvm compiler in $AOMP first" - echo " This is needed to build the bolt libraries" - echo " " - exit 1 + exit 0 fi -check_writable_installdir "$1" "$BOLT_INSTALL_DIR" - -patchrepo "$AOMP_REPOS/bolt" - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - if [ -d "$BUILD_DIR/build/bolt" ] ; then - echo - echo "FRESH START , CLEANING UP FROM PREVIOUS BUILD" - echo "rm -rf $BUILD_DIR/build/bolt" - rm -rf "$BUILD_DIR/build/bolt" - fi +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/bolt" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar BOLT_INSTALL_DIR +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir/" + echo " Try these commands till bolt is part of the AOMP manifest:" + echo + echo " cd $(cfgvar AOMP_REPOS)" + echo " git clone https://github.com/pmodels/bolt" + echo + exit 1 + fi -declare -a MYCMAKEOPTS - -MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$BOLT_INSTALL_DIR" - "${AOMP_ORIGIN_RPATH[@]}" - -DCMAKE_C_COMPILER="$AOMP_CC_COMPILER" - -DCMAKE_CXX_COMPILER="$AOMP_CXX_COMPILER" - -DOPENMP_TEST_C_COMPILER="$AOMP_CC_COMPILER" - -DOPENMP_TEST_CXX_COMPILER="$AOMP_CXX_COMPILER" - -DCMAKE_BUILD_TYPE=Release - -DOPENMP_ENABLE_LIBOMPTARGET=OFF - -DLIBOMP_HEADERS_INSTALL_PATH=include/bolt - -DLIBOMP_INSTALL_ALIASES=OFF - -DLIBOMP_USE_ARGOBOTS=on) - - mkdir -p "$BUILD_DIR/build/bolt" - cd "$BUILD_DIR/build/bolt" || exit - echo - echo " -----Running bolt cmake ---- " - echo "${AOMP_CMAKE} $(shquot "${MYCMAKEOPTS[@]}") $REPO_DIR" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$REPO_DIR"; then - echo "ERROR bolt cmake failed. Cmake flags" + if [ ! -f "$AOMP/bin/clang" ] ; then + echo "ERROR: Missing file $AOMP/bin/clang" + echo " Build the AOMP llvm compiler in $AOMP first" + echo " This is needed to build the bolt libraries" + echo " " + exit 1 + fi + + check_writable_installdir "$1" "$(cfgvar BOLT_INSTALL_DIR)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$(cfgvar BOLT_INSTALL_DIR)" + "${AOMP_ORIGIN_RPATH[@]}" + -DCMAKE_C_COMPILER="$(cfgvar AOMP_CC_COMPILER)" + -DCMAKE_CXX_COMPILER="$(cfgvar AOMP_CXX_COMPILER)" + -DOPENMP_TEST_C_COMPILER="$(cfgvar AOMP_CC_COMPILER)" + -DOPENMP_TEST_CXX_COMPILER="$(cfgvar AOMP_CXX_COMPILER)" + -DCMAKE_BUILD_TYPE=Release + -DOPENMP_ENABLE_LIBOMPTARGET=OFF + -DLIBOMP_HEADERS_INSTALL_PATH=include/bolt + -DLIBOMP_INSTALL_ALIASES=OFF + -DLIBOMP_USE_ARGOBOTS=on) + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for bolt $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR bolt $Cfg cmake failed. Cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 - fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_DIR/build/bolt" || exit -echo -echo " -----Running make for bolt ---- " - -if ! make -j "$AOMP_JOB_THREADS"; then + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for bolt $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/bolt" + echo " cd $BuildDir" echo " make " exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo " BUILD COMPLETE! To install bolt component run this command:" - echo " $0 install" - echo + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" fi -fi +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_DIR/build/bolt" || exit - echo - echo " -----Installing to $BOLT_INSTALL_DIR ----- " - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - removepatch "$AOMP_REPOS/bolt" -fi +command_dispatcher "$@" From 033517052d5c52669859037699274a335213b97b Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:26:02 -0500 Subject: [PATCH 33/71] Taskify build_rocdbgapi.sh Convert build_rocdbgapi.sh to the taskified build pattern with a single (default) config. The conditional gcc-5 experimental include flag is computed inside task_cmake, and the optional doxygen 'make doc' step is folded into task_build. User-controllable variables are routed through cfgvar/cfgbool; INSTALL_ROCDBGAPI and AOMP_DBGAPI_REPO_NAME are added to the aomp_utils string allowlist. --- bin/aomp_utils | 3 +- bin/build_rocdbgapi.sh | 227 ++++++++++++++++++++++++++++------------- 2 files changed, 160 insertions(+), 70 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index c4003f4a1d..c8c0f37b9b 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -302,7 +302,8 @@ get_config_var_string() { AOMP_LIBDEVICE_REPO_NAME|INSTALL_LIBDEVICE|SKIPTEST|\ AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP|\ - AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG|BOLT_INSTALL_DIR) + AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG|BOLT_INSTALL_DIR|\ + INSTALL_ROCDBGAPI|AOMP_DBGAPI_REPO_NAME) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_rocdbgapi.sh b/bin/build_rocdbgapi.sh index 695ad241c4..62f20e998a 100755 --- a/bin/build_rocdbgapi.sh +++ b/bin/build_rocdbgapi.sh @@ -3,20 +3,36 @@ # build_rocdbgapi.sh: Script to build ROCdbgapi for AOMP standalone build # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocdbgapi "$1" +} + +cfgbool() { + get_config_var_bool rocdbgapi "$1" +} + INSTALL_ROCDBGAPI=${INSTALL_ROCDBGAPI:-$AOMP_INSTALL_DIR} +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_DBGAPI_REPO_NAME)" -if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then +if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the ROCM runtime libraries" - echo " It gets the source from: $AOMP_REPOS/$AOMP_DBGAPI_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/rocdbgapi" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/rocdbgapi" echo " It installs in: $INSTALL_ROCDBGAPI" echo " " echo "Example commands and actions: " @@ -26,30 +42,72 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit + exit 0 fi -if [ ! -d "$AOMP_REPOS/$AOMP_DBGAPI_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_DBGAPI_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_DBGAPI_REPO_NAME set correctly?" - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR" +} -check_writable_installdir "$1" "$INSTALL_ROCDBGAPI" +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" -API_NAME=rocm-dbgapi -PROJ_NAME=$API_NAME -LIB_NAME=lib${API_NAME}.so -export API_NAME PROJ_NAME LIB_NAME + case "$Cfg" in + "default") + echo -n "$BuildDir/rocdbgapi" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/build_rocdbgapi" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_ROCDBGAPI +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_DBGAPI_REPO_NAME set correctly?" + exit 1 + fi + + check_writable_installdir "$1" "$(cfgvar INSTALL_ROCDBGAPI)" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local InstallDir + local _cxx_flags + local _loc + local _gccver + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + InstallDir="$(cfgvar INSTALL_ROCDBGAPI)" - BUILD_TYPE="Release" - echo rm -rf "$BUILD_AOMP/build/rocdbgapi" - rm -rf "$BUILD_AOMP/build/rocdbgapi" _cxx_flags="-DCMAKE_CXX_FLAGS=-I$AOMP_INSTALL_DIR/include/amd_comgr" if [ -d "/usr/include/c++/5/experimental" ] ; then _loc=$(which gcc) @@ -60,70 +118,101 @@ if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then fi fi fi - declare -a MYCMAKEOPTS - MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE="$BUILD_TYPE" + + MYCMAKEOPTS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_LIBDIR=lib - -DCMAKE_INSTALL_PREFIX="$INSTALL_ROCDBGAPI" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$INSTALL_ROCDBGAPI/include" + -DCMAKE_INSTALL_PREFIX="$InstallDir" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$InstallDir/include" -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" "$_cxx_flags" "${AOMP_ORIGIN_RPATH[@]}") - mkdir -p "$BUILD_AOMP/build/rocdbgapi" - cd "$BUILD_AOMP/build/rocdbgapi" || exit - echo " -----Running rocdbgapi cmake ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$AOMP_REPOS/$AOMP_DBGAPI_REPO_NAME" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_DBGAPI_REPO_NAME"; then - echo "ERROR rocdbgapi cmake failed. cmake flags" + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rocdbgapi $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR rocdbgapi $Cfg cmake failed. cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi + popd >& /dev/null || exit +} -cd "$BUILD_AOMP/build/rocdbgapi" || exit -echo -echo " -----Running make for rocdbgapi ---- " -echo "make -j $AOMP_JOB_THREADS" +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + local doxygen + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" -if ! make -j "$AOMP_JOB_THREADS"; then + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocdbgapi $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/rocdbgapi" + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" echo " make" exit 1 -fi + fi -doxygen=$(which doxygen) -if [ -n "$doxygen" ] ; then - # the ROCdbgapi CMakeLists.txt will prepare docs install if doxygen found. - # However, the make doc has issues. But if you dont make doc, the install - # fails. This 'make doc' will do enough so install does not fail. - echo "make -j $AOMP_JOB_THREADS doc" - make -j "$AOMP_JOB_THREADS" doc 2>/dev/null >/dev/null -fi + doxygen=$(which doxygen || true) + if [ -n "$doxygen" ] ; then + # the ROCdbgapi CMakeLists.txt will prepare docs install if doxygen found. + # However, the make doc has issues. But if you dont make doc, the install + # fails. This 'make doc' will do enough so install does not fail. + echo "make -j $Jobs doc" + make -j "$Jobs" doc 2>/dev/null >/dev/null || true + fi + popd >& /dev/null || exit +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP/build/rocdbgapi" || exit - echo " -----Installing to $INSTALL_ROCDBGAPI/lib ----- " +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir/lib ----- " echo "$SUDO make install " - if ! $SUDO make install; then + if ! $SUDO make install; then echo "ERROR make install failed " exit 1 fi - echo -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 8d8149f62270dede1baa8623ea98b0a88aef6269 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:28:07 -0500 Subject: [PATCH 34/71] Taskify build_rocgdb.sh Convert build_rocgdb.sh to the taskified build pattern with a single (default) config. ROCgdb uses an autotools configure step; it is mapped to task_cmake so it runs in the standard cmake phase of the dispatcher. task_install runs the install-info-gdb and install-strip-gdb targets. User-controllable variables are routed through cfgvar/cfgbool; AOMP_GDB_REPO_NAME is added to the aomp_utils string allowlist. --- bin/aomp_utils | 2 +- bin/build_rocgdb.sh | 224 +++++++++++++++++++++++++++++++------------- 2 files changed, 158 insertions(+), 68 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index c8c0f37b9b..5ade8292f6 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -303,7 +303,7 @@ get_config_var_string() { AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP|\ AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG|BOLT_INSTALL_DIR|\ - INSTALL_ROCDBGAPI|AOMP_DBGAPI_REPO_NAME) + INSTALL_ROCDBGAPI|AOMP_DBGAPI_REPO_NAME|AOMP_GDB_REPO_NAME) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_rocgdb.sh b/bin/build_rocgdb.sh index cf43180648..94613fb1ca 100755 --- a/bin/build_rocgdb.sh +++ b/bin/build_rocgdb.sh @@ -6,24 +6,41 @@ # This depends on rocdbgapi to be built and installed. # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocgdb "$1" +} + +cfgbool() { + get_config_var_bool rocgdb "$1" +} + # Point to the right python3.6 on Red Hat 7.6 if [ -f /opt/rh/rh-python36/enable ]; then export PATH=/opt/rh/rh-python36/root/usr/bin:$PATH export LIBRARY_PATH=/opt/rh/rh-python36/root/lib64:$LIBRARY_PATH fi -if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_GDB_REPO_NAME)" + +if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds ROCgdb for AOMP standalone build" - echo " It gets the source from: $AOMP_REPOS/$AOMP_GDB_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/rocgdb" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/rocgdb" echo " " echo "Example commands and actions: " echo " ./build_rocgdb.sh configure, make , NO Install " @@ -32,33 +49,77 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit + exit 0 fi -if [ ! -d "$AOMP_REPOS/$AOMP_GDB_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_GDB_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_GDB_REPO_NAME set correctly?" - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/rocgdb" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_GDB_REPO_NAME set correctly?" + exit 1 + fi + + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +# ROCgdb uses an autotools configure step rather than cmake; it is named +# task_cmake so that it runs in the standard "cmake" phase of the dispatcher. +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local BugUrl + local -a MYCONFIGOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + BugUrl="https://github.com/ROCm/ROCgdb/issues" + + export CXXFLAGS_FOR_BUILD="-O2" + export CFLAGS_FOR_BUILD="-O2" -check_writable_installdir "$1" "$AOMP_INSTALL_DIR" - -BUG_URL="https://github.com/ROCm/ROCgdb/issues" -export CXXFLAGS_FOR_BUILD="-O2" -export CFLAGS_FOR_BUILD="-O2" -#patchrepo "$AOMP_REPOS/$AOMP_GDB_REPO_NAME" -if [ "$1" != "noconfigure" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/build_rocgdb" - echo "Use ""$0 noconfigure"" or ""$0 install"" to avoid FRESH START." - echo "rm -rf $BUILD_AOMP/build/rocgdb" - rm -rf "$BUILD_AOMP/build/rocgdb" - declare -a MYCONFIGOPTS MYCONFIGOPTS=(--prefix="$AOMP_INSTALL_DIR" - --srcdir="$AOMP_REPOS/$AOMP_GDB_REPO_NAME" + --srcdir="$SrcDir" --program-prefix=roc - --with-bugurl="$BUG_URL" - --with-pkgversion="${AOMP_COMPILER_NAME}_${AOMP_VERSION_STRING}" + --with-bugurl="$BugUrl" + --with-pkgversion="${AOMP_COMPILER_NAME}_$(cfgvar AOMP_VERSION_STRING)" --with-gdb-datadir="\${prefix}/share/rocgdb" --enable-64-bit-bfd --enable-targets="x86_64-linux-gnu,amdgcn-amd-amdhsa" @@ -70,57 +131,86 @@ if [ "$1" != "noconfigure" ] && [ "$1" != "install" ] ; then --with-rocm-dbgapi="$AOMP_INSTALL_DIR" PKG_CONFIG_PATH="$AOMP_INSTALL_DIR/share/pkgconfig") - mkdir -p "$BUILD_AOMP/build/rocgdb" + mkdir -p "$BuildDir" export LDFLAGS="-Wl,-rpath=$AOMP_INSTALL_DIR/lib" - cd "$BUILD_AOMP/build/rocgdb" || exit - echo " -----Running gdb configure ---- " - echo "$AOMP_REPOS/$AOMP_GDB_REPO_NAME/configure $(shquot "${MYCONFIGOPTS[@]}")" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running gdb configure for rocgdb $Cfg ---- " + echo "$SrcDir/configure $(shquot "${MYCONFIGOPTS[@]}")" - if ! "$AOMP_REPOS/$AOMP_GDB_REPO_NAME"/configure "${MYCONFIGOPTS[@]}"; then + if ! "$SrcDir"/configure "${MYCONFIGOPTS[@]}"; then echo "ERROR gdb configure failed." exit 1 fi -fi + popd >& /dev/null || exit +} -if [ "$1" = "configure" ]; then - exit 0 -fi +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" -cd "$BUILD_AOMP/build/rocgdb" || exit -echo -echo " -----Running make for gdb ---- " -#echo make -j $AOMP_JOB_THREADS all-gdb -#make -j $AOMP_JOB_THREADS all-gdb -echo "make -j $AOMP_JOB_THREADS" + export CXXFLAGS_FOR_BUILD="-O2" + export CFLAGS_FOR_BUILD="-O2" -if ! make -j "$AOMP_JOB_THREADS"; then + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocgdb $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/rocgdb" + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" echo " make all-gdb" exit 1 -else - if [ "$1" != "install" ] ; then - echo - echo "Successful build of ./build_rocgdb.sh . Please run:" - echo " ./build_rocgdb.sh install " - echo "to install into directory $AOMP_INSTALL_DIR" - echo fi -fi + popd >& /dev/null || exit +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP/build/rocgdb" || exit - echo " -----Installing to $AOMP_INSTALL_DIR ----- " - echo "$SUDO make install-info-gdb" - $SUDO make install-info-gdb - echo "$SUDO make install-strip-gdb" - - if ! $SUDO make install-strip-gdb; then - echo "ERROR make install failed " - exit 1 - fi -# removepatch "$AOMP_REPOS/$AOMP_GDB_REPO_NAME" -fi +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ----- " + echo "$SUDO make install-info-gdb" + $SUDO make install-info-gdb + echo "$SUDO make install-strip-gdb" + + if ! $SUDO make install-strip-gdb; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 7693724e246d30bcaa333ed28509c28fdfbd5250 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:29:51 -0500 Subject: [PATCH 35/71] Taskify build_rocprofiler-register.sh Convert build_rocprofiler-register.sh to the taskified build pattern with a single (default) config. The HIP_CLANG_PATH export is moved into task_cmake, and the duplicated cmake linker flag is collapsed. User- controllable variables are routed through cfgvar/cfgbool; INSTALL_ROCPROF_REGISTER and AOMP_PROF_REGISTER_REPO_NAME are added to the aomp_utils string allowlist. --- bin/aomp_utils | 3 +- bin/build_rocprofiler-register.sh | 245 ++++++++++++++++++++---------- 2 files changed, 165 insertions(+), 83 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 5ade8292f6..0d2d2c0d65 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -303,7 +303,8 @@ get_config_var_string() { AOMP_ROCMCMAKE_REPO_NAME|AOMP_REPO_NAME|INSTALL_EXTRAS|INSTALL_HIPCC|\ INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP|\ AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG|BOLT_INSTALL_DIR|\ - INSTALL_ROCDBGAPI|AOMP_DBGAPI_REPO_NAME|AOMP_GDB_REPO_NAME) + INSTALL_ROCDBGAPI|AOMP_DBGAPI_REPO_NAME|AOMP_GDB_REPO_NAME|\ + INSTALL_ROCPROF_REGISTER|AOMP_PROF_REGISTER_REPO_NAME) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_rocprofiler-register.sh b/bin/build_rocprofiler-register.sh index 002cf47117..29c8aaaaae 100755 --- a/bin/build_rocprofiler-register.sh +++ b/bin/build_rocprofiler-register.sh @@ -7,21 +7,36 @@ # build_rocprofiler-register.sh: Script to build rocprofiler-register for AOMP standalone build # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocprofiler-register "$1" +} + +cfgbool() { + get_config_var_bool rocprofiler-register "$1" +} + INSTALL_ROCPROF_REGISTER=${INSTALL_ROCPROF_REGISTER:-$AOMP_INSTALL_DIR} -export HIP_CLANG_PATH=$INSTALL_ROCPROF_REGISTER/bin +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROF_REGISTER_REPO_NAME)" -if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then +if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the ROCM runtime libraries" - echo " It gets the source from: $AOMP_REPOS/$AOMP_PROF_REGISTER_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/$AOMP_PROF_REGISTER_REPO_NAME" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/$(cfgvar AOMP_PROF_REGISTER_REPO_NAME)" echo " It installs in: $INSTALL_ROCPROF_REGISTER" echo " " echo "Example commands and actions: " @@ -31,92 +46,158 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit + exit 0 fi -if [ ! -d "$AOMP_REPOS/$AOMP_PROF_REGISTER_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_PROF_REGISTER_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_PROF_REGISTER_REPO_NAME set correctly?" - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)/$(cfgvar AOMP_PROF_REGISTER_REPO_NAME)" + + case "$Cfg" in + "default") + echo -n "$BuildDir" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_ROCPROF_REGISTER +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" -check_writable_installdir "$1" "$INSTALL_ROCPROF_REGISTER" - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/$AOMP_PROF_REGISTER_REPO_NAME" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - - echo "rm -rf $BUILD_AOMP/build/$AOMP_PROF_REGISTER_REPO_NAME" - rm -rf "$BUILD_AOMP/build/$AOMP_PROF_REGISTER_REPO_NAME" - BUILD_TYPE="Release" - export CMAKE_BUILD_TYPE=$BUILD_TYPE - CMAKE_PREFIX_PATH="$ROCM_DIR/include;$ROCM_DIR/lib;$ROCM_DIR" - export CMAKE_PREFIX_PATH - mkdir -p "$BUILD_AOMP/build/$AOMP_PROF_REGISTER_REPO_NAME" - cd "$BUILD_AOMP/build/$AOMP_PROF_REGISTER_REPO_NAME" || exit - echo " -----Running $AOMP_PROF_REGISTER_REPO_NAME cmake ---- " - echo "${AOMP_CMAKE}" "-DCMAKE_INSTALL_LIBDIR=lib" \ - "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ - "-DROCM_PATH=$AOMP_INSTALL_DIR" \ - "-DCMAKE_INSTALL_PREFIX=$INSTALL_ROCPROF_REGISTER" \ - "-DCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH" \ - "-DCMAKE_EXE_LINKER_FLAGS=-Wl,--disable-new-dtags" \ - "-DROCPROFILER_REGISTER_BUILD_TESTS=0" \ - "-DROCPROFILER_REGISTER_BUILD_SAMPLES=1" \ - "-DCMAKE_EXE_LINKER_FLAGS=-Wl,--disable-new-dtags" \ - "-DBUILD_SHARED_LIBS=ON -DENABLE_LDCONFIG=OFF" \ - "$(shquot "${AOMP_ORIGIN_RPATH[@]}")" \ - "$AOMP_REPOS/$AOMP_PROF_REGISTER_REPO_NAME" - - if ! ${AOMP_CMAKE} -DCMAKE_INSTALL_LIBDIR=lib \ - -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ - -DROCM_PATH="$AOMP_INSTALL_DIR" \ - -DCMAKE_INSTALL_PREFIX="$INSTALL_ROCPROF_REGISTER" \ - -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \ - "${AOMP_ORIGIN_RPATH[@]}" \ - -DCMAKE_EXE_LINKER_FLAGS="-Wl,--disable-new-dtags" \ - -DBUILD_SHARED_LIBS=ON -DENABLE_LDCONFIG=OFF \ - -DROCPROFILER_REGISTER_BUILD_TESTS=0 \ - -DROCPROFILER_REGISTER_BUILD_SAMPLES=1 \ - "$AOMP_REPOS/$AOMP_PROF_REGISTER_REPO_NAME"; then - echo "ERROR $AOMP_PROF_REGISTER_REPO_NAME cmake failed. cmake flags" - echo " $MYCMAKEOPTS" + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_PROF_REGISTER_REPO_NAME set correctly?" exit 1 fi -fi -if [ "$1" = "cmake" ]; then - exit 0 -fi + check_writable_installdir "$1" "$(cfgvar INSTALL_ROCPROF_REGISTER)" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local InstallDir + local -a MYCMAKEOPTS -cd "$BUILD_AOMP/build/$AOMP_PROF_REGISTER_REPO_NAME" || exit -echo -echo " -----Running make for $AOMP_PROF_REGISTER_REPO_NAME ---- " -echo "make -j $AOMP_JOB_THREADS" + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + InstallDir="$(cfgvar INSTALL_ROCPROF_REGISTER)" -if ! make -j "$AOMP_JOB_THREADS"; then + export HIP_CLANG_PATH="$InstallDir/bin" + + MYCMAKEOPTS=(-DCMAKE_INSTALL_LIBDIR=lib + -DCMAKE_BUILD_TYPE=Release + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_PREFIX="$InstallDir" + -DCMAKE_PREFIX_PATH="$ROCM_DIR/include;$ROCM_DIR/lib;$ROCM_DIR" + "${AOMP_ORIGIN_RPATH[@]}" + -DCMAKE_EXE_LINKER_FLAGS="-Wl,--disable-new-dtags" + -DBUILD_SHARED_LIBS=ON + -DENABLE_LDCONFIG=OFF + -DROCPROFILER_REGISTER_BUILD_TESTS=0 + -DROCPROFILER_REGISTER_BUILD_SAMPLES=1) + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rocprofiler-register $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR rocprofiler-register $Cfg cmake failed. cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocprofiler-register $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/$AOMP_PROF_REGISTER_REPO_NAME" + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" echo " make" exit 1 -fi + fi + popd >& /dev/null || exit +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP/build/$AOMP_PROF_REGISTER_REPO_NAME" || exit - echo " -----Installing to $INSTALL_ROCPROF_REGISTER/lib ----- " - echo "$SUDO make install" - - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir/lib ----- " + echo "$SUDO make install" + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" +} + +do_list_fini() { + : +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From ef3b818b9617ed2acad6792a1dc7b570abd020d8 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 09:33:58 -0500 Subject: [PATCH 36/71] Taskify build_rocprofiler.sh Convert build_rocprofiler.sh to the taskified build pattern with a single (default) config and patch/unpatch init/fini steps. The env exports, gcc-5 experimental include flag, and GPU target list are computed inside task_cmake; task_build keeps the make + make mytest sequence and folds in the optional doxygen 'make doc'. User-controllable variables are routed through cfgvar/cfgbool; INSTALL_ROCPROF and AOMP_PROF_REPO_NAME are added to the aomp_utils string allowlist. --- bin/aomp_utils | 3 +- bin/build_rocprofiler.sh | 304 +++++++++++++++++++++++++-------------- 2 files changed, 196 insertions(+), 111 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 0d2d2c0d65..cf052d24a3 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -304,7 +304,8 @@ get_config_var_string() { INSTALL_HIPIFY|HIPFORT_INSTALL_DIR|OPENMP_BUILD_DIR|ALTAOMP|\ AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG|BOLT_INSTALL_DIR|\ INSTALL_ROCDBGAPI|AOMP_DBGAPI_REPO_NAME|AOMP_GDB_REPO_NAME|\ - INSTALL_ROCPROF_REGISTER|AOMP_PROF_REGISTER_REPO_NAME) + INSTALL_ROCPROF_REGISTER|AOMP_PROF_REGISTER_REPO_NAME|\ + INSTALL_ROCPROF|AOMP_PROF_REPO_NAME) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_rocprofiler.sh b/bin/build_rocprofiler.sh index 2b37b638f3..59a7b0b342 100755 --- a/bin/build_rocprofiler.sh +++ b/bin/build_rocprofiler.sh @@ -3,22 +3,36 @@ # build_rocprofiler.sh: Script to build rocprofiler for AOMP standalone build # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocprofiler "$1" +} + +cfgbool() { + get_config_var_bool rocprofiler "$1" +} + INSTALL_ROCPROF=${INSTALL_ROCPROF:-$AOMP_INSTALL_DIR} -export HIP_CLANG_PATH=$LLVM_INSTALL_LOC/bin -export ROCM_PATH=$AOMP_INSTALL_DIR +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROF_REPO_NAME)" -if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then +if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the ROCM runtime libraries" - echo " It gets the source from: $AOMP_REPOS/$AOMP_PROF_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/rocprofiler" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/rocprofiler" echo " It installs in: $INSTALL_ROCPROF" echo " " echo "Example commands and actions: " @@ -28,26 +42,88 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit + exit 0 fi -if [ ! -d "$AOMP_REPOS/$AOMP_PROF_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_PROF_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_PROF_REPO_NAME set correctly?" - exit 1 -fi +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" -check_writable_installdir "$1" "$INSTALL_ROCPROF" + case "$Cfg" in + "default") + echo -n "$BuildDir/rocprofiler" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} -patchrepo "$AOMP_REPOS/$AOMP_PROF_REPO_NAME" +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_ROCPROF +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_PROF_REPO_NAME set correctly?" + exit 1 + fi -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/build_rocprofiler" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." + check_writable_installdir "$1" "$(cfgvar INSTALL_ROCPROF)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local InstallDir + local GfxSemicolons + local _loc + local _gccver + local -a CMAKE_WITH_EXPERIMENTAL + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + InstallDir="$(cfgvar INSTALL_ROCPROF)" + GfxSemicolons=$(cfgvar GFXLIST | tr ' ' ';') + + export HIP_CLANG_PATH="$LLVM_INSTALL_LOC/bin" + export ROCM_PATH="$AOMP_INSTALL_DIR" + export CMAKE_BUILD_TYPE=Release + export CMAKE_PREFIX_PATH="$ROCM_DIR/roctracer/include/ext;$ROCM_DIR/include/platform;$ROCM_DIR/include;$ROCM_DIR/lib;$ROCM_DIR;$HOME/.local/bin;$HOME/local/aqlprofile;$LLVM_INSTALL_LOC" + export PATH=$HOME/.local/bin:$InstallDir/bin:$PATH - echo "rm -rf $BUILD_AOMP/build/rocprofiler" - rm -rf "$BUILD_AOMP/build/rocprofiler" CMAKE_WITH_EXPERIMENTAL=() if [ -d "/usr/include/c++/5/experimental" ] ; then _loc=$(which gcc) @@ -58,104 +134,112 @@ if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then fi fi fi - BUILD_TYPE="Release" - export CMAKE_BUILD_TYPE=$BUILD_TYPE - CMAKE_PREFIX_PATH="$ROCM_DIR/roctracer/include/ext;$ROCM_DIR/include/platform;$ROCM_DIR/include;$ROCM_DIR/lib;$ROCM_DIR;$HOME/.local/bin;$HOME/local/aqlprofile;$LLVM_INSTALL_LOC" - export CMAKE_PREFIX_PATH - #export HSA_RUNTIME_INC=$ROCM_DIR/include - #export HSA_RUNTIME_LIB=$ROCM_DIR/include/lib - #export HSA_KMT_LIB=$ROCM_DIR/lib - #export HSA_KMT_LIB_PATH=$ROCM_DIR/lib - GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') - mkdir -p "$BUILD_AOMP/build/rocprofiler" - cd "$BUILD_AOMP/build/rocprofiler" || exit - export PATH=$HOME/.local/bin:$INSTALL_ROCPROF/bin:$PATH - echo " -----Running rocprofiler cmake ---- " - echo "${AOMP_CMAKE}" "-DCMAKE_INSTALL_LIBDIR=lib" \ - "-DENABLE_ASAN_PACKAGING=ON" \ - "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ - "-DROCM_PATH=$AOMP_INSTALL_DIR" \ - "-DCMAKE_MODULE_PATH=$INSTALL_ROCPROF/lib/cmake/hip" \ - "-DCMAKE_INSTALL_PREFIX=$INSTALL_ROCPROF" \ - "-DCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH" \ - "${CMAKE_WITH_EXPERIMENTAL[@]}" \ - "${AOMP_ORIGIN_RPATH[@]}" \ - "-DGPU_TARGETS=$GFXSEMICOLONS" \ - "-DPROF_API_HEADER_PATH=$INSTALL_ROCPROF/include/roctracer/ext" \ - "-DHIP_ROOT_DIR=$INSTALL_ROCPROF/hip" \ - "$AOMP_REPOS/$AOMP_PROF_REPO_NAME" \ - "-DAQLPROFILE_LIB=$AOMP_SUPP/aqlprofile/lib/libhsa-amd-aqlprofile64.so" \ - "-DCMAKE_CXX_FLAGS=-I$HOME/local/rocmsmilib/include" \ - "-DHIP_HIPCC_FLAGS=-I$HOME/local/rocmsmilib/include" \ - "-DCMAKE_EXE_LINKER_FLAGS=-L$HOME/local/rocmsmilib/lib" \ - "-L$HOME/local/rocmsmilib/lib64" \ - "-Wl,--disable-new-dtags" - - if ! ${AOMP_CMAKE} -DCMAKE_INSTALL_LIBDIR=lib \ - -DENABLE_ASAN_PACKAGING=ON \ - -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ - -DROCM_PATH="$AOMP_INSTALL_DIR" \ - -DCMAKE_MODULE_PATH="$INSTALL_ROCPROF/lib/cmake/hip" \ - -DCMAKE_INSTALL_PREFIX="$INSTALL_ROCPROF" \ - -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \ - "${CMAKE_WITH_EXPERIMENTAL[@]}" \ - "${AOMP_ORIGIN_RPATH[@]}" \ - -DGPU_TARGETS="$GFXSEMICOLONS" \ - -DPROF_API_HEADER_PATH="$INSTALL_ROCPROF/include/roctracer/ext" \ - -DHIP_ROOT_DIR="$INSTALL_ROCPROF/hip" \ - "$AOMP_REPOS/$AOMP_PROF_REPO_NAME" \ - -DAQLPROFILE_LIB="$AOMP_SUPP/aqlprofile/lib/libhsa-amd-aqlprofile64.so" \ - -DCMAKE_CXX_FLAGS="-I$HOME/local/rocmsmilib/include" \ - -DHIP_HIPCC_FLAGS="-I$HOME/local/rocmsmilib/include" \ - -DCMAKE_EXE_LINKER_FLAGS="-L$HOME/local/rocmsmilib/lib -L$HOME/local/rocmsmilib/lib64 -Wl,--disable-new-dtags"; then - echo "ERROR rocprofiler cmake failed. cmake flags" - echo " $MYCMAKEOPTS" + + MYCMAKEOPTS=(-DCMAKE_INSTALL_LIBDIR=lib + -DENABLE_ASAN_PACKAGING=ON + -DCMAKE_BUILD_TYPE=Release + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DCMAKE_MODULE_PATH="$InstallDir/lib/cmake/hip" + -DCMAKE_INSTALL_PREFIX="$InstallDir" + -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" + "${CMAKE_WITH_EXPERIMENTAL[@]}" + "${AOMP_ORIGIN_RPATH[@]}" + -DGPU_TARGETS="$GfxSemicolons" + -DPROF_API_HEADER_PATH="$InstallDir/include/roctracer/ext" + -DHIP_ROOT_DIR="$InstallDir/hip" + -DAQLPROFILE_LIB="$(cfgvar AOMP_SUPP)/aqlprofile/lib/libhsa-amd-aqlprofile64.so" + -DCMAKE_CXX_FLAGS="-I$HOME/local/rocmsmilib/include" + -DHIP_HIPCC_FLAGS="-I$HOME/local/rocmsmilib/include" + -DCMAKE_EXE_LINKER_FLAGS="-L$HOME/local/rocmsmilib/lib -L$HOME/local/rocmsmilib/lib64 -Wl,--disable-new-dtags") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rocprofiler $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR rocprofiler $Cfg cmake failed. cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi + popd >& /dev/null || exit +} -if [ "$1" = "cmake" ]; then - exit 0 -fi +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + local doxygen + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" -cd "$BUILD_AOMP/build/rocprofiler" || exit -echo -echo " -----Running make for rocprofiler ---- " -echo "make -j $AOMP_JOB_THREADS" -make -j "$AOMP_JOB_THREADS" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocprofiler $Cfg ---- " + echo "make -j $Jobs" + make -j "$Jobs" -if ! make -j "$AOMP_JOB_THREADS" mytest; then + if ! make -j "$Jobs" mytest; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/rocprofiler" + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" echo " make" exit 1 -fi + fi -doxygen=$(which doxygen) -if [ -n "$doxygen" ] ; then - # the rocprofiler CMakeLists.txt will prepare docs install if doxygen found. - # However, the make doc has issues. But if you dont make doc, the install - # fails. This 'make doc' will do enough so install does not fail. - echo "make -j $AOMP_JOB_THREADS doc" - make -j "$AOMP_JOB_THREADS" doc 2>/dev/null >/dev/null -fi + doxygen=$(which doxygen || true) + if [ -n "$doxygen" ] ; then + # the rocprofiler CMakeLists.txt will prepare docs install if doxygen + # found. However, the make doc has issues. But if you dont make doc, the + # install fails. This 'make doc' will do enough so install does not fail. + echo "make -j $Jobs doc" + make -j "$Jobs" doc 2>/dev/null >/dev/null || true + fi + popd >& /dev/null || exit +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP/build/rocprofiler" || exit - echo " -----Installing to $INSTALL_ROCPROF/lib ----- " - echo "$SUDO make install" +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - removepatch "$AOMP_REPOS/$AOMP_PROF_REPO_NAME" -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir/lib ----- " + echo "$SUDO make install" + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 46e1330897b3eee70840bae6d1daac6ab9948c9d Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 10:14:55 -0500 Subject: [PATCH 37/71] Taskify build_rocprofiler-sdk.sh Convert build_rocprofiler-sdk.sh to the taskified build pattern with a single (default) config and patch/unpatch init/fini steps. The env exports, python version detection, and GPU target list are computed inside task_cmake; the post-install aqlprofile library copy becomes task_postinstall. User-controllable variables are routed through cfgvar/cfgbool; INSTALL_ROCPROF_SDK and AOMP_PROF_SDK_REPO_NAME are added to the aomp_utils string allowlist. --- bin/aomp_utils | 3 +- bin/build_rocprofiler-sdk.sh | 281 +++++++++++++++++++++++------------ 2 files changed, 192 insertions(+), 92 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index cf052d24a3..11848f882a 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -305,7 +305,8 @@ get_config_var_string() { AOMP_LFL_DIR|AOMP_FLANG_REPO_NAME|INSTALL_FLANG|BOLT_INSTALL_DIR|\ INSTALL_ROCDBGAPI|AOMP_DBGAPI_REPO_NAME|AOMP_GDB_REPO_NAME|\ INSTALL_ROCPROF_REGISTER|AOMP_PROF_REGISTER_REPO_NAME|\ - INSTALL_ROCPROF|AOMP_PROF_REPO_NAME) + INSTALL_ROCPROF|AOMP_PROF_REPO_NAME|\ + INSTALL_ROCPROF_SDK|AOMP_PROF_SDK_REPO_NAME) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_rocprofiler-sdk.sh b/bin/build_rocprofiler-sdk.sh index 07754e7d61..81cb0953aa 100755 --- a/bin/build_rocprofiler-sdk.sh +++ b/bin/build_rocprofiler-sdk.sh @@ -3,22 +3,36 @@ # build_rocprofiler-sdk.sh: Script to build rocprofiler-sdk for AOMP standalone build # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocprofiler-sdk "$1" +} + +cfgbool() { + get_config_var_bool rocprofiler-sdk "$1" +} + INSTALL_ROCPROF_SDK=${INSTALL_ROCPROF_SDK:-$AOMP_INSTALL_DIR} -export HIP_CLANG_PATH=$LLVM_INSTALL_LOC/bin -export ROCM_PATH=$AOMP_INSTALL_DIR +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROF_SDK_REPO_NAME)" if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the ROCM runtime libraries" - echo " It gets the source from: $AOMP_REPOS/$AOMP_PROF_SDK_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/rocprofiler-sdk" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/rocprofiler-sdk" echo " It installs in: $INSTALL_ROCPROF_SDK" echo " " echo "Example commands and actions: " @@ -28,111 +42,196 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit + exit 0 fi -if [ ! -d "$AOMP_REPOS/$AOMP_PROF_SDK_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_PROF_SDK_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_PROF_SDK_REPO_NAME set correctly?" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p "$INSTALL_ROCPROF_SDK" - if ! $SUDO touch "$INSTALL_ROCPROF_SDK"/testfile; then - echo "ERROR: No update access to $INSTALL_ROCPROF_SDK" +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/rocprofiler-sdk" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_ROCPROF_SDK +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_PROF_SDK_REPO_NAME set correctly?" exit 1 fi - $SUDO rm "$INSTALL_ROCPROF_SDK"/testfile -fi -patchrepo "$AOMP_REPOS/rocprofiler-sdk" - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/build_rocprofiler-sdk" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - - echo "rm -rf $BUILD_AOMP/build/rocprofiler-sdk" - rm -rf "$BUILD_AOMP"/build/rocprofiler-sdk - - BUILD_TYPE="Release" - GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') - - mkdir -p "$BUILD_AOMP"/build/rocprofiler-sdk - cd "$BUILD_AOMP"/build/rocprofiler-sdk || exit - export PATH=$HOME/.local/bin:$INSTALL_ROCPROF_SDK/bin:$PATH + check_writable_installdir "$1" "$(cfgvar INSTALL_ROCPROF_SDK)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local InstallDir + local GfxSemicolons + local pythonbinary + local pythonversion + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + InstallDir="$(cfgvar INSTALL_ROCPROF_SDK)" + GfxSemicolons=$(cfgvar GFXLIST | tr ' ' ';') + + export HIP_CLANG_PATH="$LLVM_INSTALL_LOC/bin" + export ROCM_PATH="$AOMP_INSTALL_DIR" + export PATH=$HOME/.local/bin:$InstallDir/bin:$PATH pythonbinary=$(which python3) || exit pythonversion=$("$pythonbinary" --version) || exit if [[ $pythonversion =~ ([Pp]ython)[[:space:]]*([0-9]+)\.([0-9]+) ]]; then pythonversion="${BASH_REMATCH[2]}.${BASH_REMATCH[3]}" else - echo "Error: cannot determine python version" - exit 1 + echo "Error: cannot determine python version" + exit 1 fi - declare -a MYCMAKEOPTS - MYCMAKEOPTS=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$HOME/local/aqlprofile" - -DCMAKE_INSTALL_PREFIX="$INSTALL_ROCPROF_SDK" - -DCMAKE_BUILD_TYPE="$BUILD_TYPE" - -DROCM_ROOT_DIR="$AOMP_INSTALL_DIR" - -DBUILD_SHARED_LIBS=On - -DGPU_TARGETS="$GFXSEMICOLONS" - -DROCPROFILER_BUILD_SAMPLES=ON - -DROCPROFILER_BUILD_TESTS=OFF - -DPython3_EXECUTABLE="$(which python3)" - -DROCPROFILER_PYTHON_VERSIONS="$pythonversion") - - echo " -----Running rocprofiler-sdk cmake ---- " - echo "${AOMP_CMAKE}" "${MYCMAKEOPTS[@]}" "$AOMP_REPOS/$AOMP_PROF_SDK_REPO_NAME" - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$AOMP_REPOS/$AOMP_PROF_SDK_REPO_NAME"; then - echo "ERROR rocprofiler-sdk cmake failed. cmake flags" + -DCMAKE_INSTALL_PREFIX="$InstallDir" + -DCMAKE_BUILD_TYPE=Release + -DROCM_ROOT_DIR="$AOMP_INSTALL_DIR" + -DBUILD_SHARED_LIBS=On + -DGPU_TARGETS="$GfxSemicolons" + -DROCPROFILER_BUILD_SAMPLES=ON + -DROCPROFILER_BUILD_TESTS=OFF + -DPython3_EXECUTABLE="$pythonbinary" + -DROCPROFILER_PYTHON_VERSIONS="$pythonversion") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rocprofiler-sdk $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR rocprofiler-sdk $Cfg cmake failed. cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_AOMP"/build/rocprofiler-sdk || exit -echo -echo " -----Running make for rocprofiler-sdk ---- " -echo make -j "$AOMP_JOB_THREADS" -if ! make -j "$AOMP_JOB_THREADS"; then + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocprofiler-sdk $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: make -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_AOMP/build/rocprofiler-sdk" + echo " cd $BuildDir" echo " make" exit 1 -fi + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir/lib ----- " + echo "$SUDO make install" + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP"/build/rocprofiler-sdk || exit - echo " -----Installing to $INSTALL_ROCPROF_SDK/lib ----- " - echo $SUDO make install - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - if [ -d "$HOME/local/aqlprofile/lib" ]; then - echo "Copying aqlprofile libraries from $HOME/local/aqlprofile/lib to $INSTALL_ROCPROF_SDK/lib" - cp -r "$HOME"/local/aqlprofile/lib/* "$INSTALL_ROCPROF_SDK"/lib - else - echo "Error: rocprofiler-sdk needs aqlprofile libraries to exist in $INSTALL_ROCPROF_SDK/lib. Please run ./build_prereq.sh first." - exit 1 - fi - - removepatch "$AOMP_REPOS/rocprofiler-sdk" -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi +task_postinstall() { + local Cfg=$1 + local InstallDir + InstallDir="$(get_install_dir "$Cfg")" + + if [ -d "$HOME/local/aqlprofile/lib" ]; then + echo "Copying aqlprofile libraries from $HOME/local/aqlprofile/lib to $InstallDir/lib" + cp -r "$HOME"/local/aqlprofile/lib/* "$InstallDir"/lib + else + echo "Error: rocprofiler-sdk needs aqlprofile libraries to exist in $InstallDir/lib. Please run ./build_prereq.sh first." + exit 1 + fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + echo "postinstall" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 39df8d42b2537d915611f2a80ae00abf77c76607 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 10:43:22 -0500 Subject: [PATCH 38/71] Taskify build_roctracer.sh Convert build_roctracer.sh to the taskified build pattern with a single (default) config and patch/unpatch init/fini steps. The env exports, gcc-5 experimental include flag, and GPU target list are computed inside task_cmake; task_build folds in the optional doxygen 'make doc'. User- controllable variables are routed through cfgvar/cfgbool; INSTALL_ROCTRACE, AOMP_TRACE_REPO_NAME, and HIP_PLATFORM are added to the aomp_utils string allowlist. --- bin/aomp_utils | 3 +- bin/build_roctracer.sh | 283 ++++++++++++++++++++++++++++------------- 2 files changed, 195 insertions(+), 91 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 11848f882a..96e575e495 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -306,7 +306,8 @@ get_config_var_string() { INSTALL_ROCDBGAPI|AOMP_DBGAPI_REPO_NAME|AOMP_GDB_REPO_NAME|\ INSTALL_ROCPROF_REGISTER|AOMP_PROF_REGISTER_REPO_NAME|\ INSTALL_ROCPROF|AOMP_PROF_REPO_NAME|\ - INSTALL_ROCPROF_SDK|AOMP_PROF_SDK_REPO_NAME) + INSTALL_ROCPROF_SDK|AOMP_PROF_SDK_REPO_NAME|\ + INSTALL_ROCTRACE|AOMP_TRACE_REPO_NAME|HIP_PLATFORM) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_roctracer.sh b/bin/build_roctracer.sh index 58707b1e25..62f3d8a2dc 100755 --- a/bin/build_roctracer.sh +++ b/bin/build_roctracer.sh @@ -3,28 +3,37 @@ # build_roctracer.sh: Script to build roctracer for AOMP standalone build # -# --- Start standard header to set AOMP environment variables ---- +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit -realpath=$(realpath "$0") +# --- Start standard header to set AOMP environment variables ---- +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") . "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- -INSTALL_ROCTRACE=${INSTALL_ROCTRACE:-$AOMP_INSTALL_DIR} -export HIP_CLANG_PATH=$LLVM_INSTALL_LOC/bin -echo "$HIP_CLANG_PATH" -export ROCM_PATH=$ROCM_DIR +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string roctracer "$1" +} + +cfgbool() { + get_config_var_bool roctracer "$1" +} -# Needed for systems that have both AMD and Nvidia cards installed. +INSTALL_ROCTRACE=${INSTALL_ROCTRACE:-$AOMP_INSTALL_DIR} HIP_PLATFORM=${HIP_PLATFORM:-amd} -export HIP_PLATFORM +REPO_DIR="$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_TRACE_REPO_NAME)" -if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then +if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo " This script builds the ROCM runtime libraries" - echo " It gets the source from: $AOMP_REPOS/$AOMP_TRACE_REPO_NAME" - echo " It builds libraries in: $BUILD_AOMP/build/roctracer" + echo " It gets the source from: $REPO_DIR" + echo " It builds libraries in: $(cfgvar BUILD_DIR)/roctracer" echo " It installs in: $INSTALL_ROCTRACE" echo " " echo "Example commands and actions: " @@ -34,26 +43,91 @@ if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " echo "To build aomp, see the README file in this directory" echo " " - exit -fi - -if [ ! -d "$AOMP_REPOS/$AOMP_TRACE_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_TRACE_REPO_NAME" - echo " Are environment variables AOMP_REPOS and AOMP_TRACE_REPO_NAME set correctly?" - exit 1 + exit 0 fi -check_writable_installdir "$1" "$INSTALL_ROCTRACE" - -patchrepo "$AOMP_REPOS/$AOMP_TRACE_REPO_NAME" +get_src_dir() { + echo "$REPO_DIR" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local BuildDir + BuildDir="$(cfgvar BUILD_DIR)" + + case "$Cfg" in + "default") + echo -n "$BuildDir/roctracer" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + cfgvar INSTALL_ROCTRACE +} + +task_precheck() { + local SrcDir + SrcDir="$(get_src_dir)" + + if [ ! -d "$SrcDir" ] ; then + echo "ERROR: Missing repository $SrcDir" + echo " Are environment variables AOMP_REPOS and AOMP_TRACE_REPO_NAME set correctly?" + exit 1 + fi -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_AOMP/build_roctracer" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." + check_writable_installdir "$1" "$(cfgvar INSTALL_ROCTRACE)" +} + +task_patch() { + patchrepo "$REPO_DIR" +} + +task_unpatch() { + removepatch "$REPO_DIR" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local InstallDir + local GfxSemicolons + local HipPlatform + local _loc + local _gccver + local -a CMAKE_WITH_EXPERIMENTAL + local -a MYCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + InstallDir="$(cfgvar INSTALL_ROCTRACE)" + GfxSemicolons=$(cfgvar GFXLIST | tr ' ' ';') + HipPlatform="$(cfgvar HIP_PLATFORM)" + + export HIP_CLANG_PATH="$LLVM_INSTALL_LOC/bin" + export HIP_PLATFORM="$HipPlatform" + export ROCM_PATH="$ROCM_DIR" + export CMAKE_BUILD_TYPE=Release + export CMAKE_PREFIX_PATH="$ROCM_DIR/include/hsa;$ROCM_DIR/include;$ROCM_DIR/lib;$ROCM_DIR;$LLVM_INSTALL_LOC" + export HIPCC_COMPILE_FLAGS_APPEND="--rocm-path=$ROCM_DIR" - echo "rm -rf $BUILD_AOMP/build/roctracer" - rm -rf "$BUILD_AOMP/build/roctracer" CMAKE_WITH_EXPERIMENTAL=() if [ -d "/usr/include/c++/5/experimental" ] ; then _loc=$(which gcc) @@ -64,73 +138,102 @@ if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then fi fi fi - BUILD_TYPE="Release" - export CMAKE_BUILD_TYPE=$BUILD_TYPE - CMAKE_PREFIX_PATH="$ROCM_DIR/include/hsa;$ROCM_DIR/include;$ROCM_DIR/lib;$ROCM_DIR;$LLVM_INSTALL_LOC" - export CMAKE_PREFIX_PATH - GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') - export ROCM_PATH=$ROCM_DIR - export HIPCC_COMPILE_FLAGS_APPEND="--rocm-path=$ROCM_PATH" - mkdir -p "$BUILD_AOMP/build/roctracer" - cd "$BUILD_AOMP/build/roctracer" || exit - echo " -----Running roctracer cmake ---- " - - if ! ${AOMP_CMAKE} -DCMAKE_INSTALL_LIBDIR=lib \ - -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ - -DCMAKE_INSTALL_PREFIX="$INSTALL_ROCTRACE" \ - -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \ - "${CMAKE_WITH_EXPERIMENTAL[@]}" \ - "${AOMP_ORIGIN_RPATH[@]}" \ - -DGPU_TARGETS="$GFXSEMICOLONS" \ - -DROCM_PATH="$ROCM_DIR" \ - "$AOMP_REPOS/$AOMP_TRACE_REPO_NAME"; then - echo "ERROR roctracer cmake failed. cmake flags" + + MYCMAKEOPTS=(-DCMAKE_INSTALL_LIBDIR=lib + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX="$InstallDir" + -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" + "${CMAKE_WITH_EXPERIMENTAL[@]}" + "${AOMP_ORIGIN_RPATH[@]}" + -DGPU_TARGETS="$GfxSemicolons" + -DROCM_PATH="$ROCM_DIR") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for roctracer $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR roctracer $Cfg cmake failed. cmake flags" echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi - -if [ "$1" = "cmake" ]; then - exit 0 -fi - -cd "$BUILD_AOMP/build/roctracer" || exit -echo -echo " -----Running make for roctracer ---- " -echo "make -j $AOMP_JOB_THREADS" - -if ! make -j "$AOMP_JOB_THREADS"; then + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + local doxygen + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for roctracer $Cfg ---- " + echo "make -j $Jobs" + if ! make -j "$Jobs"; then echo " " - echo "ERROR: make -j $AOMP_JOB_THREADS FAILED" - echo "To restart:" - echo " cd $BUILD_AOMP/build/roctracer" + echo "ERROR: make -j $Jobs FAILED" + echo "To restart:" + echo " cd $BuildDir" echo " make" exit 1 -fi - -doxygen=$(which doxygen) -if [ -n "$doxygen" ] ; then - # the roctracer CMakeLists.txt will prepare docs install if doxygen found. - # However, the make doc has issues. But if you dont make doc, the install - # fails. This 'make doc' will do enough so install does not fail. - echo "make -j $AOMP_JOB_THREADS doc" - make -j "$AOMP_JOB_THREADS" doc 2>/dev/null >/dev/null -fi - -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - cd "$BUILD_AOMP/build/roctracer" || exit - echo " -----Installing to $INSTALL_ROCTRACE/lib ----- " - echo "$SUDO make install " + fi - if ! $SUDO make install; then - echo "ERROR make install failed " - exit 1 - fi - removepatch "$AOMP_REPOS/$AOMP_TRACE_REPO_NAME" -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP" - echo -fi + doxygen=$(which doxygen || true) + if [ -n "$doxygen" ] ; then + # the roctracer CMakeLists.txt will prepare docs install if doxygen found. + # However, the make doc has issues. But if you dont make doc, the install + # fails. This 'make doc' will do enough so install does not fail. + echo "make -j $Jobs doc" + make -j "$Jobs" doc 2>/dev/null >/dev/null || true + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir/lib ----- " + echo "$SUDO make install " + + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 1eec0ae2267f617fd830f5150c1fc1ca9b65ae91 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 10:48:14 -0500 Subject: [PATCH 39/71] Taskify build_llvm_runtimes_standalone.sh Convert build_llvm_runtimes_standalone.sh to the taskified build pattern, mirroring the build_openmp.sh model. The recursive devicertl self- invocation is replaced by additional "-devicertl" configs, and the asan/perf/debug variants are modeled as composite config names. As in the original, no plain "default" config is built; only the asan, perf, perf+asan, debug, and debug+asan variants (and their devicertl passes) are configured. task_postinstall copies the debug offload/openmp sources for the debug config. User-controllable variables are routed through cfgvar/cfgbool; RUNTIMES_BUILD_DIR is added to the aomp_utils string allowlist. --- bin/aomp_utils | 3 +- bin/build_llvm_runtimes_standalone.sh | 953 ++++++++++++++------------ 2 files changed, 502 insertions(+), 454 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 96e575e495..2c0bc88e5b 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -307,7 +307,8 @@ get_config_var_string() { INSTALL_ROCPROF_REGISTER|AOMP_PROF_REGISTER_REPO_NAME|\ INSTALL_ROCPROF|AOMP_PROF_REPO_NAME|\ INSTALL_ROCPROF_SDK|AOMP_PROF_SDK_REPO_NAME|\ - INSTALL_ROCTRACE|AOMP_TRACE_REPO_NAME|HIP_PLATFORM) + INSTALL_ROCTRACE|AOMP_TRACE_REPO_NAME|HIP_PLATFORM|\ + RUNTIMES_BUILD_DIR) ;; *) >&2 echo "Unknown string configuration variable '$2'" diff --git a/bin/build_llvm_runtimes_standalone.sh b/bin/build_llvm_runtimes_standalone.sh index 0add32861b..c4edc4a44a 100755 --- a/bin/build_llvm_runtimes_standalone.sh +++ b/bin/build_llvm_runtimes_standalone.sh @@ -4,267 +4,340 @@ # This script will install in location defined by AOMP env variable # +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=$(realpath "$0") +realpath=$(realpath -- "$0") thisdir=$(dirname "$realpath") +. "$thisdir/aomp_utils" . "$thisdir/aomp_common_vars" # --- end standard header ---- +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string llvm_runtimes_standalone "$1" +} + +cfgbool() { + get_config_var_bool llvm_runtimes_standalone "$1" +} + if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then help_build_aomp fi REPO_DIR=$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME _ompd_src_dir="$LLVM_INSTALL_LOC/share/gdb/python/ompd/src" -OPENMP_BUILD_DEVICERTL=${OPENMP_BUILD_DEVICERTL:-0} RUNTIMES_BUILD_DIR=${RUNTIMES_BUILD_DIR:-"llvm_runtimes_standalone"} -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - CUDAH=$(find "$CUDAT" -type f,l -name "cuda.h" 2>/dev/null) - if [ "$CUDAH" == "" ] ; then - CUDAH=$(find "$CUDAINCLUDE" -type f,l -name "cuda.h" 2>/dev/null) +get_src_dir() { + echo "$REPO_DIR/runtimes" +} + +# Return success if the config is a "device runtime library" pass, which builds +# the same set of variants in a separate build directory with the amdgcn +# default target triple. +devicertl_config() { + local Cfg=$1 + case "$Cfg" in + *-devicertl) + return 0 + ;; + *) + ;; + esac + return 1 +} + +asan_config() { + local Cfg=${1%-devicertl} + case "$Cfg" in + asan|*+asan) + return 0 + ;; + *) + ;; + esac + return 1 +} + +debug_config() { + local Cfg=${1%-devicertl} + case "$Cfg" in + debug|debug+*) + return 0 + ;; + *) + ;; + esac + return 1 +} + +perf_config() { + local Cfg=${1%-devicertl} + case "$Cfg" in + perf|perf+*) + return 0 + ;; + *) + ;; + esac + return 1 +} + +# Print the base build directory name (without variant suffix) for a config. +runtimes_dir_base() { + local Cfg=$1 + if devicertl_config "$Cfg"; then + echo -n "$(cfgvar RUNTIMES_BUILD_DIR)-devicertl" + else + echo -n "$(cfgvar RUNTIMES_BUILD_DIR)" fi - if [ "$CUDAH" == "" ] ; then - echo - echo "ERROR: THE cuda.h FILE WAS NOT FOUND WITH ARCH $AOMP_PROC" - echo " A CUDA installation is necessary to build libomptarget deviceRTLs" - echo " Please install CUDA to build llvm_runtimes_standalone" - echo +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + local Base=${Cfg%-devicertl} + local BuildDir + local DirBase + BuildDir="$(cfgvar BUILD_DIR)" + DirBase="$(runtimes_dir_base "$Cfg")" + + case "$Base" in + "asan") + echo -n "$BuildDir/$DirBase/asan" + ;; + "perf") + echo -n "$BuildDir/${DirBase}_perf" + ;; + "perf+asan") + echo -n "$BuildDir/${DirBase}_perf/asan" + ;; + "debug") + echo -n "$BuildDir/${DirBase}_debug" + ;; + "debug+asan") + echo -n "$BuildDir/${DirBase}_debug/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$LLVM_INSTALL_LOC" +} + +# Print the OFFLOAD/LLVM libdir suffix for a given config. +libdir_suffix() { + local Cfg=${1%-devicertl} + case "$Cfg" in + asan) + printf "%s" "/asan" + ;; + perf) + printf "%s" "-perf" + ;; + perf+asan) + printf "%s" "-perf/asan" + ;; + debug) + printf "%s" "-debug" + ;; + debug+asan) + printf "%s" "-debug/asan" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +task_precheck() { + local CUDAH + local CUDAVER + local CUDATop + local CUDAInclude + local CUDABin + local AOMPProc + + if [ ! -d "$REPO_DIR" ] ; then + echo "ERROR: Missing repository $REPO_DIR " + echo " Consider setting env variables AOMP_REPOS and/or AOMP_PROJECT_REPO_NAME " exit 1 fi - # I don't see now nvcc is called, but this eliminates the deprecated warnings - export CUDAFE_FLAGS="-w" -fi -if [ ! -d "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME" ] ; then - echo "ERROR: Missing repository $AOMP_REPOS/$AOMP_PROJECT_REPO_NAME " - echo " Consider setting env variables AOMP_REPOS and/or AOMP_PROJECT_REPO_NAME " - exit 1 -fi + check_writable_installdir "$1" "$LLVM_INSTALL_LOC" -check_writable_installdir "$1" "$LLVM_INSTALL_LOC" + if "$(cfgbool AOMP_BUILD_CUDA)"; then + CUDATop=$(cfgvar CUDAT) + CUDAH=$(find "$CUDATop" -type f,l -name "cuda.h" 2>/dev/null) + if [ "$CUDAH" == "" ] ; then + CUDAInclude=$(cfgvar CUDAINCLUDE) + CUDAH=$(find "$CUDAInclude" -type f,l -name "cuda.h" 2>/dev/null) + fi + if [ "$CUDAH" == "" ] ; then + AOMPProc=$(cfgvar AOMP_PROC) + echo + echo "ERROR: THE cuda.h FILE WAS NOT FOUND WITH ARCH $AOMPProc" + echo " A CUDA installation is necessary to build libomptarget deviceRTLs" + echo " Please install CUDA to build llvm_runtimes_standalone" + echo + exit 1 + fi + # I don't see now nvcc is called, but this eliminates the deprecated warnings + export CUDAFE_FLAGS="-w" -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - if [ -f "$CUDABIN/nvcc" ] ; then - CUDAVER=$("$CUDABIN"/nvcc --version | grep compilation | cut -d" " -f5 | cut -d"." -f1) - echo "CUDA VERSION IS $CUDAVER" + CUDABin=$(cfgvar CUDABIN) + if [ -f "$CUDABin/nvcc" ] ; then + CUDAVER=$("$CUDABin"/nvcc --version | grep compilation | cut -d" " -f5 | cut -d"." -f1) + echo "CUDA VERSION IS $CUDAVER" + fi fi -fi - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN=() -else - AOMP_SET_NINJA_GEN=(-G Ninja) -fi - -export LLVM_DIR=$AOMP_INSTALL_DIR -GFXSEMICOLONS=$(echo "$GFXLIST" | tr ' ' ';') -ALTAOMP=${ALTAOMP:-$LLVM_INSTALL_LOC} - -LLVM_VERSION_MAJOR=$("${LLVM_INSTALL_LOC}"/bin/clang --version | grep -oP '(?<=clang version )[0-9]+') - -declare -a COMMON_CMAKE_OPTS - -COMMON_CMAKE_OPTS=("${AOMP_SET_NINJA_GEN[@]}" -DOPENMP_ENABLE_LIBOMPTARGET=1 - -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" - -DOPENMP_TEST_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" - -DOPENMP_TEST_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" - -DCMAKE_C_COMPILER="$ALTAOMP/bin/clang" - -DCMAKE_CXX_COMPILER="$ALTAOMP/bin/clang++" - -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" - -DLIBOMPTARGET_ENABLE_DEBUG=ON - -DDEVICELIBS_ROOT="$DEVICELIBS_ROOT" - -DLIBOMP_COPY_EXPORTS=OFF - -DLIBOMPTEST_INSTALL_COMPONENTS=ON - -DLLVM_DIR="$LLVM_DIR" - -DLIBOMPTEST_BUILD_STANDALONE=1 -DLIBOMPTARGET_BUILD_DEVICE_FORTRT=On) - -LLVM_RUNTIMES="openmp;offload" -if [ "$OPENMP_BUILD_DEVICERTL" -eq 1 ]; then - if [ -f "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/device/CMakeLists.txt" ]; then - LLVM_RUNTIMES=openmp - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_DEFAULT_TARGET_TRIPLE=amdgcn-amd-amdhsa - -DLLVM_ENABLE_RUNTIMES="$LLVM_RUNTIMES") - fi -fi - -COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_BINARY_DIR="$LLVM_INSTALL_LOC" - -DLLVM_ENABLE_RUNTIMES="$LLVM_RUNTIMES" - -DCLANG_VERSION_MAJOR="$LLVM_VERSION_MAJOR") - -if [ "$AOMP_STANDALONE_BUILD" == 0 ]; then - # For static package builds, set BUILD_SHARED_LIBS to OFF - if [ "$STATIC_PKG_DEPS" == "ON" ]; then - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" -DBUILD_SHARED_LIBS=OFF) - fi + return 0 +} + +task_patch() { + # Patch llvm-project with ATD patch customized for amd-staging. + # WARNING: This patch (ATD_ASO_full.patch) rarely applies cleanly + # because of its size and constant trunk merges to amd-staging. + # This is why default is 0 (OFF). + if "$(cfgbool AOMP_APPLY_ATD_AMD_STAGING_PATCH)" ; then + patchrepo "$REPO_DIR" + fi +} - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_MAIN_INCLUDE_DIR="$LLVM_PROJECT_ROOT/llvm/include" - -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$LLVM_PROJECT_ROOT/llvm/include" - -DROCM_DIR="$ROCM_DIR" - -DAOMP_STANDALONE_BUILD="$AOMP_STANDALONE_BUILD" - -DCMAKE_MODULE_PATH="$LLVM_PROJECT_ROOT/llvm/cmake/modules") -else - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLLVM_MAIN_INCLUDE_DIR="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/include" - -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/include" - -DCMAKE_MODULE_PATH="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/llvm/cmake/modules" - -DLLVM_INSTALL_PREFIX="$LLVM_INSTALL_LOC") -fi +task_unpatch() { + if "$(cfgbool AOMP_APPLY_ATD_AMD_STAGING_PATCH)" ; then + removepatch "$REPO_DIR" + fi +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local SrcDir + local BuildDir + local AompCmake + local UseNinja + local Standalone + local GFXSEMICOLONS + local LlvmVersionMajor + local LlvmRuntimes + local LibdirSuffix + local Altaomp + local -a AOMP_SET_NINJA_GEN + local -a MYCMAKEOPTS + local -a DEBUGCMAKEOPTS + + SrcDir="$(get_src_dir)" + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + UseNinja="$(cfgbool AOMP_USE_NINJA)" + Standalone="$(cfgbool AOMP_STANDALONE_BUILD)" + Altaomp="$(cfgvar ALTAOMP)" + + if "$UseNinja"; then + AOMP_SET_NINJA_GEN=(-G Ninja) + fi -if [ "$AOMP_BUILD_CUDA" == 1 ] ; then - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DLIBOMPTARGET_NVPTX_ENABLE_BCLIB=ON - -DLIBOMPTARGET_NVPTX_CUDA_COMPILER="$AOMP/bin/clang++" - -DLIBOMPTARGET_NVPTX_BC_LINKER="$AOMP/bin/llvm-link" - -DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES="$NVPTXGPUS") -else -# Need to force CUDA off this way in case cuda is installed in this system - COMMON_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCUDA_TOOLKIT_ROOT_DIR=OFF) -fi + export LLVM_DIR=$AOMP_INSTALL_DIR + GFXSEMICOLONS=$(cfgvar GFXLIST | tr ' ' ';') + LlvmVersionMajor=$("${LLVM_INSTALL_LOC}"/bin/clang --version | grep -oP '(?<=clang version )[0-9]+') + + # This is how we tell the hsa plugin where to find hsa + export HSA_RUNTIME_PATH=$ROCM_DIR + + # Settings common to every config. + MYCMAKEOPTS=("${AOMP_SET_NINJA_GEN[@]}" + -DOPENMP_ENABLE_LIBOMPTARGET=1 + -DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_LOC" + -DOPENMP_TEST_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DOPENMP_TEST_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DCMAKE_C_COMPILER="$Altaomp/bin/clang" + -DCMAKE_CXX_COMPILER="$Altaomp/bin/clang++" + -DLIBOMPTARGET_AMDGCN_GFXLIST="$GFXSEMICOLONS" + -DLIBOMPTARGET_ENABLE_DEBUG=ON + -DDEVICELIBS_ROOT="$DEVICELIBS_ROOT" + -DLIBOMP_COPY_EXPORTS=OFF + -DLIBOMPTEST_INSTALL_COMPONENTS=ON + -DLLVM_DIR="$LLVM_DIR" + -DLIBOMPTEST_BUILD_STANDALONE=1 + -DLIBOMPTARGET_BUILD_DEVICE_FORTRT=On) + + LlvmRuntimes="openmp;offload" + # The device runtime library pass builds only openmp for the amdgcn triple. + if devicertl_config "$Cfg"; then + if [ -f "$REPO_DIR/openmp/device/CMakeLists.txt" ]; then + LlvmRuntimes=openmp + MYCMAKEOPTS+=(-DLLVM_DEFAULT_TARGET_TRIPLE=amdgcn-amd-amdhsa) + fi + fi -# This is how we tell the hsa plugin where to find hsa -export HSA_RUNTIME_PATH=$ROCM_DIR + MYCMAKEOPTS+=(-DLLVM_BINARY_DIR="$LLVM_INSTALL_LOC" + -DLLVM_ENABLE_RUNTIMES="$LlvmRuntimes" + -DCLANG_VERSION_MAJOR="$LlvmVersionMajor") -# Patch llvm-project with ATD patch customized for amd-staging. -# WARNING: This patch (ATD_ASO_full.patch) rarely applies cleanly -# because of its size and constant trunk merges to amd-staging. -# This is why default is 0 (OFF). -if [ "$AOMP_APPLY_ATD_AMD_STAGING_PATCH" == 1 ] ; then - patchrepo "$REPO_DIR" -fi + if ! "$Standalone"; then + # For static package builds, set BUILD_SHARED_LIBS to OFF + if [ "$STATIC_PKG_DEPS" == "ON" ]; then + MYCMAKEOPTS+=(-DBUILD_SHARED_LIBS=OFF) + fi + MYCMAKEOPTS+=(-DLLVM_MAIN_INCLUDE_DIR="$LLVM_PROJECT_ROOT/llvm/include" + -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$LLVM_PROJECT_ROOT/llvm/include" + -DROCM_DIR="$ROCM_DIR" + -DAOMP_STANDALONE_BUILD="$(cfgvar AOMP_STANDALONE_BUILD)" + -DCMAKE_MODULE_PATH="$LLVM_PROJECT_ROOT/llvm/cmake/modules") + else + MYCMAKEOPTS+=(-DLLVM_MAIN_INCLUDE_DIR="$REPO_DIR/llvm/include" + -DLIBOMPTARGET_LLVM_INCLUDE_DIRS="$REPO_DIR/llvm/include" + -DCMAKE_MODULE_PATH="$REPO_DIR/llvm/cmake/modules" + -DLLVM_INSTALL_PREFIX="$LLVM_INSTALL_LOC") + fi -declare -a ASAN_CMAKE_OPTS - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo " " - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/llvm_runtimes_standalone." - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - echo "rm -rf $BUILD_DIR/build/$RUNTIMES_BUILD_DIR" - rm -rf "$BUILD_DIR/build/$RUNTIMES_BUILD_DIR" - declare -a MYCMAKEOPTS - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DCMAKE_BUILD_TYPE=Release "${AOMP_ORIGIN_RPATH[@]}") + if "$(cfgbool AOMP_BUILD_CUDA)"; then + MYCMAKEOPTS+=(-DLIBOMPTARGET_NVPTX_ENABLE_BCLIB=ON + -DLIBOMPTARGET_NVPTX_CUDA_COMPILER="$AOMP/bin/clang++" + -DLIBOMPTARGET_NVPTX_BC_LINKER="$AOMP/bin/llvm-link" + -DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES="$NVPTXGPUS") else - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$INSTALL_PREFIX/lib/cmake" - -DCMAKE_BUILD_TYPE=Release "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - - # XXX: Crude way to detect if we should enable building the mod files with flang. - # Is it preferrable to set it from the outside or based on branch name, some other in-tree file? - AOMP_BUILD_MODFILES_WITH_FLANG_NEW=0 - if [ -e "${LLVM_INSTALL_LOC}/bin/flang" ]; then - AOMP_BUILD_MODFILES_WITH_FLANG_NEW=1 - fi - - if [ "$AOMP_BUILD_MODFILES_WITH_FLANG_NEW" == 1 ]; then - echo "Building .mod files via: $LLVM_INSTALL_LOC/bin/flang" - echo "Installing .mod files to: $LLVM_INSTALL_LOC/include/flang/" - MYCMAKEOPTS=("${MYCMAKEOPTS[@]}" - -DLIBOMP_FORTRAN_MODULES_COMPILER="$LLVM_INSTALL_LOC/bin/flang" - -DLIBOMP_MODULES_INSTALL_PATH="$LLVM_INSTALL_LOC/include/flang/") - fi + # Need to force CUDA off this way in case cuda is installed in this system + MYCMAKEOPTS+=(-DCUDA_TOOLKIT_ROOT_DIR=OFF) fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DSANITIZER_AMDGPU=1 -DCMAKE_BUILD_TYPE=Release - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - "${AOMP_ASAN_ORIGIN_RPATH[@]}") - else - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH;$INSTALL_PREFIX/lib/llvm/lib/asan" - -DSANITIZER_AMDGPU=1 -DCMAKE_BUILD_TYPE=Release - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - fi - echo " -----Running llvm_runtimes_standalone cmake for asan ---- " - mkdir -p "$BUILD_DIR/build/$RUNTIMES_BUILD_DIR/asan" - cd "$BUILD_DIR/build/$RUNTIMES_BUILD_DIR/asan" || exit - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DOFFLOAD_LIBDIR_SUFFIX="/asan" \ - -DLLVM_LIBDIR_SUFFIX="/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes" - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DOFFLOAD_LIBDIR_SUFFIX="/asan" \ - -DLLVM_LIBDIR_SUFFIX="/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes"; then - echo "ERROR llvm_runtimes_standalone cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi + # Variant-specific settings. + if perf_config "$Cfg"; then + MYCMAKEOPTS+=(-DLIBOMPTARGET_ENABLE_DEBUG=OFF + -DCMAKE_BUILD_TYPE=Release + -DLIBOMPTARGET_PERF=ON) + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF + -DSANITIZER_AMDGPU=1 + "${AOMP_ASAN_ORIGIN_RPATH[@]}" + -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" + "${AOMP_ORIGIN_RPATH[@]}") fi - - # Build a dedicatd "performance" version of libomptarget - if [ "$AOMP_BUILD_PERF" == "1" ]; then - echo "rm -rf $BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf" - rm -rf "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DLIBOMPTARGET_ENABLE_DEBUG=OFF -DCMAKE_BUILD_TYPE=Release - -DLIBOMPTARGET_PERF=ON -DOFFLOAD_LIBDIR_SUFFIX=-perf - -DLLVM_LIBDIR_SUFFIX="-perf") - mkdir -p "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf" - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf" || exit - echo " -----Running llvm_runtimes_standalone cmake for perf ---- " - echo "${AOMP_CMAKE}" "$(shquot "${MYCMAKEOPTS[@]}")" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes" \ - "$(shquot "${AOMP_ORIGIN_RPATH[@]}")" - - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes" \ - "${AOMP_ORIGIN_RPATH[@]}"; then - echo "error llvm_runtimes_standalone cmake failed. cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - -DLIBOMPTARGET_ENABLE_DEBUG=OFF - -DCMAKE_BUILD_TYPE=Release - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DLIBOMPTARGET_PERF=ON -DSANITIZER_AMDGPU=1 - "${AOMP_ASAN_ORIGIN_RPATH[@]}") - echo " -----Running llvm_runtimes_standalone cmake for perf-asan ---- " - mkdir -p "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf/asan" - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf/asan" || exit - echo "${AOMP_CMAKE}" "$(shquot "${ASAN_CMAKE_OPTS[@]}")" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DOFFLOAD_LIBDIR_SUFFIX="-perf/asan" \ - -DLLVM_LIBDIR_SUFFIX="-perf/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DOFFLOAD_LIBDIR_SUFFIX="-perf/asan" \ - -DLLVM_LIBDIR_SUFFIX="-perf/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes"; then - echo "error llvm_runtimes_standalone cmake failed. cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 - fi - fi - fi - - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - _prefix_map=(-fdebug-prefix-map="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload=$_ompd_src_dir/offload") - - declare -a DEBUGCMAKEOPTS - + elif debug_config "$Cfg"; then DEBUGCMAKEOPTS=(-DLIBOMPTARGET_NVPTX_DEBUG=ON -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=Debug @@ -280,254 +353,228 @@ if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then # the system option if the debian_version file is not present. if [ ! -f /etc/debian_version ]; then echo "==> Non-Debian OS, disabling use of pip install --system" - DEBUGCMAKEOPTS=("${DEBUGCMAKEOPTS[@]}" -DDISABLE_SYSTEM_NON_DEBIAN=1) + DEBUGCMAKEOPTS+=(-DDISABLE_SYSTEM_NON_DEBIAN=1) fi # Redhat 7.6 does not have python36-devel package, which is needed for ompd compilation. # This is acquired through RH Software Collections. if [ -f /opt/rh/rh-python36/enable ]; then echo "==> Using python3.6 out of rh tools." - DEBUGCMAKEOPTS=("${DEBUGCMAKEOPTS[@]}" - -DPython3_ROOT_DIR=/opt/rh/rh-python36/root/bin - -DPYTHON_HEADERS=/opt/rh/rh-python36/root/usr/include/python3.6m) + DEBUGCMAKEOPTS+=(-DPython3_ROOT_DIR=/opt/rh/rh-python36/root/bin + -DPYTHON_HEADERS=/opt/rh/rh-python36/root/usr/include/python3.6m) fi - echo - if [ "$SANITIZER" != 1 ] ; then - echo "rm -rf $BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug" - rm -rf "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug" - echo " -----Running llvm_runtimes_standalone cmake for debug ---- " - mkdir -p "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug" - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug" || exit - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - PREFIX_PATH="-DCMAKE_PREFIX_PATH=$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - "${AOMP_DEBUG_ORIGIN_RPATH[@]}") - else - PREFIX_PATH="-DCMAKE_PREFIX_PATH=$INSTALL_PREFIX/lib/cmake" - MYCMAKEOPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") - fi + MYCMAKEOPTS+=("${DEBUGCMAKEOPTS[@]}") - if ! ${AOMP_CMAKE} "${MYCMAKEOPTS[@]}" "$PREFIX_PATH" \ - -DCMAKE_C_FLAGS="$CFLAGS -g" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS -g $(cmquot "${_prefix_map[@]}")" \ - -DOFFLOAD_LIBDIR_SUFFIX="-debug" \ - -DLLVM_LIBDIR_SUFFIX="-debug" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes"; then - echo "ERROR llvm_runtimes_standalone debug cmake failed. Cmake flags" - echo " $(shquot "${MYCMAKEOPTS[@]}")" - exit 1 - fi - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ]; then - ASAN_CMAKE_OPTS=("${COMMON_CMAKE_OPTS[@]}" "${DEBUGCMAKEOPTS[@]}" - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF - -DSANITIZER_AMDGPU=1) - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" - "${AOMP_ASAN_ORIGIN_RPATH[@]}") + if asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF + -DSANITIZER_AMDGPU=1) + if "$Standalone"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" + "${AOMP_ASAN_ORIGIN_RPATH[@]}") else - ASAN_CMAKE_OPTS=("${ASAN_CMAKE_OPTS[@]}" - -DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH;$INSTALL_PREFIX/lib/llvm/lib/asan" - "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH;$INSTALL_PREFIX/lib/llvm/lib/asan" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi - echo " -----Running llvm_runtimes_standalone cmake for debug-asan ---- " - mkdir -p "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug/asan" - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug/asan" || exit - echo "${AOMP_CMAKE}" "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DCMAKE_CXX_FLAGS="\"$(cmquot "${ASAN_FLAGS[@]}")\"" \ - -DOFFLOAD_LIBDIR_SUFFIX="-debug/asan" \ - -DLLVM_LIBDIR_SUFFIX="-debug/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes" - - if ! ${AOMP_CMAKE} "${ASAN_CMAKE_OPTS[@]}" \ - -DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" \ - -DOFFLOAD_LIBDIR_SUFFIX="-debug/asan" \ - -DLLVM_LIBDIR_SUFFIX="-debug/asan" \ - "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/runtimes"; then - echo "ERROR llvm_runtimes_standalone debug cmake failed. Cmake flags" - echo " $(shquot "${ASAN_CMAKE_OPTS[@]}")" - exit 1 + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") + else + local -a _prefix_map + _prefix_map=(-fdebug-prefix-map="$REPO_DIR/offload=$_ompd_src_dir/offload") + if "$Standalone"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" + "${AOMP_DEBUG_ORIGIN_RPATH[@]}") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$INSTALL_PREFIX/lib/cmake" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$CFLAGS -g" + -DCMAKE_CXX_FLAGS="$CXXFLAGS -g $(cmquot "${_prefix_map[@]}")") + fi + elif asan_config "$Cfg"; then + MYCMAKEOPTS+=(-DSANITIZER_AMDGPU=1 + -DCMAKE_BUILD_TYPE=Release + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF) + if "$Standalone"; then + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR/lib/cmake;$AOMP_INSTALL_DIR/lib64/cmake" + "${AOMP_ASAN_ORIGIN_RPATH[@]}") + else + MYCMAKEOPTS+=(-DCMAKE_PREFIX_PATH="$ROCM_CMAKECONFIG_PATH;$INSTALL_PREFIX/lib/llvm/lib/asan" + "${OPENMP_EXTRAS_ORIGIN_RPATH[@]}") fi + MYCMAKEOPTS+=(-DCMAKE_C_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")" + -DCMAKE_CXX_FLAGS="$(cmquot "${ASAN_FLAGS[@]}")") fi -fi -if [ "$1" = "cmake" ]; then - exit 0 -fi + # OFFLOAD/LLVM libdir suffix options + LibdirSuffix=$(libdir_suffix "$Cfg") + MYCMAKEOPTS+=(-DOFFLOAD_LIBDIR_SUFFIX="$LibdirSuffix" + -DLLVM_LIBDIR_SUFFIX="$LibdirSuffix") -if [ "$1" != "install" ] ; then - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/$RUNTIMES_BUILD_DIR/asan" || exit - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/$RUNTIMES_BUILD_DIR/asan ---- " + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running llvm_runtimes_standalone $Cfg cmake ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR llvm_runtimes_standalone $Cfg cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local NinjaBin + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + NinjaBin="$(cfgvar AOMP_NINJA_BIN)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $NinjaBin for $BuildDir ---- " + if ! $NinjaBin -j "$Jobs"; then echo " " - echo "ERROR: $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS FAILED" + echo "ERROR: $NinjaBin -j $Jobs FAILED" echo "To restart:" - echo " cd $BUILD_DIR/build/$RUNTIMES_BUILD_DIR/asan" - echo " $AOMP_NINJA_BIN" + echo " cd $BuildDir" + echo " $NinjaBin" exit 1 - fi - fi - - if [ "$AOMP_BUILD_PERF" == "1" ] ; then - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local NinjaBin + local Jobs + local LibdirSuffix + BuildDir="$(get_build_dir "$Cfg")" + NinjaBin="$(cfgvar AOMP_NINJA_BIN)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + LibdirSuffix=$(libdir_suffix "$Cfg") + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $LLVM_INSTALL_LOC/lib${LibdirSuffix} ----- " + + if ! $SUDO "$NinjaBin" -j "$Jobs" install; then + echo "ERROR $NinjaBin install failed " exit 1 - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf/asan" || exit - echo - echo - echo " ----- Running $AOMP_NINJA_BIN for $BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf/asan ----- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 - fi - fi - fi - - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - if [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 - fi - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug/asan" || exit - echo - echo - echo " -----Running $AOMP_NINJA_BIN for $BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug/asan ---- " - - if ! $AOMP_NINJA_BIN -j "$AOMP_JOB_THREADS"; then - echo "ERROR $AOMP_NINJA_BIN -j $AOMP_JOB_THREADS failed" - exit 1 - fi - fi + fi + popd >& /dev/null || exit +} + +task_postinstall() { + local Cfg=$1 + local Standalone + local _from_dir_src + local _from_dir_plugins + Standalone="$(cfgbool AOMP_STANDALONE_BUILD)" + + # Copy selected debugable runtime sources into the installation directory + # $_ompd_src_dir directory to satisfy the debug -fdebug-prefix-map. + $SUDO mkdir -p "$_ompd_src_dir/offload" + $SUDO mkdir -p "$_ompd_src_dir/offload/plugins-nextgen" + if "$Standalone"; then + _from_dir_src="$REPO_DIR/offload/libomptarget" + _from_dir_plugins="$REPO_DIR/offload/plugins-nextgen" + else + _from_dir_src="$LLVM_PROJECT_ROOT/offload/libomptarget" + _from_dir_plugins="$LLVM_PROJECT_ROOT/offload/plugins-nextgen" + fi + echo cp -rp "$_from_dir_src" "$_ompd_src_dir/offload" + $SUDO cp -rp "$_from_dir_src" "$_ompd_src_dir/offload" + echo cp -rp "$_from_dir_plugins" "$_ompd_src_dir/offload" + $SUDO cp -rp "$_from_dir_plugins" "$_ompd_src_dir/offload" + + # Copy selected debugable runtime sources into the installation + # $_ompd_src_dir/src directory to satisfy the debug -fdebug-prefix-map. + $SUDO mkdir -p "$_ompd_src_dir/openmp/runtime" + $SUDO mkdir -p "$_ompd_src_dir/openmp/libompd" + $SUDO mkdir -p "$_ompd_src_dir/openmp/device" + if "$Standalone"; then + $SUDO cp -rp "$REPO_DIR/openmp/runtime/src" "$_ompd_src_dir/openmp/runtime" + $SUDO cp -rp "$REPO_DIR/openmp/libompd/src" "$_ompd_src_dir/openmp/libompd" + $SUDO cp -rp "$REPO_DIR/openmp/device/src" "$_ompd_src_dir/openmp/device" + else + $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/runtime/src" "$_ompd_src_dir/openmp/runtime" + $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/libompd/src" "$_ompd_src_dir/openmp/libompd" + $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/device/src" "$_ompd_src_dir/openmp/device" + fi +} + +do_list_configs() { + local Sanitizer + local BuildSanitizer + local BuildPerf + local BuildDebug + local -a cfgs + local c + + Sanitizer="$(cfgbool SANITIZER)" + BuildSanitizer="$(cfgbool AOMP_BUILD_SANITIZER)" + BuildPerf="$(cfgbool AOMP_BUILD_PERF)" + BuildDebug="$(cfgbool AOMP_BUILD_DEBUG)" + + cfgs=() + if "$BuildSanitizer"; then + cfgs+=("asan") fi - - echo - echo "Successful build of ./build_llvm_runtimes_standalone.sh . Please run:" - echo " ./build_llvm_runtimes_standalone.sh install " - echo -fi - -# ----------- Install only if asked ---------------------------- -if [ "$1" == "install" ] ; then - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/$RUNTIMES_BUILD_DIR/asan" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib/asan ----- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 + if "$BuildPerf"; then + cfgs+=("perf") + if "$BuildSanitizer"; then + cfgs+=("perf+asan") fi fi - - if [ "$AOMP_BUILD_PERF" == "1" ]; then - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib-perf ----- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 + if "$BuildDebug" ; then + if ! "$Sanitizer"; then + cfgs+=("debug") fi - - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_perf/asan" || exit - echo - echo " ----- Installing to $LLVM_INSTALL_LOC/lib-perf/asan ----- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi + if "$BuildSanitizer"; then + cfgs+=("debug+asan") fi fi - if [ "$AOMP_BUILD_DEBUG" == "1" ] ; then - if [ "$SANITIZER" != 1 ] ; then - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug" || exit - echo - echo " -----Installing to $LLVM_INSTALL_LOC/lib-debug ---- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - fi - if [ "$AOMP_BUILD_SANITIZER" == 1 ] ; then - cd "$BUILD_DIR/build/${RUNTIMES_BUILD_DIR}_debug/asan" || exit - echo " -----Installing to $LLVM_INSTALL_LOC/lib-debug/asan ---- " - - if ! $SUDO "$AOMP_NINJA_BIN" -j "$AOMP_JOB_THREADS" install; then - echo "ERROR $AOMP_NINJA_BIN install failed " - exit 1 - fi - fi - - # Copy selected debugable runtime sources into the installation directory - # $_ompd_src_dir directory to satisfy the above CXXOPT -fdebug-prefix-map. - $SUDO mkdir -p "$_ompd_src_dir/offload" - $SUDO mkdir -p "$_ompd_src_dir/offload/plugins-nextgen" - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - _from_dir_src="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload/libomptarget" - _from_dir_plugins="$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/offload/plugins-nextgen" - else - _from_dir_src="$LLVM_PROJECT_ROOT/offload/libomptarget" - _from_dir_plugins="$LLVM_PROJECT_ROOT/offload/plugins-nextgen" - fi - echo cp -rp "$_from_dir_src" "$_ompd_src_dir/offload" - $SUDO cp -rp "$_from_dir_src" "$_ompd_src_dir/offload" - echo cp -rp "$_from_dir_plugins" "$_ompd_src_dir/offload" - $SUDO cp -rp "$_from_dir_plugins" "$_ompd_src_dir/offload" - - # Copy selected debugable runtime sources into the installation $ompd_src_dir/src directory - # to satisfy the above -fdebug-prefix-map. - $SUDO mkdir -p "$_ompd_src_dir/openmp/runtime" - $SUDO mkdir -p "$_ompd_src_dir/openmp/libompd" - $SUDO mkdir -p "$_ompd_src_dir/openmp/device" - if [ "$AOMP_STANDALONE_BUILD" == 1 ]; then - $SUDO cp -rp "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/runtime/src" "$_ompd_src_dir/openmp/runtime" - $SUDO cp -rp "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/libompd/src" "$_ompd_src_dir/openmp/libompd" - $SUDO cp -rp "$AOMP_REPOS/$AOMP_PROJECT_REPO_NAME/openmp/device/src" "$_ompd_src_dir/openmp/device" - else - $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/runtime/src" "$_ompd_src_dir/openmp/runtime" - $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/libompd/src" "$_ompd_src_dir/openmp/libompd" - $SUDO cp -rp "$LLVM_PROJECT_ROOT/openmp/device/src" "$_ompd_src_dir/openmp/device" - fi - fi # end of AOMP_BUILD_DEBUG install block - - if [ "$AOMP_APPLY_ATD_AMD_STAGING_PATCH" == 1 ] ; then - removepatch "$REPO_DIR" + # First build/install every variant in the host build dir, then repeat the + # whole set as a device runtime library pass in the -devicertl dir. + for c in "${cfgs[@]}"; do + echo "$c" + done + for c in "${cfgs[@]}"; do + echo "$c-devicertl" + done +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + case "$Cfg" in + debug) + echo "postinstall" + ;; + *) + ;; + esac + else + echo "Unknown config '$Cfg'" fi +} -fi # end of install block - -# We have to build the deviceRTL by itself as it requires a different target -if [ "$1" != "install" ] && [ "$OPENMP_BUILD_DEVICERTL" == 0 ] ; then - RUNTIMES_BUILD_DIR="llvm_runtimes_standalone-devicertl" OPENMP_BUILD_DEVICERTL=1 "$thisdir"/build_llvm_runtimes_standalone.sh -fi -if [ "$1" == "install" ] && [ "$OPENMP_BUILD_DEVICERTL" == 0 ]; then - RUNTIMES_BUILD_DIR="llvm_runtimes_standalone-devicertl" OPENMP_BUILD_DEVICERTL=1 "$thisdir"/build_llvm_runtimes_standalone.sh install -fi +command_dispatcher "$@" From 0e26b2c69c2620c2ed124ecf550dac522f009abd Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 10:52:18 -0500 Subject: [PATCH 40/71] Taskify build_rocPRIM.sh --- bin/rocmlibs/build_rocPRIM.sh | 294 ++++++++++++++++++++++------------ 1 file changed, 190 insertions(+), 104 deletions(-) diff --git a/bin/rocmlibs/build_rocPRIM.sh b/bin/rocmlibs/build_rocPRIM.sh index e6ab223383..ea060b800b 100755 --- a/bin/rocmlibs/build_rocPRIM.sh +++ b/bin/rocmlibs/build_rocPRIM.sh @@ -7,126 +7,212 @@ # # build_rocPRIM.sh: Script to build and install rocPRIM library # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -# Patch rocr -_repo_dir=$AOMP_REPOS/rocmlibs/rocPRIM -patchrepo $_repo_dir - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN="" -else - AOMP_SET_NINJA_GEN="-G Ninja" -fi - -GFXSEMICOLONS=`echo $GFXLIST | tr ' ' ';' ` -GFXSEMICOLONS=""$GFXSEMICOLONS"" -#export CC=$AOMP/bin/clang -export CXX=$AOMP_INSTALL_DIR/bin/hipcc -export ROCM_DIR=$AOMP -export ROCM_PATH=$AOMP -export HIP_DIR=$AOMP -export PATH=$AOMP_SUPP/cmake/bin:$AOMP/bin:$PATH -export USE_PERL_SCRIPTS=1 -export NUM_PROC=$AOMP_JOB_THREADS -export CXXFLAGS="-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1" -export LDFLAGS="-fPIC" -export CMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC/lib/cmake" -MYCMAKEOPTS="-DCMAKE_BUILD_TYPE=$BUILD_TYPE \ --DCMAKE_CXX_COMPILER=$LLVM_INSTALL_LOC/bin/clang++ \ --DHIP_COMPILER=$LLVM_INSTALL_LOC/bin/clang \ --DHIP_CXX_COMPILER=$AOMP_INSTALL_DIR/bin/hipcc \ --DCMAKE_PREFIX_PATH=$LLVM_INSTALL_LOC/lib/cmake \ --DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR \ --DAMDGPU_TARGETS="""$ROCMLIBS_GFXLIST""" --DROCM_DIR=$ROCM_DIR \ --DROCM_PATH=$ROCM_PATH \ --DHIP_DIR=$HIP_DIR \ --DHIP_PLATFORM=amd \ -" - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocprim "$1" +} + +cfgbool() { + get_config_var_bool rocprim "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/rocPRIM" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/rocPRIM" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local AompSupp + local Jobs + AompSupp="$(cfgvar AOMP_SUPP)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + export CXX=$AOMP_INSTALL_DIR/bin/hipcc + export ROCM_DIR=$AOMP + export ROCM_PATH=$AOMP + export HIP_DIR=$AOMP + export PATH="$AompSupp/cmake/bin:$AOMP/bin:$PATH" + export USE_PERL_SCRIPTS=1 + export NUM_PROC="$Jobs" + export CXXFLAGS="-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1" + export LDFLAGS="-fPIC" + export CMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC/lib/cmake" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/rocPRIM" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - rm -rf $BUILD_DIR/build/rocmlibs/rocPRIM - mkdir -p $BUILD_DIR/build/rocmlibs/rocPRIM -else - if [ ! -d $BUILD_DIR/build/rocmlibs/rocPRIM ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/rocPRIM " - echo " run $0 without nocmake or install options. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi -cd $BUILD_DIR/build/rocmlibs/rocPRIM + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo " -----Running ${AOMP_CMAKE} ---- " - echo ${AOMP_CMAKE} $MYCMAKEOPTS $_repo_dir - env CXX=$AOMP/bin/hipcc ${AOMP_CMAKE} $MYCMAKEOPTS $_repo_dir 2>&1 - if [ $? != 0 ] ; then +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a AOMP_SET_NINJA_GEN + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + if "$(cfgbool AOMP_USE_NINJA)"; then + AOMP_SET_NINJA_GEN=(-G Ninja) + fi + + MYCMAKEOPTS=("${AOMP_SET_NINJA_GEN[@]}" + -DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DHIP_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DHIP_CXX_COMPILER="$AOMP_INSTALL_DIR/bin/hipcc" + -DCMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC/lib/cmake" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DAMDGPU_TARGETS="$Gfxlist" + -DROCM_DIR="$AOMP" + -DROCM_PATH="$AOMP" + -DHIP_DIR="$AOMP" + -DHIP_PLATFORM=amd) + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rocPRIM $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! env CXX="$AOMP/bin/hipcc" "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then echo "ERROR cmake failed. Cmake flags" - echo " $MYCMAKEOPTS" + echo " $(shquot "${MYCMAKEOPTS[@]}")" + exit 1 + fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local AompCmake + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + setup_env + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $AompCmake --build for rocPRIM $Cfg ---- " + echo "$AompCmake --build . -j $Jobs" + if ! env CXX="$AOMP_INSTALL_DIR/bin/hipcc" "$AompCmake" --build . -j "$Jobs"; then + echo "ERROR make -j $Jobs failed" exit 1 fi -fi - -echo -echo " -----Running ${AOMP_CMAKE} --build ---- " -echo ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS -env CXX=$AOMP_INSTALL_DIR/bin/hipcc ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS -if [ $? != 0 ] ; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" - exit 1 -fi - -if [ "$1" == "install" ] ; then - echo " -----Installing to $AOMP_INSTALL_DIR ---- " - $SUDO ${AOMP_CMAKE} --install . - if [ $? != 0 ] ; then + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local AompCmake + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! $SUDO "$AompCmake" --install .; then echo "ERROR make install failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From acb313b55d17fc33902ac09250ac6623d78c1e11 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 10:54:48 -0500 Subject: [PATCH 41/71] Taskify build_rocSPARSE.sh --- bin/rocmlibs/build_rocSPARSE.sh | 289 ++++++++++++++++++++------------ 1 file changed, 182 insertions(+), 107 deletions(-) diff --git a/bin/rocmlibs/build_rocSPARSE.sh b/bin/rocmlibs/build_rocSPARSE.sh index e66dd674d8..7eed3d817a 100755 --- a/bin/rocmlibs/build_rocSPARSE.sh +++ b/bin/rocmlibs/build_rocSPARSE.sh @@ -8,129 +8,204 @@ # build_rocsparse.sh: Script to build and install rocsparse library # # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -_repo_dir=$AOMP_REPOS/rocmlibs/rocSPARSE -patchrepo $_repo_dir - -export CC=$LLVM_INSTALL_LOC/bin/clang -export CXX=$LLVM_INSTALL_LOC/bin/clang++ -export ROCM_DIR=$AOMP_INSTALL_DIR -export ROCM_PATH=$AOMP_INSTALL_DIR -export PATH=$AOMP_SUPP/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH -export HIP_USE_PERL_SCRIPTS=1 -export USE_PERL_SCRIPTS=1 -export NUM_PROC=$AOMP_JOB_THREADS -export CXXFLAGS="-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1" -export LDFLAGS="-fPIC" -if [ "$AOMP_USE_CCACHE" != 0 ] ; then - _ccache_bin=`which ccache` - # export CMAKE_CXX_COMPILER_LAUNCHER=$_ccache_bin -fi - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -if [ "$1" == "nocmake" ] ; then - echo "ERROR: nocmake is not an option for $0" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocsparse "$1" +} + +cfgbool() { + get_config_var_bool rocsparse "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/rocSPARSE" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/rocSPARSE" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local AompSupp + local Jobs + AompSupp="$(cfgvar AOMP_SUPP)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + export CC=$LLVM_INSTALL_LOC/bin/clang + export CXX=$LLVM_INSTALL_LOC/bin/clang++ + export ROCM_DIR=$AOMP_INSTALL_DIR + export ROCM_PATH=$AOMP_INSTALL_DIR + export PATH="$AompSupp/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH" + export HIP_USE_PERL_SCRIPTS=1 + export USE_PERL_SCRIPTS=1 + export NUM_PROC="$Jobs" + export CXXFLAGS="-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1" + export LDFLAGS="-fPIC" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/rocSPARSE" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $BUILD_DIR/build/rocmlibs/rocSPARSE - rm -rf $BUILD_DIR/build/rocmlibs/rocSPARSE - mkdir -p $BUILD_DIR/build/rocmlibs/rocSPARSE -else - if [ ! -d $BUILD_DIR/build/rocmlibs/rocSPARSE ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/rocSPARSE does not exist" - echo " run $0 without install option. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi -if [ "$1" != "install" ] ; then - # Remember start directory to return on exit - _curdir=$PWD - echo - echo " -----Running cmake ---" - echo cd $AOMP_REPOS/build/rocmlibs/rocSPARSE - cd $AOMP_REPOS/build/rocmlibs/rocSPARSE - pwd - MYCMAKEOPTS=" - -DCMAKE_CXX_COMPILER=$CXX - -DCMAKE_C_COMPILER=$CC - -DROCM_DIR:PATH=$AOMP_INSTALL_DIR - -DCPACK_PACKAGING_INSTALL_PREFIX=$AOMP_INSTALL_DIR - -DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR - -DROCM_PATH=$AOMP_INSTALL_DIR - -DCMAKE_PREFIX_PATH:PATH=$AOMP_INSTALL_DIR - -DCPACK_SET_DESTDIR=OFF - -DCMAKE_BUILD_TYPE=Release - -DBUILD_WITH_ROCBLAS=ON - -DAMDGPU_TARGETS="""$ROCMLIBS_GFXLIST""" - " - echo $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - if [ $? != 0 ] ; then - echo "ERROR cmake failed." - echo " $MYCMAKEOPTS" - cd $_curdir + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + MYCMAKEOPTS=(-DCMAKE_CXX_COMPILER="$CXX" + -DCMAKE_C_COMPILER="$CC" + -DROCM_DIR:PATH="$AOMP_INSTALL_DIR" + -DCPACK_PACKAGING_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DCMAKE_PREFIX_PATH:PATH="$AOMP_INSTALL_DIR" + -DCPACK_SET_DESTDIR=OFF + -DCMAKE_BUILD_TYPE=Release + -DBUILD_WITH_ROCBLAS=ON + -DAMDGPU_TARGETS="$Gfxlist") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rocSPARSE $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + setup_env - make -j$AOMP_JOB_THREADS - if [ $? != 0 ] ; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocSPARSE $Cfg ---- " + if ! make -j"$Jobs"; then + echo "ERROR make -j $Jobs failed" exit 1 fi -fi - -if [ "$1" == "install" ] ; then - echo " -----Installing to $AOMP_INSTALL_DIR ---- " - cd $AOMP_REPOS/build/rocmlibs/rocSPARSE - make -j$AOMP_JOB_THREADS install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make -j"$Jobs" install; then + echo "ERROR install to $InstallDir failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From f648b16eb5814528ff325900674f7a0f045fe404 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 16 Jun 2026 10:56:04 -0500 Subject: [PATCH 42/71] Taskify build_rocSOLVER.sh --- bin/rocmlibs/build_rocSOLVER.sh | 293 ++++++++++++++++++++------------ 1 file changed, 184 insertions(+), 109 deletions(-) diff --git a/bin/rocmlibs/build_rocSOLVER.sh b/bin/rocmlibs/build_rocSOLVER.sh index 409a23ca3a..872dc9bf56 100755 --- a/bin/rocmlibs/build_rocSOLVER.sh +++ b/bin/rocmlibs/build_rocSOLVER.sh @@ -8,130 +8,205 @@ # build_rocSOLVER.sh: Script to build and install rocSOLVER library # # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -_repo_dir=$AOMP_REPOS/rocmlibs/rocSOLVER -patchrepo $_repo_dir - -export CC=$LLVM_INSTALL_LOC/bin/clang -export CXX=$LLVM_INSTALL_LOC/bin/clang++ -export ROCM_DIR=$AOMP_INSTALL_DIR -export ROCM_PATH=$AOMP_INSTALL_DIR -export PATH=$AOMP_SUPP/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH -export HIP_USE_PERL_SCRIPTS=1 -export USE_PERL_SCRIPTS=1 -# Reduce number of jobs because of large mem requirements for linking -_num_procs=$(( $AOMP_JOB_THREADS / 2 )) -export NUM_PROC=$_num_procs -export CXXFLAGS="-I$AOMP_INSTALL_DIR/include -D__HIP_PLATFORM_AMD__=1" -export LDFLAGS="-fPIC" -if [ "$AOMP_USE_CCACHE" != 0 ] ; then - _ccache_bin=`which ccache` - # export CMAKE_CXX_COMPILER_LAUNCHER=$_ccache_bin -fi - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -if [ "$1" == "nocmake" ] ; then - echo "ERROR: nocmake is not an option for $0" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocsolver "$1" +} + +cfgbool() { + get_config_var_bool rocsolver "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/rocSOLVER" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/rocSOLVER" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local AompSupp + local Jobs + AompSupp="$(cfgvar AOMP_SUPP)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + export CC=$LLVM_INSTALL_LOC/bin/clang + export CXX=$LLVM_INSTALL_LOC/bin/clang++ + export ROCM_DIR=$AOMP_INSTALL_DIR + export ROCM_PATH=$AOMP_INSTALL_DIR + export PATH="$AompSupp/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH" + export HIP_USE_PERL_SCRIPTS=1 + export USE_PERL_SCRIPTS=1 + # Reduce number of jobs because of large mem requirements for linking + export NUM_PROC=$(( Jobs / 2 )) + export CXXFLAGS="-I$AOMP_INSTALL_DIR/include -D__HIP_PLATFORM_AMD__=1" + export LDFLAGS="-fPIC" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/rocSOLVER" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $BUILD_DIR/build/rocmlibs/rocSOLVER - rm -rf $BUILD_DIR/build/rocmlibs/rocSOLVER - mkdir -p $BUILD_DIR/build/rocmlibs/rocSOLVER -else - if [ ! -d $BUILD_DIR/build/rocmlibs/rocSOLVER ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/rocSOLVER does not exist" - echo " run $0 without install option. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi - -if [ "$1" != "install" ] ; then - # Remember start directory to return on exit - _curdir=$PWD - echo " -----Running cmake ---" - echo cd $AOMP_REPOS/build/rocmlibs/rocSOLVER - cd $AOMP_REPOS/build/rocmlibs/rocSOLVER - pwd - MYCMAKEOPTS=" - -DCMAKE_CXX_COMPILER=$CXX - -DCMAKE_C_COMPILER=$CC - -DROCM_DIR:PATH=$AOMP_INSTALL_DIR - -DCPACK_PACKAGING_INSTALL_PREFIX=$AOMP_INSTALL_DIR - -DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR - -DROCM_PATH=$AOMP_INSTALL_DIR - -DCMAKE_PREFIX_PATH:PATH=$AOMP_INSTALL_DIR - -DCPACK_SET_DESTDIR=OFF - -DCMAKE_BUILD_TYPE=Release - -Drocblas_DIR=$AOMP_INSTALL_DIR/rocblas - -DAMDGPU_TARGETS="""$ROCMLIBS_GFXLIST""" - " - echo $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - if [ $? != 0 ] ; then - echo "ERROR cmake failed." - echo " $MYCMAKEOPTS" - cd $_curdir + + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + MYCMAKEOPTS=(-DCMAKE_CXX_COMPILER="$CXX" + -DCMAKE_C_COMPILER="$CC" + -DROCM_DIR:PATH="$AOMP_INSTALL_DIR" + -DCPACK_PACKAGING_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DCMAKE_PREFIX_PATH:PATH="$AOMP_INSTALL_DIR" + -DCPACK_SET_DESTDIR=OFF + -DCMAKE_BUILD_TYPE=Release + -Drocblas_DIR="$AOMP_INSTALL_DIR/rocblas" + -DAMDGPU_TARGETS="$Gfxlist") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rocSOLVER $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + setup_env - make -j$AOMP_JOB_THREADS - if [ $? != 0 ] ; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rocSOLVER $Cfg ---- " + if ! make -j"$Jobs"; then + echo "ERROR make -j $Jobs failed" exit 1 fi -fi - -if [ "$1" == "install" ] ; then - echo " -----Installing to $AOMP_INSTALL_DIR ---- " - cd $AOMP_REPOS/build/rocmlibs/rocSOLVER - make -j$AOMP_JOB_THREADS install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make -j"$Jobs" install; then + echo "ERROR install to $InstallDir failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 244427eafeac0373109a99874d3f1bd7deb66d85 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 03:09:27 -0500 Subject: [PATCH 43/71] Taskify build_hipBLAS-common.sh --- bin/rocmlibs/build_hipBLAS-common.sh | 291 +++++++++++++++++---------- 1 file changed, 184 insertions(+), 107 deletions(-) diff --git a/bin/rocmlibs/build_hipBLAS-common.sh b/bin/rocmlibs/build_hipBLAS-common.sh index 525ee5c03f..1b9bbd6b13 100755 --- a/bin/rocmlibs/build_hipBLAS-common.sh +++ b/bin/rocmlibs/build_hipBLAS-common.sh @@ -1,128 +1,205 @@ #!/bin/bash -# -# build_hipprim-common.sh: Script to build and install hipprim-common library +# +#Copyright © Advanced Micro Devices, Inc., or its affiliates. +# +#SPDX-License-Identifier: MIT +# +# build_hipBLAS-common.sh: Script to build and install hipBLAS-common library # This build is classic cmake, make, make install # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -# Patch rocr -_repo_dir=$AOMP_REPOS/rocmlibs/hipBLAS-common -patchrepo $_repo_dir - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN="" -else - AOMP_SET_NINJA_GEN="-G Ninja" -fi - -GFXSEMICOLONS=`echo $GFXLIST | tr ' ' ';' ` -GFXSEMICOLONS=""$GFXSEMICOLONS"" -#export CC=$AOMP/bin/clang -export CXX=$AOMP_INSTALL_DIR/bin/hipcc -export ROCM_DIR=$AOMP -export ROCM_PATH=$AOMP -export HIP_DIR=$AOMP -export PATH=$AOMP_SUPP/cmake/bin:$AOMP/bin:$PATH -export USE_PERL_SCRIPTS=1 -export NUM_PROC=$AOMP_JOB_THREADS -export CXXFLAGS="-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1" -export LDFLAGS="-fPIC" -export CMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC/lib/cmake" -MYCMAKEOPTS="-DCMAKE_BUILD_TYPE=$BUILD_TYPE \ --DCMAKE_CXX_COMPILER=$LLVM_INSTALL_LOC/bin/clang++ \ --DHIP_COMPILER=$LLVM_INSTALL_LOC/bin/clang \ --DHIP_CXX_COMPILER=$AOMP_INSTALL_DIR/bin/hipcc \ --DCMAKE_PREFIX_PATH=$LLVM_INSTALL_LOC/lib/cmake \ --DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR \ --DAMDGPU_TARGETS="""$ROCMLIBS_GFXLIST""" \ --DROCM_DIR=$ROCM_DIR \ --DROCM_PATH=$ROCM_PATH \ --DHIP_DIR=$HIP_DIR \ --DHIP_PLATFORM=amd \ -" - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string hipblas_common "$1" +} + +cfgbool() { + get_config_var_bool hipblas_common "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/hipBLAS-common" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/hipBLAS-common" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local AompSupp + local Jobs + AompSupp="$(cfgvar AOMP_SUPP)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + export CXX=$AOMP_INSTALL_DIR/bin/hipcc + export ROCM_DIR=$AOMP + export ROCM_PATH=$AOMP + export HIP_DIR=$AOMP + export PATH="$AompSupp/cmake/bin:$AOMP/bin:$PATH" + export USE_PERL_SCRIPTS=1 + export NUM_PROC="$Jobs" + export CXXFLAGS="-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1" + export LDFLAGS="-fPIC" + export CMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC/lib/cmake" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/hipBLAS-common" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - rm -rf $BUILD_DIR/build/rocmlibs/hipBLAS-common - mkdir -p $BUILD_DIR/build/rocmlibs/hipBLAS-common -else - if [ ! -d $BUILD_DIR/build/rocmlibs/hipBLAS-common ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/hipBLAS-common " - echo " run $0 without nocmake or install options. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi -cd $BUILD_DIR/build/rocmlibs/hipBLAS-common + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo " -----Running ${AOMP_CMAKE} ---- " - echo ${AOMP_CMAKE} $MYCMAKEOPTS $_repo_dir - ${AOMP_CMAKE} $MYCMAKEOPTS $_repo_dir 2>&1 - if [ $? != 0 ] ; then +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a AOMP_SET_NINJA_GEN + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + if "$(cfgbool AOMP_USE_NINJA)"; then + AOMP_SET_NINJA_GEN=(-G Ninja) + fi + + MYCMAKEOPTS=("${AOMP_SET_NINJA_GEN[@]}" + -DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DHIP_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DHIP_CXX_COMPILER="$AOMP_INSTALL_DIR/bin/hipcc" + -DCMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC/lib/cmake" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DAMDGPU_TARGETS="$Gfxlist" + -DROCM_DIR="$AOMP" + -DROCM_PATH="$AOMP" + -DHIP_DIR="$AOMP" + -DHIP_PLATFORM=amd) + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for hipBLAS-common $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then echo "ERROR cmake failed. Cmake flags" - echo " $MYCMAKEOPTS" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi - -# echo -# echo " -----Running ${AOMP_CMAKE} --build ---- " -# echo ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS -# ${AOMP_CMAKE} . -j $AOMP_JOB_THREADS -# if [ $? != 0 ] ; then -# echo "ERROR make -j $AOMP_JOB_THREADS failed" -# exit 1 -# fi - -if [ "$1" == "install" ] ; then - echo " -----Installing to $AOMP_INSTALL_DIR ---- " - $SUDO make package install - if [ $? != 0 ] ; then - echo "ERROR make install failed " + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + # hipBLAS-common is header-only; there is no separate build step. The + # package is generated and installed during the install task. + echo " -----No separate build step for hipBLAS-common $Cfg ---- " +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + setup_env + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! $SUDO make package install; then + echo "ERROR make package install failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 936324ef7ae4ca9d37a23c0c5bb081e1db822a69 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 03:12:22 -0500 Subject: [PATCH 44/71] Taskify build_hipBLAS.sh --- bin/rocmlibs/build_hipBLAS.sh | 304 +++++++++++++++++++++------------- 1 file changed, 190 insertions(+), 114 deletions(-) diff --git a/bin/rocmlibs/build_hipBLAS.sh b/bin/rocmlibs/build_hipBLAS.sh index a67ed333cc..7881857683 100755 --- a/bin/rocmlibs/build_hipBLAS.sh +++ b/bin/rocmlibs/build_hipBLAS.sh @@ -1,139 +1,215 @@ #!/bin/bash -# +# #Copyright © Advanced Micro Devices, Inc., or its affiliates. # #SPDX-License-Identifier: MIT # -# build_hipblas.sh: Script to build and install hipblas library +# build_hipBLAS.sh: Script to build and install hipBLAS library # # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -_repo_dir=$AOMP_REPOS/rocmlibs/hipBLAS -patchrepo $_repo_dir - -export CC=$LLVM_INSTALL_LOC/bin/clang -export CXX=$LLVM_INSTALL_LOC/bin/clang++ -export FC=$LLVM_INSTALL_LOC/bin/flang -export ROCM_DIR=$AOMP_INSTALL_DIR -export ROCM_PATH=$AOMP_INSTALL_DIR -export PATH=$AOMP_SUPP/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH -export HIP_USE_PERL_SCRIPTS=1 -export USE_PERL_SCRIPTS=1 -export NUM_PROC=$AOMP_JOB_THREADS -export CXXFLAGS="-I$AOMP_INSTALL_DIR/include -D__HIP_PLATFORM_AMD__=1" -export LDFLAGS="-fPIC" -if [ "$AOMP_USE_CCACHE" != 0 ] ; then - _ccache_bin=`which ccache` - # export CMAKE_CXX_COMPILER_LAUNCHER=$_ccache_bin -fi - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -if [ "$1" == "nocmake" ] ; then - echo "ERROR: nocmake is not an option for $0" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string hipblas "$1" +} + +cfgbool() { + get_config_var_bool hipblas "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/hipBLAS" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/hipBLAS" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local AompSupp + local Jobs + AompSupp="$(cfgvar AOMP_SUPP)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + export CC=$LLVM_INSTALL_LOC/bin/clang + export CXX=$LLVM_INSTALL_LOC/bin/clang++ + export FC=$LLVM_INSTALL_LOC/bin/flang + export ROCM_DIR=$AOMP_INSTALL_DIR + export ROCM_PATH=$AOMP_INSTALL_DIR + export PATH="$AompSupp/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH" + export HIP_USE_PERL_SCRIPTS=1 + export USE_PERL_SCRIPTS=1 + export NUM_PROC="$Jobs" + export CXXFLAGS="-I$AOMP_INSTALL_DIR/include -D__HIP_PLATFORM_AMD__=1" + export LDFLAGS="-fPIC" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/hipBLAS" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $BUILD_DIR/build/rocmlibs/hipBLAS - rm -rf $BUILD_DIR/build/rocmlibs/hipBLAS - mkdir -p $BUILD_DIR/build/rocmlibs/hipBLAS -else - if [ ! -d $BUILD_DIR/build/rocmlibs/hipBLAS ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/hipBLAS does not exist" - echo " run $0 without install option. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi - -if [ "$1" != "install" ] ; then - # Remember start directory to return on exit - _curdir=$PWD - echo " -----Running cmake ---" - echo cd $AOMP_REPOS/build/rocmlibs/hipBLAS - cd $AOMP_REPOS/build/rocmlibs/hipBLAS - pwd - MYCMAKEOPTS=" - -DCMAKE_CXX_COMPILER=$CXX - -DCMAKE_C_COMPILER=$CC - -DROCM_DIR:PATH=$AOMP_INSTALL_DIR - -DCPACK_PACKAGING_INSTALL_PREFIX=$AOMP_INSTALL_DIR - -DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR - -DROCM_PATH=$AOMP_INSTALL_DIR - -DCMAKE_PREFIX_PATH:PATH=$AOMP_INSTALL_DIR - -DCPACK_SET_DESTDIR=OFF - -DCMAKE_BUILD_TYPE=Release - -Drocblas_DIR=$AOMP_INSTALL_DIR/rocblas - -DAMDGPU_TARGETS="""$ROCMLIBS_GFXLIST""" - -DCUSTOM_TARGET=host - -DBUILD_WITH_SOLVER=ON - -DROCBLAS_PATH=$AOMP_INSTALL_DIR/rocblas - -DROCSOLVER_PATH=$AOMP_INSTALL_DIR/rocsolver - " - echo $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - if [ $? != 0 ] ; then - echo "ERROR cmake failed." - echo " $MYCMAKEOPTS" - cd $_curdir + + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + MYCMAKEOPTS=(-DCMAKE_CXX_COMPILER="$CXX" + -DCMAKE_C_COMPILER="$CC" + -DROCM_DIR:PATH="$AOMP_INSTALL_DIR" + -DCPACK_PACKAGING_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DCMAKE_PREFIX_PATH:PATH="$AOMP_INSTALL_DIR" + -DCPACK_SET_DESTDIR=OFF + -DCMAKE_BUILD_TYPE=Release + -Drocblas_DIR="$AOMP_INSTALL_DIR/rocblas" + -DAMDGPU_TARGETS="$Gfxlist" + -DCUSTOM_TARGET=host + -DBUILD_WITH_SOLVER=ON + -DROCBLAS_PATH="$AOMP_INSTALL_DIR/rocblas" + -DROCSOLVER_PATH="$AOMP_INSTALL_DIR/rocsolver") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for hipBLAS $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi - make -j$AOMP_JOB_THREADS + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + setup_env - if [ $? != 0 ] ; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for hipBLAS $Cfg ---- " + if ! make -j"$Jobs"; then + echo "ERROR make -j $Jobs failed" exit 1 fi -fi - -if [ "$1" == "install" ] ; then - echo " -----Installing to $AOMP_INSTALL_DIR ---- " - cd $BUILD_DIR/build/rocmlibs/hipBLAS - make -j$AOMP_JOB_THREADS install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make -j"$Jobs" install; then + echo "ERROR install to $InstallDir failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 4c0d289ac7f3303f3bbbed224392509e3912b97f Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 03:16:32 -0500 Subject: [PATCH 45/71] Taskify build_rocRAND.sh --- bin/rocmlibs/build_rocRAND.sh | 293 +++++++++++++++++++++------------- 1 file changed, 185 insertions(+), 108 deletions(-) diff --git a/bin/rocmlibs/build_rocRAND.sh b/bin/rocmlibs/build_rocRAND.sh index f74ac7469d..6f9fd1e93d 100755 --- a/bin/rocmlibs/build_rocRAND.sh +++ b/bin/rocmlibs/build_rocRAND.sh @@ -1,129 +1,206 @@ #!/bin/bash -# -# build_rocRAND.sh: script to build rocRAND # -BUILD_TYPE=${BUILD_TYPE:-Release} +#Copyright © Advanced Micro Devices, Inc., or its affiliates. +# +#SPDX-License-Identifier: MIT +# +# build_rocRAND.sh: script to build and install rocRAND library +# + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -_howcalled=${0##*/} -_shname=${_howcalled#build_*} # strip off build_ -_libname=${_shname%*.sh} # strip off .sh to get component libname -_repo_dir=$AOMP_REPOS/rocmlibs/$_libname - -patchrepo $_repo_dir - -export CXX=$AOMP_INSTALL_DIR/bin/hipcc -export ROCM_DIR=$AOMP_INSTALL_DIR -export ROCM_PATH=$AOMP_INSTALL_DIR -export PATH=$AOMP_SUPP/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH -#export HIP_USE_PERL_SCRIPTS=1 -#export USE_PERL_SCRIPTS=1 -export LDFLAGS="-fPIC" - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -if [ "$1" == "nocmake" ] ; then - echo "ERROR: nocmake is not an option for $0" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rocrand "$1" +} + +cfgbool() { + get_config_var_bool rocrand "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/rocRAND" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/rocRAND" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local AompSupp + AompSupp="$(cfgvar AOMP_SUPP)" + export CXX=$AOMP_INSTALL_DIR/bin/hipcc + export ROCM_DIR=$AOMP_INSTALL_DIR + export ROCM_PATH=$AOMP_INSTALL_DIR + export PATH="$AompSupp/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH" + export LDFLAGS="-fPIC" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/$_libname" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $BUILD_DIR/build/rocmlibs/$_libname - rm -rf $BUILD_DIR/build/rocmlibs/$_libname - mkdir -p $BUILD_DIR/build/rocmlibs/$_libname -else - if [ ! -d $BUILD_DIR/build/rocmlibs/$_libname ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/$_libname does not exist" - echo " run $0 without install option. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi -if [ "$1" != "install" ] ; then - # Remember start directory to return on exit - _curdir=$PWD - echo - echo " -----Running cmake ---" - echo cd $AOMP_REPOS/build/rocmlibs/$_libname - cd $AOMP_REPOS/build/rocmlibs/$_libname - pwd - MYCMAKEOPTS="\ --DCMAKE_CXX_COMPILER=$CXX \ --DCMAKE_CXX_FLAGS=""-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1"" \ --DROCM_DIR=$AOMP_INSTALL_DIR \ --DBUILD_FORTRAN_WRAPPER=ON \ --DROCM_PATH=$AOMP_INSTALL_DIR \ --DHIP_ROOT_DIR=$AOMP_INSTALL_DIR \ --DCPACK_PACKAGING_INSTALL_PREFIX=$AOMP_INSTALL_DIR \ --DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR \ --DCMAKE_PREFIX_PATH=$AOMP_INSTALL_DIR \ --DCPACK_SET_DESTDIR=OFF \ --DCMAKE_BUILD_TYPE=Release \ --DBUILD_BENCHMARK=ON \ --DAMDGPU_TARGETS="""$ROCMLIBS_GFXLIST""" " - echo " ----- Running $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir -----" - $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - if [ $? != 0 ] ; then - echo "ERROR cmake failed." - echo " $MYCMAKEOPTS" - cd $_curdir + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + MYCMAKEOPTS=(-DCMAKE_CXX_COMPILER="$CXX" + -DCMAKE_CXX_FLAGS="-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1" + -DROCM_DIR="$AOMP_INSTALL_DIR" + -DBUILD_FORTRAN_WRAPPER=ON + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DHIP_ROOT_DIR="$AOMP_INSTALL_DIR" + -DCPACK_PACKAGING_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR" + -DCPACK_SET_DESTDIR=OFF + -DCMAKE_BUILD_TYPE=Release + -DBUILD_BENCHMARK=ON + -DAMDGPU_TARGETS="$Gfxlist") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rocRAND $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local AompCmake + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + setup_env - echo " ----- Running ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS -----" - ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS - if [ $? != 0 ] ; then - echo "ERROR: ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS FAILED" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $AompCmake --build for rocRAND $Cfg ---- " + if ! "$AompCmake" --build . -j "$Jobs"; then + echo "ERROR $AompCmake --build . -j $Jobs failed" exit 1 fi -fi - -if [ "$1" == "install" ] ; then - echo " ----- Installing to $AOMP_INSTALL_DIR ----- " - cd $AOMP_REPOS/build/rocmlibs/$_libname - make -j$AOMP_JOB_THREADS install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make -j"$Jobs" install; then + echo "ERROR install to $InstallDir failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From f6dee8e5536cf401263c740fd154cbdaf6757606 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 03:16:32 -0500 Subject: [PATCH 46/71] Taskify build_hipRAND.sh --- bin/rocmlibs/build_hipRAND.sh | 291 +++++++++++++++++++++------------- 1 file changed, 184 insertions(+), 107 deletions(-) diff --git a/bin/rocmlibs/build_hipRAND.sh b/bin/rocmlibs/build_hipRAND.sh index 090967c1b5..9a09caeac4 100755 --- a/bin/rocmlibs/build_hipRAND.sh +++ b/bin/rocmlibs/build_hipRAND.sh @@ -1,128 +1,205 @@ #!/bin/bash -# -# build_hipRAND.sh.sh: script to build rocRAND # -BUILD_TYPE=${BUILD_TYPE:-Release} +#Copyright © Advanced Micro Devices, Inc., or its affiliates. +# +#SPDX-License-Identifier: MIT +# +# build_hipRAND.sh: script to build and install hipRAND library +# + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -_howcalled=${0##*/} -_shname=${_howcalled#build_*} # strip off build_ -_libname=${_shname%*.sh} # strip off .sh to get component libname -_repo_dir=$AOMP_REPOS/rocmlibs/$_libname - -patchrepo $_repo_dir - -export CXX=$AOMP_INSTALL_DIR/bin/hipcc -export ROCM_DIR=$AOMP_INSTALL_DIR -export ROCM_PATH=$AOMP_INSTALL_DIR -export PATH=$AOMP_SUPP/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH -#export HIP_USE_PERL_SCRIPTS=1 -#export USE_PERL_SCRIPTS=1 -export LDFLAGS="-fPIC" - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -if [ "$1" == "nocmake" ] ; then - echo "ERROR: nocmake is not an option for $0" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string hiprand "$1" +} + +cfgbool() { + get_config_var_bool hiprand "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/hipRAND" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/hipRAND" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local AompSupp + AompSupp="$(cfgvar AOMP_SUPP)" + export CXX=$AOMP_INSTALL_DIR/bin/hipcc + export ROCM_DIR=$AOMP_INSTALL_DIR + export ROCM_PATH=$AOMP_INSTALL_DIR + export PATH="$AompSupp/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH" + export LDFLAGS="-fPIC" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/$_libname" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $BUILD_DIR/build/rocmlibs/$_libname - rm -rf $BUILD_DIR/build/rocmlibs/$_libname - mkdir -p $BUILD_DIR/build/rocmlibs/$_libname -else - if [ ! -d $BUILD_DIR/build/rocmlibs/$_libname ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/$_libname does not exist" - echo " run $0 without install option. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi -if [ "$1" != "install" ] ; then - # Remember start directory to return on exit - _curdir=$PWD - echo - echo " -----Running cmake ---" - echo cd $AOMP_REPOS/build/rocmlibs/$_libname - cd $AOMP_REPOS/build/rocmlibs/$_libname - pwd - MYCMAKEOPTS="\ --DCMAKE_CXX_COMPILER=$CXX \ --DCMAKE_CXX_FLAGS=""-I$LLVM_INSTALL_LOC/include\;-D__HIP_PLATFORM_AMD__=1"" \ --DROCM_DIR=$AOMP_INSTALL_DIR \ --DBUILD_FORTRAN_WRAPPER=ON \ --DROCM_PATH=$AOMP_INSTALL_DIR \ --DHIP_ROOT_DIR=$AOMP_INSTALL_DIR \ --DCPACK_PACKAGING_INSTALL_PREFIX=$AOMP_INSTALL_DIR \ --DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR \ --DCMAKE_PREFIX_PATH=$AOMP_INSTALL_DIR \ --DCPACK_SET_DESTDIR=OFF \ --DCMAKE_BUILD_TYPE=Release \ --DAMDGPU_TARGETS="""$ROCMLIBS_GFXLIST""" " - echo " ----- Running $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir -----" - $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - if [ $? != 0 ] ; then - echo "ERROR cmake failed." - echo " $MYCMAKEOPTS" - cd $_curdir + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + MYCMAKEOPTS=(-DCMAKE_CXX_COMPILER="$CXX" + -DCMAKE_CXX_FLAGS="-I$LLVM_INSTALL_LOC/include;-D__HIP_PLATFORM_AMD__=1" + -DROCM_DIR="$AOMP_INSTALL_DIR" + -DBUILD_FORTRAN_WRAPPER=ON + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DHIP_ROOT_DIR="$AOMP_INSTALL_DIR" + -DCPACK_PACKAGING_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR" + -DCPACK_SET_DESTDIR=OFF + -DCMAKE_BUILD_TYPE=Release + -DAMDGPU_TARGETS="$Gfxlist") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for hipRAND $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local AompCmake + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + setup_env - echo " ----- Running ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS -----" - ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS - if [ $? != 0 ] ; then - echo "ERROR: ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS FAILED" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $AompCmake --build for hipRAND $Cfg ---- " + if ! "$AompCmake" --build . -j "$Jobs"; then + echo "ERROR $AompCmake --build . -j $Jobs failed" exit 1 fi -fi - -if [ "$1" == "install" ] ; then - echo " ----- Installing to $AOMP_INSTALL_DIR ----- " - cd $AOMP_REPOS/build/rocmlibs/$_libname - make -j$AOMP_JOB_THREADS install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make -j"$Jobs" install; then + echo "ERROR install to $InstallDir failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From ed67f38937945a6dce0e9af29e3e1edfab1f9561 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 03:23:51 -0500 Subject: [PATCH 47/71] Taskify build_rccl.sh --- bin/aomp_utils | 2 +- bin/rocmlibs/build_rccl.sh | 332 +++++++++++++++++++++++-------------- 2 files changed, 204 insertions(+), 130 deletions(-) diff --git a/bin/aomp_utils b/bin/aomp_utils index 2c0bc88e5b..ee5b38ebc3 100644 --- a/bin/aomp_utils +++ b/bin/aomp_utils @@ -325,7 +325,7 @@ get_config_var_bool() { AOMP_BUILD_CUDA|AOMP_APPLY_ATD_AMD_STAGING_PATCH|AOMP_USE_NINJA|\ AOMP_STANDALONE_BUILD|SANITIZER|AOMP_LEGACY_OPENMP|AOMP_BUILD_SANITIZER|\ AOMP_BUILD_PERF|AOMP_BUILD_DEBUG|AOMP_BUILD_TENSILE|ROCBLAS_USE_HIPBLASLT|\ - AOMP_SKIP_AMD_FLANGRT|AOMP_LIMIT_FLANG) + AOMP_SKIP_AMD_FLANGRT|AOMP_LIMIT_FLANG|AOMP_USE_CCACHE) ;; *) >&2 echo "Unknown bool configuration variable '$2'" diff --git a/bin/rocmlibs/build_rccl.sh b/bin/rocmlibs/build_rccl.sh index 5e1125ca2a..3c358098e2 100755 --- a/bin/rocmlibs/build_rccl.sh +++ b/bin/rocmlibs/build_rccl.sh @@ -1,150 +1,224 @@ #!/bin/bash -# +# +#Copyright © Advanced Micro Devices, Inc., or its affiliates. +# +#SPDX-License-Identifier: MIT +# # build_rccl.sh: Script to build and install rccl. -# This uses a slightly modified install.sh from rccl. # It has a dependency on rocm-core. # -BUILD_TYPE=${BUILD_TYPE:-Release} +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -_howcalled=${0##*/} -_shname=${_howcalled#build_*} # strip off build_ -_libname=${_shname%*.sh} # strip off .sh to get component libname = rccl -_source_dir=$AOMP_REPOS/rocmlibs/$_libname - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - _set_ninja_gen="" -else - _set_ninja_gen="--time-trace" -fi - -if [ -d "$HOME/local/rocm-core/.info" ]; then - echo Copying rocm-core .info from $HOME/local/rocm-core/.info to $AOMP_INSTALL_DIR - cp -r $HOME/local/rocm-core/.info $AOMP_INSTALL_DIR -else - echo "Error: rccl needs $AOMP_INSTALL_DIR/.info to exist. Please run ./build_prereq.sh first." - exit 1 -fi - -patchrepo $_source_dir - -export CC=$LLVM_INSTALL_LOC/bin/clang -export CXX=$LLVM_INSTALL_LOC/bin/clang++ -export FC=$LLVM_INSTALL_LOC/bin/flang -export ROCM_DIR=$AOMP_INSTALL_DIR -export ROCM_PATH=$AOMP_INSTALL_DIR -# rccl needs cmake 3.25, so put prereq cmake first in path -export PATH=$AOMP_SUPP/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH -export NUM_PROC=$AOMP_JOB_THREADS -export CXXFLAGS="-I$HOME/local/rocm-core/include" -export LDFLAGS="-fPIC" -export EXPLICIT_ROCM_VERSION=$(grep -E "[0-9]+\.[0-9]+\.[0-9]+" < $HOME/local/rocm-core/.info/version) - -if [ "$AOMP_USE_CCACHE" != 0 ] ; then - _ccache_bin=`which ccache` - export CMAKE_CXX_COMPILER_LAUNCHER=$_ccache_bin -fi - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string rccl "$1" +} + +cfgbool() { + get_config_var_bool rccl "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/rccl" +_rocm_core_info="$HOME/local/rocm-core/.info" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/rccl" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local AompSupp + local Jobs + local CcacheBin + AompSupp="$(cfgvar AOMP_SUPP)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + export CC=$LLVM_INSTALL_LOC/bin/clang + export CXX=$LLVM_INSTALL_LOC/bin/clang++ + export FC=$LLVM_INSTALL_LOC/bin/flang + export ROCM_DIR=$AOMP_INSTALL_DIR + export ROCM_PATH=$AOMP_INSTALL_DIR + # rccl needs cmake 3.25, so put prereq cmake first in path + export PATH="$AompSupp/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH" + export NUM_PROC="$Jobs" + export CXXFLAGS="-I$HOME/local/rocm-core/include" + export LDFLAGS="-fPIC" + EXPLICIT_ROCM_VERSION=$(grep -E "[0-9]+\.[0-9]+\.[0-9]+" < "$_rocm_core_info/version") + export EXPLICIT_ROCM_VERSION + if "$(cfgbool AOMP_USE_CCACHE)"; then + CcacheBin=$(which ccache) + export CMAKE_CXX_COMPILER_LAUNCHER=$CcacheBin fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -if [ "$1" == "nocmake" ] ; then - _nocmake_option="--nocmake" -else - _nocmake_option="" -fi - -if [ "$BUILD_TYPE" == "Release" ] ; then - _buildtype_option="" - _build_dir_option="release" -else - _buildtype_option="--debug" - _build_dir_option="debug" -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/$_libname" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $BUILD_DIR/build/rocmlibs/$_libname - rm -rf $BUILD_DIR/build/rocmlibs/$_libname - mkdir -p $BUILD_DIR/build/rocmlibs/$_libname -else - if [ ! -d $BUILD_DIR/build/rocmlibs/$_libname ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/$_libname does not exist" - echo " run $0 without install and without nocmake option" + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi - -# Remember start directory to return on exit -_curdir=$PWD -if [ "$1" != "install" ] ; then - echo - echo " -----Running cmake in install.sh ---" - echo cd $AOMP_REPOS/build/rocmlibs/$_libname - cd $AOMP_REPOS/build/rocmlibs/$_libname - echo ${AOMP_CMAKE} --toolchain=toolchain-linux.cmake -DCMAKE_BUILD_TYPE=Release -DGPU_TARGETS="$ROCMLIBS_GFXLIST" -DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR -DROCM_PATH=$AOMP_INSTALL_DIR -DCOLLTRACE=OFF -DNPKIT_FLAGS="" -DONLY_FUNCS="" -DEXPLICIT_ROCM_VERSION=$EXPLICIT_ROCM_VERSION $_source_dir - ${AOMP_CMAKE} --toolchain=toolchain-linux.cmake -DCMAKE_BUILD_TYPE=Release -DGPU_TARGETS="$ROCMLIBS_GFXLIST" -DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR -DROCM_PATH=$AOMP_INSTALL_DIR -DCOLLTRACE=OFF -DNPKIT_FLAGS="" -DONLY_FUNCS="" -DEXPLICIT_ROCM_VERSION=$EXPLICIT_ROCM_VERSION $_source_dir - if [ $? != 0 ] ; then - echo "ERROR cmake failed." - echo " $MYCMAKEOPTS" - cd $_curdir - exit 1 - fi - make -j$AOMP_JOB_THREADS + if [ -d "$_rocm_core_info" ]; then + echo "Copying rocm-core .info from $_rocm_core_info to $AOMP_INSTALL_DIR" + cp -r "$_rocm_core_info" "$AOMP_INSTALL_DIR" + else + echo "Error: rccl needs $AOMP_INSTALL_DIR/.info to exist. Please run ./build_prereq.sh first." + exit 1 + fi - if [ $? != 0 ] ; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" - exit 1 - fi -fi - -if [ "$1" == "install" ] ; then - echo " ----- Installing to $AOMP_INSTALL_DIR ----- " - echo cd $AOMP_REPOS/build/rocmlibs/$_libname - cd $AOMP_REPOS/build/rocmlibs/$_libname - make -j$AOMP_JOB_THREADS install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + MYCMAKEOPTS=(--toolchain=toolchain-linux.cmake + -DCMAKE_BUILD_TYPE=Release + -DGPU_TARGETS="$Gfxlist" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR" + -DROCM_PATH="$AOMP_INSTALL_DIR" + -DCOLLTRACE=OFF + -DNPKIT_FLAGS="" + -DONLY_FUNCS="" + -DEXPLICIT_ROCM_VERSION="$EXPLICIT_ROCM_VERSION") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for rccl $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + setup_env + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for rccl $Cfg ---- " + if ! make -j"$Jobs"; then + echo "ERROR make -j $Jobs failed" + exit 1 + fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make -j"$Jobs" install; then + echo "ERROR install to $InstallDir failed " + exit 1 + fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" - echo - removepatch $_source_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From c6ed556f91a7da904ba3b25b9273364e9474db60 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 03:23:51 -0500 Subject: [PATCH 48/71] Taskify build_half.sh --- bin/rocmlibs/build_half.sh | 240 ++++++++++++++++++++++++------------- 1 file changed, 158 insertions(+), 82 deletions(-) diff --git a/bin/rocmlibs/build_half.sh b/bin/rocmlibs/build_half.sh index 5349d93f7e..bd30c04414 100755 --- a/bin/rocmlibs/build_half.sh +++ b/bin/rocmlibs/build_half.sh @@ -1,103 +1,179 @@ #!/bin/bash -# +# +#Copyright © Advanced Micro Devices, Inc., or its affiliates. +# +#SPDX-License-Identifier: MIT +# # build_half.sh: script to build and install half # + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit + # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -_libname=half -_repo_dir=$AOMP_REPOS/rocmlibs/$_libname -patchrepo $_repo_dir - -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -if [ "$1" == "nocmake" ] ; then - echo "ERROR: nocmake is not an option for $0" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string half "$1" +} + +cfgbool() { + get_config_var_bool half "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/half" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/half" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/$_libname" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $BUILD_DIR/build/rocmlibs/$_libname - rm -rf $BUILD_DIR/build/rocmlibs/$_libname - mkdir -p $BUILD_DIR/build/rocmlibs/$_libname -else - if [ ! -d $BUILD_DIR/build/rocmlibs/$_libname ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/$_libname does not exist" - echo " run $0 without install option. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi -if [ "$1" != "install" ] ; then - # Remember start directory to return on exit - _curdir=$PWD - echo - echo " -----Running cmake ---" - echo cd $AOMP_REPOS/build/rocmlibs/$_libname - cd $AOMP_REPOS/build/rocmlibs/$_libname - pwd - MYCMAKEOPTS="-DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR" - echo " ----- Running $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir -----" - $AOMP_CMAKE $MYCMAKEOPTS $_repo_dir - if [ $? != 0 ] ; then - echo "ERROR cmake failed." - echo " $MYCMAKEOPTS" - cd $_curdir + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + + MYCMAKEOPTS=(-DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for half $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then + echo "ERROR cmake failed. Cmake flags" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local AompCmake + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + AompCmake="$(cfgvar AOMP_CMAKE)" + Jobs="$(cfgvar AOMP_JOB_THREADS)" - echo " ----- Running ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS -----" - ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS - if [ $? != 0 ] ; then - echo "ERROR: ${AOMP_CMAKE} --build . -j $AOMP_JOB_THREADS FAILED" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running $AompCmake --build for half $Cfg ---- " + if ! "$AompCmake" --build . -j "$Jobs"; then + echo "ERROR $AompCmake --build . -j $Jobs failed" exit 1 fi -fi - -if [ "$1" == "install" ] ; then - echo " ----- Installing to $AOMP_INSTALL_DIR ----- " - cd $AOMP_REPOS/build/rocmlibs/$_libname - make -j$AOMP_JOB_THREADS install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make -j"$Jobs" install; then + echo "ERROR install to $InstallDir failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From b92118b382f66f7a104cf5559503dc8be4ab324d Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 03:26:29 -0500 Subject: [PATCH 49/71] Taskify build_hipSOLVER.sh --- bin/rocmlibs/build_hipSOLVER.sh | 230 +++++++++++++++++++++----------- 1 file changed, 151 insertions(+), 79 deletions(-) diff --git a/bin/rocmlibs/build_hipSOLVER.sh b/bin/rocmlibs/build_hipSOLVER.sh index 99c29fc3e3..2bf02091f3 100755 --- a/bin/rocmlibs/build_hipSOLVER.sh +++ b/bin/rocmlibs/build_hipSOLVER.sh @@ -1,101 +1,173 @@ #!/bin/bash -# -# build_rocsolver.sh: Script to build and install rocsolver library # +#Copyright © Advanced Micro Devices, Inc., or its affiliates. # -BUILD_TYPE=${BUILD_TYPE:-Release} +#SPDX-License-Identifier: MIT +# +# build_hipSOLVER.sh: Script to build and install hipSOLVER library +# + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -_source_dir=$AOMP_REPOS/rocmlibs/hipSOLVER -_curdir=$PWD -cd $_source_dir +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string hipsolver "$1" +} -patchrepo $_source_dir +cfgbool() { + get_config_var_bool hipsolver "$1" +} -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -if [ "$1" == "nocmake" ] ; then - echo "ERROR: nocmake is not an option for $0" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/hipSOLVER" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +# +# hipSOLVER does not follow the AOMP build directory convention because its +# install.sh assumes the build directory is a subdirectory of the source +# directory. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$_repo_dir/build" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -# This does not follow AOMP build directories convention because install.sh -# assumes build directory is a subdirectory of source_directory. -# Changes to install.sh to fix this would be difficult. -_build_dir=$_source_dir/build -if [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $_build_dir" - echo "Use ""$0 install"" to avoid FRESH START." - echo rm -rf $_build_dir - rm -rf $_build_dir - mkdir -p $_build_dir -else - if [ ! -d $_build_dir ] ; then - echo "ERROR: The build directory $_build_dir does not exist" - echo " run $0 without install option. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi -cd $_source_dir -if [ "$1" != "install" ] ; then - # Remember start directory to return on exit - _curdir=$PWD - echo " ----- Running hipSOLVER install.sh -----" + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} + +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local SrcDir + local -a INSTALL_OPTS + + SrcDir="$(get_src_dir)" export ROCM_PATH=$AOMP_INSTALL_DIR - _cmd="./install.sh --compiler $AOMP_INSTALL_DIR/lib/llvm/bin/clang++ --rocblas-path $AOMP_INSTALL_DIR --hipblas-path $AOMP_INSTALL_DIR --rocsolver-path $AOMP_INSTALL_DIR --cmakepp $AOMP_INSTALL_DIR --no-sparse --no-hip-clang --relocatable --cmake-arg -DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR" - $_cmd - if [ $? != 0 ] ; then - echo "ERROR $_cmd failed." - cd $_curdir + + # hipSOLVER's install.sh both configures and builds the library. + INSTALL_OPTS=(--compiler "$AOMP_INSTALL_DIR/lib/llvm/bin/clang++" + --rocblas-path "$AOMP_INSTALL_DIR" + --hipblas-path "$AOMP_INSTALL_DIR" + --rocsolver-path "$AOMP_INSTALL_DIR" + --cmakepp "$AOMP_INSTALL_DIR" + --no-sparse + --no-hip-clang + --relocatable + --cmake-arg -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR") + + pushd "$SrcDir" >& /dev/null || exit + echo " ----- Running hipSOLVER install.sh for $Cfg -----" + echo "./install.sh $(shquot "${INSTALL_OPTS[@]}")" + if ! ./install.sh "${INSTALL_OPTS[@]}"; then + echo "ERROR ./install.sh failed." exit 1 fi -fi - -if [ "$1" == "install" ] ; then - echo " -----Installing to $AOMP_INSTALL_DIR ---- " - cd $_build_dir/release - make install - if [ $? != 0 ] ; then - echo "ERROR install to $AOMP_INSTALL_DIR failed " + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + # hipSOLVER's install.sh (run in the cmake task) both configures and builds + # the library, so there is no separate build step. + echo " -----No separate build step for hipSOLVER $Cfg ---- " +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir/release" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! make install; then + echo "ERROR install to $InstallDir failed " exit 1 fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - removepatch $_source_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR" - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 92e3a45cbe374b0cd9d4299438ffeb350af5c172 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 03:26:29 -0500 Subject: [PATCH 50/71] Taskify build_powerinfer.sh --- bin/rocmlibs/build_powerinfer.sh | 317 ++++++++++++++++++++----------- 1 file changed, 204 insertions(+), 113 deletions(-) diff --git a/bin/rocmlibs/build_powerinfer.sh b/bin/rocmlibs/build_powerinfer.sh index 604e1b55d0..b66634fe7b 100755 --- a/bin/rocmlibs/build_powerinfer.sh +++ b/bin/rocmlibs/build_powerinfer.sh @@ -1,147 +1,238 @@ #!/bin/bash -# +# #Copyright © Advanced Micro Devices, Inc., or its affiliates. # #SPDX-License-Identifier: MIT -# +# # build_powerinfer.sh: Script to build and install powerinfer library # This build is classic cmake, make, make install # -BUILD_TYPE=${BUILD_TYPE:-Release} + +# Without these options, we can lose error status from command subtitutions, +# etc. +set -e +shopt -s inherit_errexit # --- Start standard header to set AOMP environment variables ---- -realpath=`realpath $0` -thisdir=`dirname $realpath` +realpath=$(realpath -- "$0") +thisdir=$(dirname "$realpath") . "$thisdir/../aomp_utils" -. $thisdir/../aomp_common_vars +. "$thisdir/../aomp_common_vars" # --- end standard header ---- -# Patch rocr -_repo_dir=$AOMP_REPOS/rocmlibs/PowerInfer -patchrepo $_repo_dir - -if [ "$AOMP_USE_NINJA" == 0 ] ; then - AOMP_SET_NINJA_GEN="" -else - AOMP_SET_NINJA_GEN="-G Ninja" -fi - -GFXSEMICOLONS=`echo $GFXLIST | tr ' ' ';' ` -GFXSEMICOLONS=""$GFXSEMICOLONS"" -export CC=$AOMP/bin/clang -export CXX=$AOMP/bin/clang++ -#export ROCM_DIR=$AOMP -#export PATH=$AOMP_SUPP/cmake/bin:$AOMP/bin:$PATH -#export PATH=$AOMP/bin:$PATH -export USE_PERL_SCRIPTS=1 -export NUM_PROC=$AOMP_JOB_THREADS -export CXXFLAGS="-I$AOMP_INSTALL_DIR/include -D__HIP_PLATFORM_AMD__=1" -#export LDFLAGS="-fPIC" - -MYCMAKEOPTS="-DCMAKE_BUILD_TYPE=$BUILD_TYPE \ --DLLAMA_HIPBLAS=ON \ --DCMAKE_PREFIX_PATH=$LLVM_INSTALL_LOC/lib/cmake \ --DCMAKE_INSTALL_PREFIX=$AOMP_INSTALL_DIR/PowerInfer \ --DCMAKE_C_COMPILER=$LLVM_INSTALL_LOC/bin/clang \ --DCMAKE_CXX_COMPILER=$LLVM_INSTALL_LOC/bin/clang++ \ --DHIP_PLATFORM=amd \ --DAMDGPU_TARGETS="""$ROCMLIBS_GFXLIST""" -" -# $AOMP_ORIGIN_RPATH \ -if [ $AOMP_STANDALONE_BUILD == 1 ] ; then - if [ ! -L $AOMP ] ; then - if [ -d $AOMP ] ; then - echo "ERROR: Directory $AOMP is a physical directory." - echo " It must be a symbolic link or not exist" - exit 1 - fi - fi -else - echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" - exit 1 -fi - -# Make sure we can update the install directory -if [ "$1" == "install" ] ; then - $SUDO mkdir -p $AOMP_INSTALL_DIR - $SUDO touch $AOMP_INSTALL_DIR/testfile - if [ $? != 0 ] ; then - echo "ERROR: No update access to $AOMP_INSTALL_DIR" +# All user-controllable (environment) values are read through these wrappers so +# that they can later be driven by an orchestration layer. +cfgvar() { + get_config_var_string powerinfer "$1" +} + +cfgbool() { + get_config_var_bool powerinfer "$1" +} + +_repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/PowerInfer" + +get_src_dir() { + echo "$_repo_dir" +} + +# Print the build dir for a given config, passed as $1. +get_build_dir() { + local Cfg=$1 + case "$Cfg" in + "default") + echo -n "$(cfgvar BUILD_DIR)/rocmlibs/PowerInfer" + ;; + *) + >&2 echo "Unknown config '$Cfg'" + exit 1 + ;; + esac +} + +# Print the install dir for a given config, passed as $1. +get_install_dir() { + echo "$AOMP_INSTALL_DIR/PowerInfer" +} + +# Set the environment shared by the cmake and build steps. +setup_env() { + local Jobs + Jobs="$(cfgvar AOMP_JOB_THREADS)" + export CC=$AOMP/bin/clang + export CXX=$AOMP/bin/clang++ + export USE_PERL_SCRIPTS=1 + export NUM_PROC="$Jobs" + export CXXFLAGS="-I$AOMP_INSTALL_DIR/include -D__HIP_PLATFORM_AMD__=1" +} + +task_precheck() { + if ! "$(cfgbool AOMP_STANDALONE_BUILD)"; then + echo "ERROR: $0 only valid for AOMP_STANDALONE_BUILD=1" exit 1 fi - $SUDO rm $AOMP_INSTALL_DIR/testfile -fi - -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo "This is a FRESH START. ERASING any previous builds in $BUILD_DIR/build/rocmlibs/PowerInfer" - echo "Use ""$0 nocmake"" or ""$0 install"" to avoid FRESH START." - rm -rf $BUILD_DIR/build/rocmlibs/PowerInfer - mkdir -p $BUILD_DIR/build/rocmlibs/PowerInfer -else - if [ ! -d $BUILD_DIR/build/rocmlibs/PowerInfer ] ; then - echo "ERROR: The build directory $BUILD_DIR/build/rocmlibs/PowerInfer " - echo " run $0 without nocmake or install options. " + if [ ! -L "$AOMP" ] && [ -d "$AOMP" ] ; then + echo "ERROR: Directory $AOMP is a physical directory." + echo " It must be a symbolic link or not exist" exit 1 fi -fi -cd $BUILD_DIR/build/rocmlibs/PowerInfer + check_writable_installdir "$1" "$AOMP_INSTALL_DIR" +} -if [ "$1" != "nocmake" ] && [ "$1" != "install" ] ; then - echo - echo " -----Running cmake ---- " - echo cmake $MYCMAKEOPTS $_repo_dir - env CXX=$AOMP/bin/hipcc cmake $MYCMAKEOPTS $_repo_dir 2>&1 - if [ $? != 0 ] ; then +task_patch() { + patchrepo "$_repo_dir" +} + +task_unpatch() { + removepatch "$_repo_dir" +} + +task_clean() { + local Cfg=$1 + local BuildDir + BuildDir=$(get_build_dir "$Cfg") + echo "rm -rf $(shquot "$BuildDir")" + rm -rf "$BuildDir" + mkdir -p "$BuildDir" +} + +task_cmake() { + local Cfg=$1 + local BuildDir + local SrcDir + local AompCmake + local Gfxlist + local -a AOMP_SET_NINJA_GEN + local -a MYCMAKEOPTS + + BuildDir="$(get_build_dir "$Cfg")" + SrcDir="$(get_src_dir)" + AompCmake="$(cfgvar AOMP_CMAKE)" + Gfxlist="$(cfgvar ROCMLIBS_GFXLIST)" + setup_env + + if "$(cfgbool AOMP_USE_NINJA)"; then + AOMP_SET_NINJA_GEN=(-G Ninja) + fi + + MYCMAKEOPTS=("${AOMP_SET_NINJA_GEN[@]}" + -DCMAKE_BUILD_TYPE="$(cfgvar BUILD_TYPE)" + -DLLAMA_HIPBLAS=ON + -DCMAKE_PREFIX_PATH="$LLVM_INSTALL_LOC/lib/cmake" + -DCMAKE_INSTALL_PREFIX="$AOMP_INSTALL_DIR/PowerInfer" + -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" + -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" + -DHIP_PLATFORM=amd + -DAMDGPU_TARGETS="$Gfxlist") + + mkdir -p "$BuildDir" + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running cmake for PowerInfer $Cfg ---- " + echo "$AompCmake $(shquot "${MYCMAKEOPTS[@]}") $SrcDir" + + if ! env CXX="$AOMP/bin/hipcc" "$AompCmake" "${MYCMAKEOPTS[@]}" "$SrcDir"; then echo "ERROR cmake failed. Cmake flags" - echo " $MYCMAKEOPTS" + echo " $(shquot "${MYCMAKEOPTS[@]}")" exit 1 fi -fi - -echo -echo " -----Running make ---- " -echo make -j $AOMP_JOB_THREADS -env CXX=$AOMP_INSTALL_DIR/bin/hipcc make -j $AOMP_JOB_THREADS -if [ $? != 0 ] ; then - echo "ERROR make -j $AOMP_JOB_THREADS failed" - exit 1 -fi - -if [ "$1" == "install" ] ; then - echo " -----Installing to $AOMP_INSTALL_DIR ---- " - $SUDO make install - if [ $? != 0 ] ; then - echo "ERROR make install install failed " + popd >& /dev/null || exit +} + +task_build() { + local Cfg=$1 + local BuildDir + local Jobs + BuildDir="$(get_build_dir "$Cfg")" + Jobs="$(cfgvar AOMP_JOB_THREADS)" + setup_env + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Running make for PowerInfer $Cfg ---- " + if ! env CXX="$AOMP_INSTALL_DIR/bin/hipcc" make -j"$Jobs"; then + echo "ERROR make -j $Jobs failed" exit 1 fi + popd >& /dev/null || exit +} + +task_install() { + local Cfg=$1 + local BuildDir + local InstallDir + BuildDir="$(get_build_dir "$Cfg")" + InstallDir="$(get_install_dir "$Cfg")" + + pushd "$BuildDir" >& /dev/null || exit + echo " -----Installing to $InstallDir ---- " + if ! $SUDO make install; then + echo "ERROR make install failed " + exit 1 + fi + popd >& /dev/null || exit echo - echo "SUCCESSFUL INSTALL to $AOMP_INSTALL_DIR/PowerInfer" + echo "SUCCESSFUL INSTALL to $InstallDir" echo - pushd $_repo_dir - cd gguf-py +} + +task_postinstall() { + local Cfg=$1 + local SrcDir + local VenvDir + SrcDir="$(get_src_dir)" + VenvDir="$AOMP_INSTALL_DIR/../venv" + + echo " -----Installing PowerInfer python packages for $Cfg ---- " + python3 -m venv "$VenvDir" + # shellcheck disable=SC1091 + source "$VenvDir/bin/activate" + + pushd "$SrcDir/gguf-py" >& /dev/null || exit echo "Installing gguf python package" - python3 -m venv $AOMP_INSTALL_DIR/../venv - source $AOMP_INSTALL_DIR/../venv/bin/activate - pip install . - if [ $? != 0 ] ; then + if ! pip install .; then echo "ERROR pip install failed for PowerInfer/gguf-py package" + deactivate exit 1 fi - cd ../powerinfer-py + popd >& /dev/null || exit + + pushd "$SrcDir/powerinfer-py" >& /dev/null || exit echo "Installing powerinfer python package" - pip install . - if [ $? != 0 ] ; then + if ! pip install .; then echo "ERROR pip install failed for PowerInfer/powerinfer-py package" + deactivate exit 1 fi + popd >& /dev/null || exit + deactivate - popd - removepatch $_repo_dir -else - echo - echo "SUCCESSFUL BUILD, please run: $0 install" - echo " to install into $AOMP_INSTALL_DIR/PowerInfer " - echo -fi +} + +do_list_configs() { + echo "default" +} + +do_list_init() { + echo "precheck" + echo "patch" +} + +do_list_fini() { + echo "unpatch" +} + +# List of tasks per config. +do_list_tasks() { + local Cfg=$1 + if valid_config "$Cfg"; then + echo "clean" + echo "cmake" + echo "build" + echo "install" + echo "postinstall" + else + echo "Unknown config '$Cfg'" + fi +} + +command_dispatcher "$@" From 1ab78a4078de2c3a201fbb718b5a1d6d63e8ee45 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 04:54:55 -0500 Subject: [PATCH 51/71] Add aomp_build.py orchestrator and taskify build_supp.sh Introduce a unified, introspectable build orchestrator (bin/aomp_build.py) that resolves a component set from a CUDF-style config (bin/configs/aomp.cudf), topologically orders it, elaborates per-component tasks via each script's taskified `list` interface, and runs them by number/range/continue/glob with per-task logs. Supports feature aliases, build-variant selection, env-var flags, and git version-manifest export/import. Taskify build_supp.sh (and its build_prereq.sh symlink) with the standard command_dispatcher interface (single coarse default config) so every component speaks the same interface to the orchestrator. Local runcmd renamed to supp_runcmd to avoid clashing with aomp_utils' dispatcher runcmd; legacy direct invocation is preserved. --- bin/aomp_build.py | 738 ++++++++++++++++++++++++++++++++++++++++++ bin/build_supp.sh | 552 +++++++++++++++++-------------- bin/configs/aomp.cudf | 251 ++++++++++++++ 3 files changed, 1304 insertions(+), 237 deletions(-) create mode 100755 bin/aomp_build.py create mode 100644 bin/configs/aomp.cudf diff --git a/bin/aomp_build.py b/bin/aomp_build.py new file mode 100755 index 0000000000..30c28dd173 --- /dev/null +++ b/bin/aomp_build.py @@ -0,0 +1,738 @@ +#!/usr/bin/env python3 +"""aomp_build.py - unified, introspectable AOMP build orchestrator. + +This driver pulls the taskified per-component build scripts (build_.sh, +each speaking the command_dispatcher interface from aomp_utils) into a single +workflow: + + * resolve a component set from a CUDF-style config (configs/aomp.cudf), + honoring --add/--remove of components and feature aliases; + * topologically order the components (deterministic, declaration-order + tie-break, which reproduces the canonical build_aomp.sh ordering); + * elaborate fine-grained tasks by querying each component's `list`, + filtered by the selected build variant(s); + * list those tasks, or run them individually, by number/range, from a + point onward (`continue`), by glob, or all at once - mirroring the + `amd-build` selector grammar; + * write per-task numbered logs and tail the log on failure; + * export/import a JSON version manifest (per-component git fingerprint) for + reproducible builds. + +Stdlib only; intended to run under the same environment as the build scripts. +""" + +from __future__ import annotations + +import argparse +import datetime +import fnmatch +import json +import os +import re +import subprocess +import sys +from dataclasses import dataclass, field + +BIN_DIR = os.path.dirname(os.path.abspath(__file__)) +DEFAULT_CONFIG = os.path.join(BIN_DIR, "configs", "aomp.cudf") + + +# --------------------------------------------------------------------------- # +# Config model + CUDF parser +# --------------------------------------------------------------------------- # +@dataclass +class Package: + name: str + depends: list[str] = field(default_factory=list) + xdir: str = "." + order: int = 0 # declaration order, used as topo-sort tie-break + + +@dataclass +class Config: + packages: dict[str, Package] = field(default_factory=dict) + features: dict[str, list[str]] = field(default_factory=dict) + request: list[str] = field(default_factory=list) + + +def _split_list(value: str) -> list[str]: + return [item.strip() for item in value.split(",") if item.strip()] + + +def parse_cudf(path: str) -> Config: + """Parse a CUDF-style config file into a Config. + + Stanzas are separated by blank lines; '#' lines are comments. A line whose + first token has no trailing ':' is treated as a continuation of the + previous key's value (used to wrap long comma-separated lists). + """ + cfg = Config() + order = 0 + + try: + with open(path, encoding="utf-8") as handle: + raw_lines = handle.readlines() + except OSError as exc: + sys.exit(f"aomp_build: cannot read config '{path}': {exc}") + + stanza: dict[str, str] = {} + + def flush(stanza: dict[str, str]) -> None: + nonlocal order + if not stanza: + return + if "package" in stanza: + name = stanza["package"] + pkg = Package( + name=name, + depends=_split_list(stanza.get("depends", "")), + xdir=stanza.get("x-dir", ".") or ".", + order=order, + ) + cfg.packages[name] = pkg + order += 1 + elif "feature" in stanza: + cfg.features[stanza["feature"]] = _split_list(stanza.get("expands", "")) + elif "request" in stanza or "install" in stanza: + cfg.request = _split_list(stanza.get("install", "")) + + last_key: str | None = None + for line in raw_lines: + stripped = line.strip() + if not stripped: + flush(stanza) + stanza = {} + last_key = None + continue + if stripped.startswith("#"): + continue + # Continuation line: no "key:" at the start. + if ":" not in stripped.split(" ", 1)[0] and last_key is not None: + stanza[last_key] = (stanza.get(last_key, "") + " " + stripped).strip() + continue + key, _, value = stripped.partition(":") + key = key.strip() + stanza[key] = value.strip() + last_key = key + flush(stanza) + + if not cfg.packages: + sys.exit(f"aomp_build: no packages found in config '{path}'") + return cfg + + +# --------------------------------------------------------------------------- # +# Feature expansion + dependency resolution +# --------------------------------------------------------------------------- # +def expand_names(names: list[str], cfg: Config) -> set[str]: + """Expand a list of component/feature names into a set of components.""" + result: set[str] = set() + for name in names: + if name in cfg.features: + result.update(cfg.features[name]) + else: + result.add(name) + return result + + +def resolve_components( + cfg: Config, adds: list[str], removes: list[str] +) -> list[str]: + """Resolve the final, topologically ordered component list. + + request +/- (features|components), then transitive dependency closure with + removal cascade: removing a component also drops anything that depends on + it (directly or transitively). + """ + requested = set(cfg.request) + requested |= expand_names(adds, cfg) + removed = expand_names(removes, cfg) + requested -= removed + + unknown = {n for n in requested | removed if n not in cfg.packages} + if unknown: + sys.exit( + "aomp_build: unknown component(s): " + ", ".join(sorted(unknown)) + ) + + # Transitive dependency closure with removal cascade. + final = set(requested) + changed = True + while changed: + changed = False + for comp in list(final): + for dep in cfg.packages[comp].depends: + if dep in removed: + final.discard(comp) + removed.add(comp) + changed = True + break + if dep not in final: + final.add(dep) + changed = True + + return topo_sort(cfg, final) + + +def topo_sort(cfg: Config, comps: set[str]) -> list[str]: + """Deterministic Kahn topological sort with declaration-order tie-break.""" + indeg = {c: 0 for c in comps} + succ: dict[str, list[str]] = {c: [] for c in comps} + for comp in comps: + for dep in cfg.packages[comp].depends: + if dep in comps: + indeg[comp] += 1 + succ[dep].append(comp) + + ready = sorted((c for c in comps if indeg[c] == 0), + key=lambda c: cfg.packages[c].order) + ordered: list[str] = [] + while ready: + comp = ready.pop(0) + ordered.append(comp) + for nxt in succ[comp]: + indeg[nxt] -= 1 + if indeg[nxt] == 0: + ready.append(nxt) + ready.sort(key=lambda c: cfg.packages[c].order) + + if len(ordered) != len(comps): + cycle = comps - set(ordered) + sys.exit("aomp_build: dependency cycle among: " + ", ".join(sorted(cycle))) + return ordered + + +# --------------------------------------------------------------------------- # +# Build-script invocation helpers +# --------------------------------------------------------------------------- # +def script_path(cfg: Config, comp: str) -> str: + xdir = cfg.packages[comp].xdir + if xdir in (".", "", None): + return os.path.join(BIN_DIR, f"build_{comp}.sh") + return os.path.join(BIN_DIR, xdir, f"build_{comp}.sh") + + +def run_script_capture(path: str, args: list[str], env: dict[str, str]) -> str: + """Run a build script and return stdout (used for introspection).""" + proc = subprocess.run( + ["bash", path, *args], + capture_output=True, + text=True, + env=env, + ) + if proc.returncode != 0: + sys.stderr.write(proc.stderr) + sys.exit( + f"aomp_build: '{os.path.basename(path)} {' '.join(args)}' " + f"failed (rc={proc.returncode})" + ) + return proc.stdout + + +def discover_env() -> dict[str, str]: + """Source aomp_utils + aomp_common_vars to learn BUILD_DIR/AOMP_REPOS.""" + snippet = ( + f'. "{BIN_DIR}/aomp_utils" >/dev/null 2>&1; ' + f'. "{BIN_DIR}/aomp_common_vars" >/dev/null 2>&1; ' + 'printf "%s\\n" "$BUILD_DIR" "$AOMP_REPOS" "$AOMP_REPO_NAME"' + ) + proc = subprocess.run( + ["bash", "-c", snippet], capture_output=True, text=True + ) + out = proc.stdout.splitlines() + out += [""] * (3 - len(out)) + return { + "BUILD_DIR": out[0] or os.path.join(os.path.expanduser("~"), "git", "aomp"), + "AOMP_REPOS": out[1] or os.path.join(os.path.expanduser("~"), "git", "aomp"), + "AOMP_REPO_NAME": out[2] or "aomp", + } + + +# --------------------------------------------------------------------------- # +# Task elaboration +# --------------------------------------------------------------------------- # +@dataclass +class Task: + comp: str + action: str # e.g. "cmake" (without the "task_" prefix) + cfgname: str | None # build config/variant, e.g. "default" / "asan" + script: str # path to build_.sh + script_args: list[str] # args to pass back to the script + + @property + def name(self) -> str: + return f"{self.comp}/{self.action}" + + +def component_configs(script: str, env: dict[str, str]) -> list[str]: + out = run_script_capture(script, ["list_configs"], env) + return [line.strip() for line in out.splitlines() if line.strip()] + + +def select_variants( + comp: str, available: list[str], global_variants: list[str], + per_comp: dict[str, list[str]], +) -> list[str]: + """Decide which build configs to elaborate for a component. + + Components advertise their configs via `list_configs`. Two styles exist: + style-A always offers a plain "default" plus opt-in variants (asan/debug); + style-B (e.g. the runtimes) derives its config set from the environment and + has no "default". So with no explicit --variant we build "default" when it + is offered, otherwise every advertised config (the intended normal build + for style-B). An explicit --variant is intersected with the advertised set. + """ + if comp in per_comp: + wanted = per_comp[comp] + elif global_variants: + wanted = global_variants + else: + wanted = None # no explicit request + + if wanted is None: + if "default" in available: + return ["default"] + return list(available) + + chosen = [v for v in wanted if v in available] + if chosen: + return chosen + # Explicit variant request didn't match this component: fall back to a + # plain default if it has one, else all advertised configs. + if "default" in available: + return ["default"] + return list(available) + + +def elaborate_tasks( + cfg: Config, components: list[str], env: dict[str, str], + global_variants: list[str], per_comp_variants: dict[str, list[str]], + include_clean: bool, +) -> list[Task]: + tasks: list[Task] = [] + for comp in components: + script = script_path(cfg, comp) + if not os.path.exists(script): + sys.exit(f"aomp_build: missing build script for '{comp}': {script}") + available = component_configs(script, env) + wanted = select_variants( + comp, available, global_variants, per_comp_variants + ) + listing = run_script_capture(script, ["list"], env).splitlines() + for line in listing: + toks = line.split() + if not toks: + continue + action_tok = toks[0] + if not action_tok.startswith("task_"): + continue + action = action_tok[len("task_"):] + taskcfg = toks[1] if len(toks) > 1 else None + # Variant filter: config-bearing tasks must match a wanted config; + # config-less tasks (init/fini such as patch/unpatch) always run. + if taskcfg is not None and taskcfg not in wanted: + continue + if action == "clean" and not include_clean: + continue + tasks.append( + Task( + comp=comp, + action=action, + cfgname=taskcfg, + script=script, + script_args=toks, + ) + ) + return tasks + + +# --------------------------------------------------------------------------- # +# Selector grammar (amd-build style) +# --------------------------------------------------------------------------- # +def brace_expand(token: str) -> list[str]: + """Minimal brace expansion: a{b,c}d -> [abd, acd]. Single level.""" + match = re.search(r"\{([^{}]*)\}", token) + if not match: + return [token] + pre, post = token[: match.start()], token[match.end():] + out: list[str] = [] + for part in match.group(1).split(","): + out.extend(brace_expand(pre + part + post)) + return out + + +def select_tasks(tasks: list[Task], selectors: list[str]) -> list[int]: + """Return the indices (into tasks) selected by the positional selectors. + + Grammar (mirrors amd-build): + * no selectors -> all tasks + * N -> task number N (1-based) + * N--M -> inclusive range + * continue [N|name] -> from the given task to the end + * glob (with {a,b} braces)-> substring/glob match on "comp/action" + """ + if not selectors: + return list(range(len(tasks))) + + names = [t.name for t in tasks] + selected: list[int] = [] + + def add(idx: int) -> None: + if 0 <= idx < len(tasks) and idx not in selected: + selected.append(idx) + + def resolve_point(token: str) -> int: + if token.isdigit(): + return int(token) - 1 + for i, nm in enumerate(names): + if token == nm or fnmatch.fnmatch(nm, token) or token in nm: + return i + sys.exit(f"aomp_build: selector '{token}' matched no task") + + i = 0 + while i < len(selectors): + sel = selectors[i] + if sel == "continue": + if i + 1 >= len(selectors): + sys.exit("aomp_build: 'continue' requires a task number or name") + start = resolve_point(selectors[i + 1]) + for idx in range(start, len(tasks)): + add(idx) + i += 2 + continue + if "--" in sel: + lo_s, hi_s = sel.split("--", 1) + lo, hi = resolve_point(lo_s), resolve_point(hi_s) + if lo > hi: + lo, hi = hi, lo + for idx in range(lo, hi + 1): + add(idx) + i += 1 + continue + if sel.isdigit(): + add(int(sel) - 1) + i += 1 + continue + # Glob / substring match (with brace expansion). + matched = False + for pat in brace_expand(sel): + for idx, nm in enumerate(names): + if fnmatch.fnmatch(nm, pat) or pat == nm or pat in nm: + add(idx) + matched = True + if not matched: + sys.exit(f"aomp_build: selector '{sel}' matched no task") + i += 1 + + selected.sort() + return selected + + +# --------------------------------------------------------------------------- # +# Execution +# --------------------------------------------------------------------------- # +def tail_file(path: str, n: int = 40) -> str: + try: + with open(path, encoding="utf-8", errors="replace") as handle: + lines = handle.readlines() + except OSError: + return "" + return "".join(lines[-n:]) + + +def run_tasks( + tasks: list[Task], indices: list[int], env: dict[str, str], log_dir: str, + dry_run: bool, +) -> int: + os.makedirs(log_dir, exist_ok=True) + total = len(indices) + for count, idx in enumerate(indices, start=1): + task = tasks[idx] + num = idx + 1 + safe = task.name.replace("/", "-") + log_path = os.path.join(log_dir, f"{num:03d}-{safe}.log") + cmd = ["bash", task.script, *task.script_args] + header = ( + f"[{count}/{total}] task {num}: {task.name}" + f"{(' (' + task.cfgname + ')') if task.cfgname else ''}" + ) + if dry_run: + print(f"{header}\n {' '.join(cmd)} > {log_path}") + continue + print(f"{header} -> {log_path}", flush=True) + start = datetime.datetime.now() + with open(log_path, "w", encoding="utf-8") as log: + log.write(f"### task {num}: {task.name}\n") + log.write(f"### command: {' '.join(cmd)}\n") + log.write(f"### start: {start.isoformat()}\n\n") + log.flush() + proc = subprocess.run(cmd, stdout=log, stderr=subprocess.STDOUT, env=env) + end = datetime.datetime.now() + log.write(f"\n### end: {end.isoformat()} (rc={proc.returncode})\n") + if proc.returncode != 0: + print( + f"\naomp_build: FAILED task {num} ({task.name}), rc={proc.returncode}", + file=sys.stderr, + ) + print(f"--- tail of {log_path} ---", file=sys.stderr) + print(tail_file(log_path), file=sys.stderr) + return proc.returncode + return 0 + + +# --------------------------------------------------------------------------- # +# Version manifest (git fingerprint) +# --------------------------------------------------------------------------- # +def git_facts(src: str) -> dict | None: + if not src or not os.path.isdir(os.path.join(src, ".git")): + return None + + def git(*args: str) -> str: + proc = subprocess.run( + ["git", "-C", src, *args], capture_output=True, text=True + ) + return proc.stdout.strip() if proc.returncode == 0 else "" + + return { + "sha": git("rev-parse", "HEAD"), + "repo": git("config", "--get", "remote.origin.url"), + "branch": git("rev-parse", "--abbrev-ref", "HEAD"), + "dirty": bool(git("status", "--porcelain")), + } + + +def component_src_dir(cfg: Config, comp: str, env: dict[str, str]) -> str: + script = script_path(cfg, comp) + if not os.path.exists(script): + return "" + return run_script_capture(script, ["show_src_dir"], env).strip() + + +def export_manifest( + cfg: Config, components: list[str], env: dict[str, str], path: str, + config_name: str, +) -> None: + manifest = { + "generated": datetime.datetime.now().isoformat(), + "config": config_name, + "order": components, + "components": {}, + } + for comp in components: + src = component_src_dir(cfg, comp, env) + facts = git_facts(src) + if facts is not None: + manifest["components"][comp] = facts + os.makedirs(os.path.dirname(os.path.abspath(path)), exist_ok=True) + with open(path, "w", encoding="utf-8") as handle: + json.dump(manifest, handle, indent=2, sort_keys=True) + handle.write("\n") + print(f"aomp_build: wrote manifest for {len(manifest['components'])} " + f"component(s) to {path}") + + +def import_manifest( + cfg: Config, components: list[str], env: dict[str, str], path: str, +) -> int: + try: + with open(path, encoding="utf-8") as handle: + manifest = json.load(handle) + except (OSError, json.JSONDecodeError) as exc: + sys.exit(f"aomp_build: cannot read manifest '{path}': {exc}") + + recorded = manifest.get("components", {}) + targets = [c for c in components if c in recorded] + + # First pass: refuse if any target repo has local modifications. + plan: list[tuple[str, str, str]] = [] # (comp, src, sha) + dirty: list[str] = [] + for comp in targets: + src = component_src_dir(cfg, comp, env) + facts = git_facts(src) + if facts is None: + print(f"aomp_build: skipping '{comp}' (no git source at {src})") + continue + if facts["dirty"]: + dirty.append(comp) + plan.append((comp, src, recorded[comp]["sha"])) + + if dirty: + sys.exit( + "aomp_build: refusing to import manifest; local modifications in: " + + ", ".join(dirty) + ) + + # Second pass: check out recorded SHAs. + for comp, src, sha in plan: + if not sha: + print(f"aomp_build: skipping '{comp}' (no recorded sha)") + continue + print(f"aomp_build: checking out {comp} @ {sha[:12]} in {src}") + proc = subprocess.run(["git", "-C", src, "checkout", sha]) + if proc.returncode != 0: + sys.exit(f"aomp_build: git checkout failed for '{comp}'") + return 0 + + +# --------------------------------------------------------------------------- # +# Environment / CLI flag mapping +# --------------------------------------------------------------------------- # +def parse_variant_specs(specs: list[str]) -> tuple[list[str], dict[str, list[str]]]: + """Split --variant values into global variants and per-component overrides. + + A bare value (e.g. "asan") applies globally; "comp=cfg" overrides one + component. Repeatable; "comp=cfg" accumulates multiple configs per comp. + """ + global_variants: list[str] = [] + per_comp: dict[str, list[str]] = {} + for spec in specs: + if "=" in spec: + comp, _, val = spec.partition("=") + per_comp.setdefault(comp.strip(), []).append(val.strip()) + else: + global_variants.append(spec.strip()) + return global_variants, per_comp + + +def build_child_env(args: argparse.Namespace) -> dict[str, str]: + env = dict(os.environ) + + def setenv(name: str, value: str) -> None: + env[name] = value + + if args.jobs is not None: + setenv("AOMP_JOB_THREADS", str(args.jobs)) + if args.ninja is not None: + setenv("AOMP_USE_NINJA", "1" if args.ninja else "0") + if args.ccache is not None: + setenv("AOMP_USE_CCACHE", "1" if args.ccache else "0") + if args.gfx: + setenv("GFXLIST", args.gfx) + if args.build_type: + setenv("BUILD_TYPE", args.build_type) + if args.sudo: + setenv("SUDO", "yes") + return env + + +# --------------------------------------------------------------------------- # +# CLI +# --------------------------------------------------------------------------- # +def build_arg_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + prog="aomp_build.py", + description="Unified AOMP component build orchestrator.", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=( + "Selectors (positional, amd-build style):\n" + " (none) run all elaborated tasks\n" + " list print the numbered task list and exit\n" + " N run task number N (1-based)\n" + " N--M run the inclusive range of tasks N..M\n" + " continue X run from task X (number or name) to the end\n" + " comp/action glob/substring match (supports {a,b} braces)\n" + ), + ) + parser.add_argument("selectors", nargs="*", help="task selector(s); see below") + parser.add_argument("-c", "--config", default=DEFAULT_CONFIG, + help=f"CUDF config file (default: {DEFAULT_CONFIG})") + parser.add_argument("--add", action="append", default=[], metavar="NAME", + help="add a component or feature (repeatable)") + parser.add_argument("--remove", action="append", default=[], metavar="NAME", + help="remove a component or feature (repeatable)") + parser.add_argument("--variant", action="append", default=[], metavar="SPEC", + help="build variant: 'cfg' (global) or 'comp=cfg' " + "(per-component); repeatable") + parser.add_argument("-C", "--clean", action="store_true", + help="include 'clean' tasks (default: skip for " + "incremental builds)") + parser.add_argument("-n", "--dry-run", action="store_true", + help="show what would run without executing") + parser.add_argument("--components", action="store_true", + help="print the resolved, ordered component list and exit") + parser.add_argument("--log-dir", default=None, + help="directory for per-task logs " + "(default: /aomp_build_logs)") + # Environment knobs passed to child build scripts. + parser.add_argument("-j", "--jobs", type=int, default=None, + help="parallel build threads (AOMP_JOB_THREADS)") + parser.add_argument("--ninja", dest="ninja", action="store_true", default=None, + help="use ninja (AOMP_USE_NINJA=1)") + parser.add_argument("--no-ninja", dest="ninja", action="store_false", + help="do not use ninja (AOMP_USE_NINJA=0)") + parser.add_argument("--ccache", dest="ccache", action="store_true", default=None, + help="use ccache (AOMP_USE_CCACHE=1)") + parser.add_argument("--no-ccache", dest="ccache", action="store_false", + help="do not use ccache (AOMP_USE_CCACHE=0)") + parser.add_argument("--gfx", default=None, metavar="LIST", + help="GPU target list (GFXLIST)") + parser.add_argument("--build-type", default=None, metavar="TYPE", + help="CMake build type (BUILD_TYPE)") + parser.add_argument("--sudo", action="store_true", + help="install with sudo (SUDO=yes)") + # Version manifest. + parser.add_argument("--export-manifest", nargs="?", const="", metavar="FILE", + help="export a git fingerprint manifest and exit " + "(default path under /manifests)") + parser.add_argument("--import-manifest", metavar="FILE", + help="check out recorded git SHAs before building") + return parser + + +def main(argv: list[str]) -> int: + args = build_arg_parser().parse_args(argv) + + cfg = parse_cudf(args.config) + config_name = os.path.splitext(os.path.basename(args.config))[0] + env_info = discover_env() + child_env = build_child_env(args) + + components = resolve_components(cfg, args.add, args.remove) + + if args.components: + for comp in components: + print(comp) + return 0 + + build_dir = env_info["BUILD_DIR"] + log_dir = args.log_dir or os.path.join(build_dir, "aomp_build_logs") + manifest_dir = os.path.join(build_dir, "manifests") + + # Manifest export is a standalone action. + if args.export_manifest is not None: + path = args.export_manifest or os.path.join( + manifest_dir, f"{config_name}-manifest.json" + ) + export_manifest(cfg, components, child_env, path, config_name) + return 0 + + # Manifest import runs as a pre-step before any task execution. + if args.import_manifest: + rc = import_manifest(cfg, components, child_env, args.import_manifest) + if rc != 0: + return rc + + global_variants, per_comp_variants = parse_variant_specs(args.variant) + tasks = elaborate_tasks( + cfg, components, child_env, global_variants, per_comp_variants, + include_clean=args.clean, + ) + + # `list` selector: print the numbered task list and exit. + if args.selectors and args.selectors[0] == "list": + width = len(str(len(tasks))) + for i, task in enumerate(tasks, start=1): + cfgstr = f" [{task.cfgname}]" if task.cfgname else "" + print(f"{i:>{width}} {task.name}{cfgstr}") + return 0 + + indices = select_tasks(tasks, args.selectors) + if not indices: + print("aomp_build: no tasks selected") + return 0 + + return run_tasks(tasks, indices, child_env, log_dir, args.dry_run) + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/bin/build_supp.sh b/bin/build_supp.sh index 0cf8b2de6a..c3c993bf3c 100755 --- a/bin/build_supp.sh +++ b/bin/build_supp.sh @@ -63,7 +63,7 @@ thisdir=$(dirname "$realpath") # --- end standard header ---- FLANG=${FLANG:-flang} -function runcmd(){ +function supp_runcmd(){ THISCMD=$1 if [ "$DRYRUN" ] ; then echo "$THISCMD" @@ -80,6 +80,128 @@ function runcmd(){ fi } +# Helper: build a space-separated list of supplemental/prerequisite components. +build_components(){ + local _components="$1" + local curdir=$PWD + local _component + local _thisdate + for _component in $_components ; do + _thisdate=$(date) + { + echo "" + echo "# -------------------------------------------------" + echo "# $_component build started on $_thisdate" + } >> "$CMDLOGFILE" + if [ "$_component" == "openmpi" ] ; then + buildopenmpi + elif [ "$_component" == "rocmopenmpi" ] ; then + buildrocmopenmpi + elif [ "$_component" == "xpmem" ] ; then + buildxpmem + elif [ "$_component" == "ucx" ] ; then + builducx + elif [ "$_component" == "ucc" ] ; then + builducc + elif [ "$_component" == "silo" ] ; then + buildsilo + elif [ "$_component" == "hdf5" ] ; then + buildhdf5 + elif [ "$_component" == "fftw" ] ; then + buildfftw + elif [ "$_component" == "hwloc" ] ; then + buildhwloc + elif [ "$_component" == "cmake" ] ; then + buildcmake + elif [ "$_component" == "rocmsmilib" ] ; then + buildrocmsmilib + elif [ "$_component" == "ninja" ] ; then + buildninja + elif [ "$_component" == "aqlprofile" ] ; then + getrocmpackage aqlprofile hsa-amd-aqlprofile 1.0.0 + elif [ "$_component" == "openclicdloader" ] ; then + getrocmpackage openclicdloader rocm-opencl-icd-loader 1.2 + elif [ "$_component" == "rocm-core" ] ; then + getrocmpackage rocm-core rocm-core 7.1.0 + else + echo "ERROR: Invalid component name $_component" >>"$CMDLOGFILE" + echo "ERROR: Invalid component name $_component" + if [ "$sname" == "build_prereq.sh" ] ; then + echo " Must be a subset of: $PREREQUISITE_COMPONENTS" + else + echo " Must be a subset of: $SUPPLEMENTAL_COMPONENTS" + fi + exit 0 + fi + _thisdate=$(date) + echo "# DONE: successful build of $_component on $_thisdate " >>"$CMDLOGFILE" + done + cd "$curdir" || exit +} + +# Return the default component list for the current invocation name. When +# invoked through the build_prereq.sh symlink, build the prerequisite set; +# otherwise build the supplemental set. +default_components(){ + if [ "$sname" == "build_prereq.sh" ] ; then + echo "$PREREQUISITE_COMPONENTS" + else + echo "$SUPPLEMENTAL_COMPONENTS" + fi +} + +# These components are downloaded/cloned on demand rather than tracked as a +# single git source tree, so there is no meaningful source directory. +get_src_dir(){ + echo "" +} + +get_build_dir(){ + echo -n "$AOMP_SUPP_BUILD" +} + +get_install_dir(){ + echo -n "$AOMP_SUPP" +} + +# build_supp/build_prereq is modeled as a single coarse "build everything" +# task. The actual per-component dependency handling lives in the build +# helpers above (e.g. ucc pulls in ucx/xpmem on demand). +task_build(){ + local Cfg=$1 + build_components "$(default_components)" +} + +# build_aomp.sh will try to install each component (including "prereq"), but +# supplemental/prerequisite artifacts are not installed into the AOMP +# installation, so install is intentionally a no-op. +task_install(){ + local Cfg=$1 + echo "Nothing to install for $sname (supplemental/prerequisite components)" +} + +do_list_configs(){ + echo "default" +} + +do_list_init(){ + : +} + +do_list_fini(){ + : +} + +do_list_tasks(){ + local Cfg=$1 + if valid_config "$Cfg"; then + echo "build" + echo "install" + else + echo "Unknown config '$Cfg'" + fi +} + function runcmdout(){ THISCMD=$1 OUTFILE=$2 @@ -178,25 +300,25 @@ function buildxpmem(){ return fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" + supp_runcmd "rm -rf $_builddir" fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "wget https://github.com/openucx/xpmem/archive/refs/tags/v$_version.tar.gz" - runcmd "tar -xzf v$_version.tar.gz" - runcmd "cd xpmem-$_version" + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "wget https://github.com/openucx/xpmem/archive/refs/tags/v$_version.tar.gz" + supp_runcmd "tar -xzf v$_version.tar.gz" + supp_runcmd "cd xpmem-$_version" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" - runcmd "./autogen.sh" - runcmd "./configure --prefix=$_installdir" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "./autogen.sh" + supp_runcmd "./configure --prefix=$_installdir" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -231,22 +353,22 @@ function builducx(){ return fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" - fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "wget https://github.com/openucx/ucx/releases/download/v$_version/ucx-$_version.tar.gz" - runcmd "tar -xzf ucx-$_version.tar.gz" - runcmd "cd ucx-$_version" - runcmd "mkdir -p build" - runcmd "cd build" + supp_runcmd "rm -rf $_builddir" + fi + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "wget https://github.com/openucx/ucx/releases/download/v$_version/ucx-$_version.tar.gz" + supp_runcmd "tar -xzf ucx-$_version.tar.gz" + supp_runcmd "cd ucx-$_version" + supp_runcmd "mkdir -p build" + supp_runcmd "cd build" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" + supp_runcmd "mkdir -p $_installdir" # Configure UCX with ROCm and XPMEM support - runcmd "../contrib/configure-release \ + supp_runcmd "../contrib/configure-release \ --prefix=$_installdir \ --with-rocm=$ROCM_PATH \ --with-xpmem=$XPMEM_PATH \ @@ -259,12 +381,12 @@ function builducx(){ --enable-params-check \ --enable-examples" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -299,31 +421,31 @@ function builducc(){ return fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" + supp_runcmd "rm -rf $_builddir" fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "wget https://github.com/openucx/ucc/archive/refs/tags/v$_version.tar.gz" - runcmd "tar -xzf v$_version.tar.gz" - runcmd "cd ucc-$_version" + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "wget https://github.com/openucx/ucc/archive/refs/tags/v$_version.tar.gz" + supp_runcmd "tar -xzf v$_version.tar.gz" + supp_runcmd "cd ucc-$_version" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" - runcmd "./autogen.sh" + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "./autogen.sh" # Configure UCC with ROCm and UCX support - runcmd "./configure \ + supp_runcmd "./configure \ --prefix=$_installdir \ --with-rocm=$ROCM_PATH \ --with-ucx=$UCX_PATH" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -365,25 +487,25 @@ function _buildopenmpi_impl(){ fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" - fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "wget https://download.open-mpi.org/release/open-mpi/$_release/openmpi-$_version.tar.bz2" - runcmd "bzip2 -d openmpi-$_version.tar.bz2" - runcmd "tar -xf openmpi-$_version.tar" - runcmd "cd openmpi-$_version" + supp_runcmd "rm -rf $_builddir" + fi + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "wget https://download.open-mpi.org/release/open-mpi/$_release/openmpi-$_version.tar.bz2" + supp_runcmd "bzip2 -d openmpi-$_version.tar.bz2" + supp_runcmd "tar -xf openmpi-$_version.tar" + supp_runcmd "cd openmpi-$_version" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" + supp_runcmd "mkdir -p $_installdir" # Update configure to recognize flang - runcmd "cp configure configure-orig" + supp_runcmd "cp configure configure-orig" runcmdout "sed -e s/flang\s*)/flang*)/ configure-orig" configure # Configure with common options plus any extra options - runcmd "./configure \ + supp_runcmd "./configure \ --prefix=$_installdir \ --with-hwloc=$AOMP_SUPP/hwloc \ --with-hwloc-libdir=$AOMP_SUPP/hwloc/lib \ @@ -401,12 +523,12 @@ function _buildopenmpi_impl(){ fi fi - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -488,29 +610,29 @@ function buildninja(){ return fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" + supp_runcmd "rm -rf $_builddir" fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "wget https://github.com/ninja-build/ninja/archive/refs/tags/v${_version}.tar.gz" - runcmd "tar -xzf v${_version}.tar.gz" - runcmd "cd ninja-$_version" + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "wget https://github.com/ninja-build/ninja/archive/refs/tags/v${_version}.tar.gz" + supp_runcmd "tar -xzf v${_version}.tar.gz" + supp_runcmd "cd ninja-$_version" _patch_file="$thisdir/patches/ninja-nprocs-v${_version}.patch" if [ -r "$_patch_file" ]; then runcmd "cp $_patch_file $_builddir" runcmdin "patch --merge -p1" "$_patch_file" fi if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir/bin" - runcmd "$AOMP_SUPP/cmake/bin/cmake -Bbuild-cmake" - runcmd "$AOMP_SUPP/cmake/bin/cmake --build build-cmake" - runcmd "cp -p build-cmake/ninja $_installdir/bin/." + supp_runcmd "mkdir -p $_installdir/bin" + supp_runcmd "$AOMP_SUPP/cmake/bin/cmake -Bbuild-cmake" + supp_runcmd "$AOMP_SUPP/cmake/bin/cmake --build build-cmake" + supp_runcmd "cp -p build-cmake/ninja $_installdir/bin/." if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -537,44 +659,44 @@ function getrocmpackage(){ return fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" + supp_runcmd "rm -rf $_builddir" fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" osname=$(grep -e ^NAME= < /etc/os-release) if [[ $osname =~ "Ubuntu" ]]; then # not sure if deb_version is 20 or 22 deb_version="24" os_version=$(grep VERSION_ID /etc/os-release | cut -d"\"" -f2) [ "$os_version" == "22.04" ] && deb_version="22" - runcmd "wget https://repo.radeon.com/rocm/apt/$_version/pool/main/$_directory/$_packagename$_packageversion/$_packagename${_packageversion}_${_componentversion}.${_fullversion}-${_buildnumber}~${deb_version}.04_amd64.deb" - runcmd "dpkg -x $_packagename${_packageversion}_${_componentversion}.${_fullversion}-${_buildnumber}~${deb_version}.04_amd64.deb $_builddir" + supp_runcmd "wget https://repo.radeon.com/rocm/apt/$_version/pool/main/$_directory/$_packagename$_packageversion/$_packagename${_packageversion}_${_componentversion}.${_fullversion}-${_buildnumber}~${deb_version}.04_amd64.deb" + supp_runcmd "dpkg -x $_packagename${_packageversion}_${_componentversion}.${_fullversion}-${_buildnumber}~${deb_version}.04_amd64.deb $_builddir" elif [[ $osname =~ "SLES" ]]; then - runcmd "wget https://repo.radeon.com/rocm/zyp/$_version/main/$_packagename$_packageversion-$_componentversion.$_fullversion-sles156.$_buildnumber.x86_64.rpm" + supp_runcmd "wget https://repo.radeon.com/rocm/zyp/$_version/main/$_packagename$_packageversion-$_componentversion.$_fullversion-sles156.$_buildnumber.x86_64.rpm" echo "$_packagename$_packageversion-$_componentversion.$_fullversion-sles156.$_buildnumber.x86_64.rpm | cpio -idm" rpm2cpio "$_packagename$_packageversion-$_componentversion.$_fullversion-sles156.$_buildnumber.x86_64.rpm" | cpio -idm else - runcmd "wget https://repo.radeon.com/rocm/rhel8/$_version/main/$_packagename$_packageversion-$_componentversion.$_fullversion-$_buildnumber.el8.x86_64.rpm" + supp_runcmd "wget https://repo.radeon.com/rocm/rhel8/$_version/main/$_packagename$_packageversion-$_componentversion.$_fullversion-$_buildnumber.el8.x86_64.rpm" echo "$_packagename$_packageversion-$_componentversion.$_fullversion-$_buildnumber.el8.x86_64.rpm | cpio -idm" rpm2cpio "$_packagename$_packageversion-$_componentversion.$_fullversion-$_buildnumber.el8.x86_64.rpm" | cpio -idm fi if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi if [ "$_cname" == "rocm-core" ] ; then - runcmd "mkdir -p $_installdir" - runcmd "cp -rp $_builddir/opt/rocm-$_packageversion/. $_installdir" + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "cp -rp $_builddir/opt/rocm-$_packageversion/. $_installdir" else - runcmd "mkdir -p $_installdir/lib" - runcmd "cd $_installdir" - runcmd "cp -rp $_builddir/opt/rocm-$_packageversion/lib $_installdir" + supp_runcmd "mkdir -p $_installdir/lib" + supp_runcmd "cd $_installdir" + supp_runcmd "cp -rp $_builddir/opt/rocm-$_packageversion/lib $_installdir" fi if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -592,25 +714,25 @@ function buildhdf5(){ fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" - fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd " wget https://support.hdfgroup.org/ftp/HDF5/releases/$_release/hdf5-$_version/src/hdf5-$_version.tar.bz2" - runcmd "bzip2 -d hdf5-$_version.tar.bz2" - runcmd "tar -xf hdf5-$_version.tar" - runcmd "cd hdf5-$_version" + supp_runcmd "rm -rf $_builddir" + fi + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd " wget https://support.hdfgroup.org/ftp/HDF5/releases/$_release/hdf5-$_version/src/hdf5-$_version.tar.bz2" + supp_runcmd "bzip2 -d hdf5-$_version.tar.bz2" + supp_runcmd "tar -xf hdf5-$_version.tar" + supp_runcmd "cd hdf5-$_version" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" - runcmd "./configure --enable-fortran --prefix=$_installdir" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "./configure --enable-fortran --prefix=$_installdir" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -627,24 +749,24 @@ function buildsilo(){ fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" + supp_runcmd "rm -rf $_builddir" fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "wget https://github.com/LLNL/Silo/releases/download/$_version/silo-$_version.tar.xz" - runcmd "tar -x --xz -f silo-$_version.tar.xz" - runcmd "cd silo-$_version" + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "wget https://github.com/LLNL/Silo/releases/download/$_version/silo-$_version.tar.xz" + supp_runcmd "tar -x --xz -f silo-$_version.tar.xz" + supp_runcmd "cd silo-$_version" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" - runcmd "./configure --prefix=$_installdir" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "./configure --prefix=$_installdir" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -661,28 +783,28 @@ function buildfftw(){ fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" + supp_runcmd "rm -rf $_builddir" fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "wget http://www.fftw.org/fftw-$_version.tar.gz" - runcmd "tar -xzf fftw-$_version.tar.gz" - runcmd "cd fftw-$_version" + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "wget http://www.fftw.org/fftw-$_version.tar.gz" + supp_runcmd "tar -xzf fftw-$_version.tar.gz" + supp_runcmd "cd fftw-$_version" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" - fi - runcmd "mkdir -p $_installdir" - runcmd "./configure --prefix=$_installdir --enable-shared --enable-threads --enable-sse2 --enable-avx" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" - runcmd "make clean" - runcmd "./configure --prefix=$_installdir --enable-shared --enable-threads --enable-sse2 --enable-avx --enable-float" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "rm -rf $_installdir" + fi + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "./configure --prefix=$_installdir --enable-shared --enable-threads --enable-sse2 --enable-avx" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" + supp_runcmd "make clean" + supp_runcmd "./configure --prefix=$_installdir --enable-shared --enable-threads --enable-sse2 --enable-avx --enable-float" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -700,24 +822,24 @@ function buildcmake(){ fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" + supp_runcmd "rm -rf $_builddir" fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "wget https://github.com/Kitware/CMake/releases/download/v$_version/cmake-$_version.tar.gz" - runcmd "tar -xzf cmake-$_version.tar.gz" - runcmd "cd cmake-$_version" + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "wget https://github.com/Kitware/CMake/releases/download/v$_version/cmake-$_version.tar.gz" + supp_runcmd "tar -xzf cmake-$_version.tar.gz" + supp_runcmd "cd cmake-$_version" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" - runcmd "./bootstrap --parallel=8 --prefix=$_installdir" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "./bootstrap --parallel=8 --prefix=$_installdir" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -734,25 +856,25 @@ function buildrocmsmilib(){ fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" - fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "git clone -b release/rocm-rel-7.1 https://github.com/ROCm/rocm_smi_lib rocmsmilib-$_version" - runcmd "cd rocmsmilib-$_version" - runcmd "mkdir -p build" - runcmd "cd build" - runcmd "$AOMP_SUPP/cmake/bin/cmake -DCMAKE_INSTALL_PREFIX=$_installdir .." + supp_runcmd "rm -rf $_builddir" + fi + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "git clone -b release/rocm-rel-7.1 https://github.com/ROCm/rocm_smi_lib rocmsmilib-$_version" + supp_runcmd "cd rocmsmilib-$_version" + supp_runcmd "mkdir -p build" + supp_runcmd "cd build" + supp_runcmd "$AOMP_SUPP/cmake/bin/cmake -DCMAKE_INSTALL_PREFIX=$_installdir .." if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -775,25 +897,25 @@ function buildhwloc(){ exit 1 fi if [ -d "$_builddir" ] ; then - runcmd "rm -rf $_builddir" - fi - runcmd "mkdir -p $_builddir" - runcmd "cd $_builddir" - runcmd "git clone https://github.com/open-mpi/hwloc hwloc-$_version" - runcmd "cd hwloc-$_version" - runcmd "git checkout v$_version" - runcmd "./autogen.sh" - runcmd "./configure --prefix=$_installdir --with-pic=yes --enable-static=yes --enable-shared=no --disable-io --disable-libudev --disable-libxml2 --with-rocm=$AOMP_SUPP/rocsmilib" + supp_runcmd "rm -rf $_builddir" + fi + supp_runcmd "mkdir -p $_builddir" + supp_runcmd "cd $_builddir" + supp_runcmd "git clone https://github.com/open-mpi/hwloc hwloc-$_version" + supp_runcmd "cd hwloc-$_version" + supp_runcmd "git checkout v$_version" + supp_runcmd "./autogen.sh" + supp_runcmd "./configure --prefix=$_installdir --with-pic=yes --enable-static=yes --enable-shared=no --disable-io --disable-libudev --disable-libxml2 --with-rocm=$AOMP_SUPP/rocsmilib" if [ -d "$_installdir" ] ; then - runcmd "rm -rf $_installdir" + supp_runcmd "rm -rf $_installdir" fi - runcmd "mkdir -p $_installdir" - runcmd "make -j${AOMP_JOB_THREADS}" - runcmd "make install" + supp_runcmd "mkdir -p $_installdir" + supp_runcmd "make -j${AOMP_JOB_THREADS}" + supp_runcmd "make install" if [ -L "$_linkfrom" ] ; then - runcmd "rm $_linkfrom" + supp_runcmd "rm $_linkfrom" fi - runcmd "ln -sfr $_installdir $_linkfrom" + supp_runcmd "ln -sfr $_installdir $_linkfrom" echo "# $_linkfrom is now symbolic link to $_installdir " >>"$CMDLOGFILE" } @@ -805,6 +927,19 @@ if [ "$1" == "-h" ] ; then build_supp_help exit 0 fi + +# Task interface for the aomp_build.py orchestrator and the standard component +# task introspection. These keywords are routed to command_dispatcher; any +# other argument (or no argument) falls through to the legacy direct +# invocation below, which builds the default set or a list of named components. +case "$1" in + list|list_configs|list_tasks|list_init|list_fini|\ + show_src_dir|show_build_dir|show_install_dir|all|cmake|nocmake|task_*) + command_dispatcher "$@" + exit $? + ;; +esac + if [ "$1" == "install" ] ; then # build_aomp.sh will try to install each aomp component including "prereq" # but they are already installed so we just return here to avoid error message. @@ -812,65 +947,8 @@ if [ "$1" == "install" ] ; then exit 0 fi if [ "$1" == "" ] ; then - if [ "$sname" == "build_prereq.sh" ] ; then - _components="$PREREQUISITE_COMPONENTS" - else - _components="$SUPPLEMENTAL_COMPONENTS" - fi + _components="$(default_components)" else _components=$* fi -# save the current directory -curdir=$PWD -for _component in $_components ; do - _thisdate=$(date) - { - echo "" - echo "# -------------------------------------------------" - echo "# $_component build started on $_thisdate" - } >> "$CMDLOGFILE" - if [ "$_component" == "openmpi" ] ; then - buildopenmpi - elif [ "$_component" == "rocmopenmpi" ] ; then - buildrocmopenmpi - elif [ "$_component" == "xpmem" ] ; then - buildxpmem - elif [ "$_component" == "ucx" ] ; then - builducx - elif [ "$_component" == "ucc" ] ; then - builducc - elif [ "$_component" == "silo" ] ; then - buildsilo - elif [ "$_component" == "hdf5" ] ; then - buildhdf5 - elif [ "$_component" == "fftw" ] ; then - buildfftw - elif [ "$_component" == "hwloc" ] ; then - buildhwloc - elif [ "$_component" == "cmake" ] ; then - buildcmake - elif [ "$_component" == "rocmsmilib" ] ; then - buildrocmsmilib - elif [ "$_component" == "ninja" ] ; then - buildninja - elif [ "$_component" == "aqlprofile" ] ; then - getrocmpackage aqlprofile hsa-amd-aqlprofile 1.0.0 - elif [ "$_component" == "openclicdloader" ] ; then - getrocmpackage openclicdloader rocm-opencl-icd-loader 1.2 - elif [ "$_component" == "rocm-core" ] ; then - getrocmpackage rocm-core rocm-core 7.1.0 - else - echo "ERROR: Invalid component name $_component" >>"$CMDLOGFILE" - echo "ERROR: Invalid component name $_component" - if [ "$sname" == "build_prereq.sh" ] ; then - echo " Must be a subset of: $PREREQUISITE_COMPONENTS" - else - echo " Must be a subset of: $SUPPLEMENTAL_COMPONENTS" - fi - exit 0 - fi - _thisdate=$(date) - echo "# DONE: successful build of $_component on $_thisdate " >>"$CMDLOGFILE" -done - -cd "$curdir" || exit +build_components "$_components" diff --git a/bin/configs/aomp.cudf b/bin/configs/aomp.cudf new file mode 100644 index 0000000000..b96c6b7af3 --- /dev/null +++ b/bin/configs/aomp.cudf @@ -0,0 +1,251 @@ +# aomp.cudf - AOMP build component dependency description +# +# CUDF-style (Common Upgradeability Description Format) stanzas describing the +# AOMP build components, their dependencies, and the default requested build +# set. This file is consumed by bin/aomp_build.py to resolve a component set, +# topologically order it, and elaborate per-component build tasks. +# +# Format +# ------ +# * Stanzas are separated by one or more blank lines. +# * Within a stanza, each line is "key: value". +# * Lines beginning with '#' and blank lines are ignored. +# * Lists (depends, expands, install) are comma-separated and may wrap onto +# continuation lines (any line that does not contain a ':' before the first +# whitespace is treated as a continuation of the previous value). +# +# Stanza kinds +# ------------ +# package: a buildable component. Fields: +# package: component name (drives build_.sh) +# version: schema version of this stanza (currently always 1) +# depends: components that must be built first (optional) +# x-dir: bin subdirectory holding build_.sh; one of +# "." (default) or "rocmlibs". +# feature: a named alias expanding to a set of components. Fields: +# feature: feature/group name +# expands: comma-separated component names +# Used by aomp_build.py --add/--remove to toggle whole groups. +# request: the default requested build set. Field: +# install: comma-separated components built by default. +# +# Source of truth for the component list, ordering, and grouping is +# bin/build_aomp.sh (the standalone x86_64 build) and bin/rocmlibs/build_rocmlibs.sh. +# Dependencies are expressed as a DAG; aomp_build.py performs a deterministic +# topological sort that breaks ties using the package declaration order below, +# which reproduces the canonical build_aomp.sh ordering. + +#----------------------------------------------------------------------------- +# Core AOMP components (bin/build_.sh), in build_aomp.sh order. +#----------------------------------------------------------------------------- + +package: prereq +version: 1 +x-dir: . + +package: project +version: 1 +depends: prereq +x-dir: . + +package: rocprofiler-register +version: 1 +depends: project +x-dir: . + +package: rocr +version: 1 +depends: project +x-dir: . + +package: llvm_runtimes_standalone +version: 1 +depends: project, rocr +x-dir: . + +package: extras +version: 1 +depends: llvm_runtimes_standalone +x-dir: . + +package: comgr +version: 1 +depends: project, rocr +x-dir: . + +package: rocminfo +version: 1 +depends: rocr +x-dir: . + +package: rocm_smi_lib +version: 1 +depends: prereq +x-dir: . + +package: amdsmi +version: 1 +depends: prereq +x-dir: . + +package: llvm-classic +version: 1 +depends: project +x-dir: . + +package: flang-classic +version: 1 +depends: llvm-classic +x-dir: . + +package: pgmath +version: 1 +depends: flang-classic +x-dir: . + +package: flang +version: 1 +depends: pgmath +x-dir: . + +package: flang_runtime +version: 1 +depends: flang +x-dir: . + +package: hipcc +version: 1 +depends: llvm_runtimes_standalone +x-dir: . + +package: hipamd +version: 1 +depends: hipcc, comgr +x-dir: . + +package: hipify +version: 1 +depends: hipcc +x-dir: . + +package: hipfort +version: 1 +depends: hipamd, flang_runtime +x-dir: . + +package: rocdbgapi +version: 1 +depends: comgr +x-dir: . + +package: rocgdb +version: 1 +depends: rocdbgapi +x-dir: . + +package: rocprofiler-sdk +version: 1 +depends: hipamd, rocprofiler-register +x-dir: . + +#----------------------------------------------------------------------------- +# ROCm math/communication libraries (bin/rocmlibs/build_.sh), in +# build_rocmlibs.sh order. Not built by default; add with --add rocmlibs. +#----------------------------------------------------------------------------- + +package: rocm-cmake +version: 1 +depends: prereq +x-dir: . + +package: rocBLAS +version: 1 +depends: rocm-cmake, hipamd +x-dir: rocmlibs + +package: rocPRIM +version: 1 +depends: rocm-cmake, hipamd +x-dir: rocmlibs + +package: rocSPARSE +version: 1 +depends: rocBLAS, rocPRIM +x-dir: rocmlibs + +package: rocSOLVER +version: 1 +depends: rocBLAS, rocPRIM, rocSPARSE +x-dir: rocmlibs + +package: hipBLAS-common +version: 1 +depends: rocm-cmake +x-dir: rocmlibs + +package: hipBLAS +version: 1 +depends: rocBLAS, hipBLAS-common, rocSOLVER +x-dir: rocmlibs + +package: rocRAND +version: 1 +depends: rocm-cmake, hipamd +x-dir: rocmlibs + +package: hipRAND +version: 1 +depends: rocRAND +x-dir: rocmlibs + +package: rccl +version: 1 +depends: rocm-cmake, hipamd +x-dir: rocmlibs + +package: half +version: 1 +depends: rocm-cmake +x-dir: rocmlibs + +package: hipSOLVER +version: 1 +depends: rocSOLVER, hipBLAS +x-dir: rocmlibs + +#----------------------------------------------------------------------------- +# Feature aliases: named groups for --add / --remove. +#----------------------------------------------------------------------------- + +# Classic Flang and the LLVM it depends on (build_aomp.sh AOMP_SKIP_FLANG==0). +feature: flang +expands: llvm-classic, flang-classic, pgmath, flang, flang_runtime + +# HIP runtime/toolchain. +feature: hip +expands: hipcc, hipamd, hipify + +# Debugger components (build_aomp.sh AOMP_BUILD_DEBUG==1). +feature: debug +expands: rocdbgapi, rocgdb + +# Profiler components. +feature: profiler +expands: rocprofiler-register, rocprofiler-sdk + +# ROCm math/communication libraries. +feature: rocmlibs +expands: rocm-cmake, rocBLAS, rocPRIM, rocSPARSE, rocSOLVER, hipBLAS-common, + hipBLAS, rocRAND, hipRAND, rccl, half, hipSOLVER + +#----------------------------------------------------------------------------- +# Default requested build set: the standalone x86_64 AOMP build from +# build_aomp.sh (with classic Flang, without the optional debug/hipfort +# components and without rocmlibs). Modify with --add / --remove. +#----------------------------------------------------------------------------- + +request: +install: prereq, project, rocprofiler-register, rocr, llvm_runtimes_standalone, + extras, comgr, rocminfo, rocm_smi_lib, amdsmi, llvm-classic, + flang-classic, pgmath, flang, flang_runtime, hipcc, hipamd, hipify, + rocprofiler-sdk From 94d4ba6d3d921de53ab36e184099357917ab775b Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 04:56:58 -0500 Subject: [PATCH 52/71] Send flang-classic skip warning to stderr When the classic LLVM source is absent, build_llvm-classic.sh and build_flang-classic.sh print a skip warning. Route it to stderr so the taskified introspection commands (list, list_configs, ...) keep a clean stdout for the aomp_build.py orchestrator. --- bin/build_flang-classic.sh | 10 +++++++--- bin/build_llvm-classic.sh | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/bin/build_flang-classic.sh b/bin/build_flang-classic.sh index 68ff588189..fa8f3db030 100755 --- a/bin/build_flang-classic.sh +++ b/bin/build_flang-classic.sh @@ -49,9 +49,13 @@ AOMP_LFL_DIR=${AOMP_LFL_DIR:-"17.0-4"} # directly rather than through cfgbool. if [ "$AOMP_BUILD_FLANG_CLASSIC" == 0 ] ; then if [ "$1" != "install" ] ; then - echo "WARNING: ROCM install for $AOMP_FLANG_CLASSIC_REL/llvm-classic not found." - echo " This build will skip build of flang-classic." - echo " The flang will link to the clang driver." + # Warn on stderr so introspection commands (list, list_configs, ...) + # keep a clean stdout for the orchestrator. + { + echo "WARNING: ROCM install for $AOMP_FLANG_CLASSIC_REL/llvm-classic not found." + echo " This build will skip build of flang-classic." + echo " The flang will link to the clang driver." + } >&2 fi exit 0 fi diff --git a/bin/build_llvm-classic.sh b/bin/build_llvm-classic.sh index 330a02c568..cd38a30d2b 100755 --- a/bin/build_llvm-classic.sh +++ b/bin/build_llvm-classic.sh @@ -49,9 +49,13 @@ AOMP_LFL_DIR=${AOMP_LFL_DIR:-"17.0-4"} # directly rather than through cfgbool. if [ "$AOMP_BUILD_FLANG_CLASSIC" == 0 ] ; then if [ "$1" != "install" ] ; then - echo "WARNING: ROCM install for $AOMP_FLANG_CLASSIC_REL/llvm-classic not found." - echo " This build will skip build of flang-classic." - echo " The flang will link to the clang driver." + # Warn on stderr so introspection commands (list, list_configs, ...) + # keep a clean stdout for the orchestrator. + { + echo "WARNING: ROCM install for $AOMP_FLANG_CLASSIC_REL/llvm-classic not found." + echo " This build will skip build of flang-classic." + echo " The flang will link to the clang driver." + } >&2 fi exit 0 fi From 9da2b351407a176f8e5856a6d678ed203731b089 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 05:27:29 -0500 Subject: [PATCH 53/71] Document aomp_build.py; refine selectors, --add/--remove, defaults - Add bin/AOMP_BUILD.md documenting the orchestrator (user workflows and internals). - Make 'continue' a trailing selector keyword: the preceding selector becomes a "from there to the end" anchor (e.g. 'comp1 comp2 continue'). - Accept comma-separated lists for --add/--remove (in addition to repeating the flag). - Drop the deprecated classic Flang stack (llvm-classic, flang-classic, pgmath, flang, flang_runtime) from the default request; still available via --add flang. --- bin/AOMP_BUILD.md | 561 ++++++++++++++++++++++++++++++++++++++++++ bin/aomp_build.py | 121 +++++---- bin/configs/aomp.cudf | 9 +- 3 files changed, 642 insertions(+), 49 deletions(-) create mode 100644 bin/AOMP_BUILD.md diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md new file mode 100644 index 0000000000..e292a104ed --- /dev/null +++ b/bin/AOMP_BUILD.md @@ -0,0 +1,561 @@ +# `aomp_build.py` — AOMP build orchestrator + +`aomp_build.py` is a unified, introspectable driver for building AOMP. It pulls +the individual taskified component build scripts (`build_.sh`) into a +single workflow: it resolves which components to build from a config file, +orders them by their dependencies, breaks each component into fine-grained +tasks, and runs those tasks (all of them, a numbered range, a glob, or from a +chosen point onward) with per-task logging. + +It is the successor workflow to running `build_aomp.sh` directly: the same +components, the same order, but introspectable, incremental, and scriptable. + +- Orchestrator: [`bin/aomp_build.py`](aomp_build.py) +- Default config: [`bin/configs/aomp.cudf`](configs/aomp.cudf) +- Per-component scripts: `bin/build_.sh` and `bin/rocmlibs/build_.sh` + +--- + +## Table of contents + +- [Requirements](#requirements) +- [Quick start](#quick-start) +- [Concepts](#concepts) +- [Command-line reference](#command-line-reference) +- [Selectors](#selectors) +- [Build variants](#build-variants) +- [Components and features](#components-and-features) +- [The version manifest](#the-version-manifest) +- [Logs](#logs) +- [User workflows](#user-workflows) +- [Internals](#internals) + - [The taskified component interface](#the-taskified-component-interface) + - [The CUDF config format](#the-cudf-config-format) + - [Resolution pipeline](#resolution-pipeline) + - [Task elaboration](#task-elaboration) + - [Execution](#execution) + - [Environment discovery and child environment](#environment-discovery-and-child-environment) +- [Troubleshooting](#troubleshooting) +- [Extending](#extending) + +--- + +## Requirements + +- Python 3 (standard library only; no third-party packages). +- `bash` and the usual AOMP build prerequisites (the orchestrator simply + invokes the existing `build_.sh` scripts). +- A working AOMP environment as set up by `aomp_common_vars` (repos cloned + under `$AOMP_REPOS`, etc.). `aomp_build.py` itself only reads a few + variables (`BUILD_DIR`, `AOMP_REPOS`, `AOMP_REPO_NAME`); each build script + sources `aomp_common_vars` on its own. + +`aomp_build.py` does not need to be run from any particular directory — it +locates the build scripts relative to its own location in `bin/`. + +--- + +## Quick start + +```bash +cd $AOMP_REPOS/aomp/bin + +# See the components that would be built (resolved + dependency-ordered). +./aomp_build.py --components + +# See every task that would run, numbered. +./aomp_build.py list + +# Dry-run everything (prints commands + log paths, runs nothing). +./aomp_build.py -n + +# Build everything. +./aomp_build.py + +# Build just one component's tasks. +./aomp_build.py 'comgr/*' + +# Resume from a component after fixing a failure (trailing 'continue'). +./aomp_build.py comgr/cmake continue +``` + +--- + +## Concepts + +| Term | Meaning | +|------|---------| +| **Component** | A buildable unit with a `build_.sh` script (e.g. `project`, `comgr`, `flang`, `rocBLAS`). | +| **Feature** | A named alias expanding to a set of components (e.g. `flang`, `rocmlibs`), used by `--add`/`--remove`. | +| **Config / variant** | A build configuration a component advertises (e.g. `default`, `asan`, `perf`, `debug`, `*-devicertl`). | +| **Task** | A single step of a component build: `precheck`, `patch`, `clean`, `cmake`, `build`, `install`, `postinstall`, `unpatch`. | +| **Request** | The default set of components to build, declared in the config's `request:` stanza. | +| **Selector** | A positional argument that picks which elaborated tasks to run. | + +The pipeline, end to end: + +``` +parse argv ─▶ load CUDF config ─▶ expand features; apply --add/--remove + ─▶ dependency closure + topological sort + ─▶ elaborate tasks (query each build_.sh list, filter by variant) + ─▶ select tasks (selector grammar) + ─▶ list, or run with per-task logs +``` + +--- + +## Command-line reference + +``` +aomp_build.py [options] [selector ...] +``` + +### Actions / output + +| Option | Description | +|--------|-------------| +| `list` (selector) | Print the numbered task list and exit. | +| `--components` | Print the resolved, dependency-ordered component list and exit. | +| `-n`, `--dry-run` | Show what would run (command + log path per task) without executing. | +| `--export-manifest [FILE]` | Write a git fingerprint manifest and exit. Default path: `/manifests/-manifest.json`. | +| `--import-manifest FILE` | Check out recorded git SHAs before building (refuses if any repo is dirty). | + +### Component selection + +| Option | Description | +|--------|-------------| +| `-c`, `--config FILE` | CUDF config file. Default: `bin/configs/aomp.cudf`. | +| `--add NAMES` | Add component(s) or feature(s). Comma-separated and/or repeatable. | +| `--remove NAMES` | Remove component(s) or feature(s) (cascades to dependents). Comma-separated and/or repeatable. | +| `--variant SPEC` | Build variant: `cfg` (global) or `comp=cfg` (per-component). Repeatable. | +| `-C`, `--clean` | Include `clean` tasks (skipped by default for incremental builds). | + +### Build environment knobs (exported to child build scripts) + +| Option | Environment variable | Notes | +|--------|----------------------|-------| +| `-j`, `--jobs N` | `AOMP_JOB_THREADS` | Parallel build threads. | +| `--ninja` / `--no-ninja` | `AOMP_USE_NINJA=1` / `0` | Use the Ninja generator. | +| `--ccache` / `--no-ccache` | `AOMP_USE_CCACHE=1` / `0` | Use ccache. | +| `--gfx LIST` | `GFXLIST` | GPU target list. | +| `--build-type TYPE` | `BUILD_TYPE` | CMake build type. | +| `--sudo` | `SUDO=yes` | Install with sudo. | + +### Logging + +| Option | Description | +|--------|-------------| +| `--log-dir DIR` | Directory for per-task logs. Default: `/aomp_build_logs`. | + +Any variable not set via a flag is inherited from the environment, so you can +still drive the build the "classic" way (`AOMP_JOB_THREADS=32 ./aomp_build.py`). + +--- + +## Selectors + +Selectors are positional arguments that decide which of the elaborated tasks to +run. The grammar mirrors `amd-build`: + +| Selector | Meaning | +|----------|---------| +| *(none)* | Run all elaborated tasks. | +| `list` | Print the numbered task list and exit (does not run anything). | +| `N` | Run task number `N` (1-based, as shown by `list`). | +| `N--M` | Run the inclusive range of tasks `N` through `M`. | +| `comp/action` | Glob/substring match on task names; supports `{a,b}` brace expansion. | +| `... X continue` | Trailing `continue` turns the preceding selector `X` into a "from `X` to the end" anchor. Any earlier selectors are selected normally. | + +Multiple selectors can be combined; the union of matched tasks runs in task +order. Names take the form `component/action` (e.g. `comgr/cmake`, +`flang/build`). + +`continue` is a **trailing** keyword: it must be the last argument, and it +applies to the selector immediately before it. `X` may be a task number or a +task name; if it matches several tasks (e.g. a component name), continuation +starts from its first task. + +Examples: + +```bash +./aomp_build.py 5 # just task 5 +./aomp_build.py 5--12 # tasks 5 through 12 +./aomp_build.py 30 continue # from task 30 to the end +./aomp_build.py flang/cmake continue # from flang's cmake task onward +./aomp_build.py comgr continue # from comgr's first task to the end +./aomp_build.py project/build comgr continue # project's build, then comgr onward +./aomp_build.py 'comgr/*' # every comgr task +./aomp_build.py '*/install' # every install task +./aomp_build.py '{comgr,rocr}/build' # comgr build + rocr build +``` + +> Tip: quote selectors containing `*`, `?`, or `{}` so your shell doesn't try +> to expand them first. + +--- + +## Build variants + +Each component advertises one or more *configs* (variants) through its +`list_configs` command. There are two common styles: + +- **Style A** (most components): always offer a plain `default` plus opt-in + variants such as `asan` and `debug`. +- **Style B** (e.g. `llvm_runtimes_standalone`): derive their config set from + the environment (`AOMP_BUILD_SANITIZER`, `AOMP_BUILD_PERF`, + `AOMP_BUILD_DEBUG`) and have **no** plain `default`; the advertised set is + the normal build (e.g. `asan`, `perf`, `perf+asan`, `debug`, plus + `*-devicertl` device-runtime passes). + +Selection policy: + +- **No `--variant`:** build `default` if the component offers it; otherwise + build **every** advertised config (faithful to style B). +- **`--variant cfg` (global):** build config `cfg` for every component that + advertises it. Components that don't advertise `cfg` fall back to `default` + (or all advertised configs if they have no `default`). +- **`--variant comp=cfg` (per-component):** override the variant for `comp` + only. Repeatable to request multiple configs for one component + (`--variant llvm_runtimes_standalone=asan --variant llvm_runtimes_standalone=perf`). + +Examples: + +```bash +./aomp_build.py --variant asan list +./aomp_build.py --variant llvm_runtimes_standalone=perf list +``` + +--- + +## Components and features + +The default component set is the `request:` stanza of the config — the +standalone x86_64 AOMP build from `build_aomp.sh`, **omitting the deprecated +classic Flang stack** (`llvm-classic`, `flang-classic`, `pgmath`, `flang`, +`flang_runtime`) as well as the optional debug/hipfort components and the ROCm +math libraries. Re-enable classic Flang with `--add flang`. + +Adjust it with `--add` / `--remove`, which accept **component** names or +**feature** names. Each option is repeatable and also accepts a comma-separated +list, so `--add rocmlibs,debug` and `--add rocmlibs --add debug` are +equivalent. Features defined in the default config: + +| Feature | Expands to | +|---------|-----------| +| `flang` | `llvm-classic`, `flang-classic`, `pgmath`, `flang`, `flang_runtime` (deprecated classic Flang; not in the default set) | +| `hip` | `hipcc`, `hipamd`, `hipify` | +| `debug` | `rocdbgapi`, `rocgdb` | +| `profiler` | `rocprofiler-register`, `rocprofiler-sdk` | +| `rocmlibs` | `rocm-cmake`, `rocBLAS`, `rocPRIM`, `rocSPARSE`, `rocSOLVER`, `hipBLAS-common`, `hipBLAS`, `rocRAND`, `hipRAND`, `rccl`, `half`, `hipSOLVER` | + +Resolution rules: + +- `--add` pulls in the named component(s)/feature(s) **and their transitive + dependencies**. +- `--remove` drops the named component(s)/feature(s) **and anything that + depends on them** (the removal cascades). + +```bash +./aomp_build.py --add rocmlibs --components # core AOMP + ROCm libraries +./aomp_build.py --remove flang --components # drop the whole Flang group +./aomp_build.py --add rocgdb --components # adds rocdbgapi too (dependency) +./aomp_build.py --add rocmlibs,debug --components # comma-separated list +``` + +--- + +## The version manifest + +The manifest captures the exact git state of every component's source repo, so +a build can be reproduced later. + +Export: + +```bash +./aomp_build.py --export-manifest # default path +./aomp_build.py --add rocmlibs --export-manifest m.json # explicit path + set +``` + +The JSON records, per component that has a git source: + +```json +{ + "generated": "2026-06-17T10:00:00", + "config": "aomp", + "order": ["prereq", "project", "..."], + "components": { + "project": { + "sha": "…", + "repo": "https://github.com/…", + "branch": "amd-staging", + "dirty": false + } + } +} +``` + +Import (a pre-step before building): + +```bash +./aomp_build.py --import-manifest m.json [selectors...] +``` + +- For each component in the manifest that is also in the resolved set, the + recorded SHA is checked out (`git checkout `). +- **Safety:** if any target repo has local modifications, the import is + **refused** entirely (nothing is checked out) and the dirty repos are listed. +- Components without a git source (e.g. `prereq`) are skipped. + +Manifests live under `/manifests/` by default +(`BUILD_DIR` = `$BUILD_AOMP`, normally `$AOMP_REPOS`). + +--- + +## Logs + +Each executed task writes a numbered log: + +``` +/NNN-component-action.log +``` + +where `NNN` is the global task number (matching `list`) and `` +defaults to `/aomp_build_logs`. Each log begins with the task +number, the exact command, and a start timestamp, and ends with an end +timestamp and the return code. + +On failure, the orchestrator prints the failing task and tails the log to +stderr, then stops (non-zero exit). Re-run with ` continue` after +fixing the problem. + +--- + +## User workflows + +### Full build from scratch + +```bash +cd $AOMP_REPOS/aomp/bin +./aomp_build.py # builds the default component set in order +``` + +### Inspect before building + +```bash +./aomp_build.py --components # which components, in what order +./aomp_build.py list # every task, numbered +./aomp_build.py -n # full dry-run (commands + log paths) +``` + +### Rebuild a single component + +```bash +./aomp_build.py 'comgr/*' # all comgr tasks (incremental: no clean) +./aomp_build.py -C 'comgr/*' # force a clean rebuild of comgr +./aomp_build.py comgr/build # just re-run comgr's build step +``` + +### Resume after a failure + +A task fails; its log is tailed to your terminal. Fix the issue, then resume +with a trailing `continue`: + +```bash +./aomp_build.py comgr/cmake continue # re-run from comgr's cmake onward +# or by number, using the value shown in `list`: +./aomp_build.py 30 continue +``` + +### Build extra component sets + +```bash +./aomp_build.py --add rocmlibs # core AOMP + ROCm math libs +./aomp_build.py --add rocmlibs 'rocBLAS/*' # only rocBLAS tasks (deps still resolved) +./aomp_build.py --add debug # add rocdbgapi + rocgdb +``` + +### Build a sanitizer / perf / debug variant + +```bash +./aomp_build.py --variant asan # asan everywhere it's offered +./aomp_build.py --variant llvm_runtimes_standalone=debug +``` + +### Tune the build environment + +```bash +./aomp_build.py -j 32 --ninja --ccache # threads + ninja + ccache +./aomp_build.py --gfx "gfx90a;gfx942" # specific GPU targets +``` + +### Reproduce an earlier build + +```bash +# On the reference machine: +./aomp_build.py --export-manifest good.json +# Later / elsewhere (repos must be clean): +./aomp_build.py --import-manifest good.json +``` + +--- + +## Internals + +### The taskified component interface + +Every component script (`build_.sh`) speaks a common interface provided +by `command_dispatcher` in [`bin/aomp_utils`](aomp_utils). The orchestrator +relies on exactly these commands: + +| Command | Purpose | +|---------|---------| +| `list_configs` | Print the configs/variants this component offers, one per line. | +| `list` | Print every task as `task_ [cfg]`, one per line (init tasks, then per-config tasks, then fini tasks). | +| `task_ [cfg]` | Run a single task for a given config. | +| `show_src_dir` | Print the component's git source directory (for the manifest). | +| `show_build_dir ` / `show_install_dir ` | Print build/install directories (informational). | + +Because `list` emits each line already in `task_ [cfg]` form, the +orchestrator can pass a line straight back to the script to execute it. + +`build_supp.sh` (and its `build_prereq.sh` symlink) is modeled as a single +coarse component: one `default` config, a `task_build` that runs the existing +"build all prerequisite/supplemental components" logic, and a no-op +`task_install`. It still supports its legacy direct invocation +(`build_supp.sh openmpi`, no-arg, `install`, `-h`). + +### The CUDF config format + +The config (default [`bin/configs/aomp.cudf`](configs/aomp.cudf)) is a +CUDF-style (Common Upgradeability Description Format) text file. Stanzas are +separated by blank lines; `#` lines are comments. Within a stanza each line is +`key: value`; a line whose first token has no `:` is treated as a continuation +of the previous value (used to wrap long comma-separated lists). + +Three stanza kinds: + +``` +package: comgr # a buildable component +version: 1 # stanza schema version (always 1) +depends: project, rocr # components that must build first (a DAG) +x-dir: . # bin subdir with build_.sh: "." or "rocmlibs" + +feature: flang # a named alias for a set of components +expands: llvm-classic, flang-classic, pgmath, flang, flang_runtime + +request: # the default requested build set +install: prereq, project, ... +``` + +The package list, ordering, and grouping are derived from +[`bin/build_aomp.sh`](build_aomp.sh) (standalone x86_64 build) and +[`bin/rocmlibs/build_rocmlibs.sh`](rocmlibs/build_rocmlibs.sh). Dependencies are +expressed as a DAG; packages are declared in canonical build order so the +topological sort reproduces that order (see below). + +The parser is intentionally simple and lives entirely in `parse_cudf()`. It +leaves room for a future external version *solver* (the "CUDF" framing): today +the `request:` set plus `--add`/`--remove` is resolved directly, but the same +config could later feed a real dependency/version solver. + +### Resolution pipeline + +`resolve_components()` turns the config + `--add`/`--remove` into an ordered +component list: + +1. Start from `request.install`. +2. `requested |= expand(--add)` and `removed = expand(--remove)`; features are + expanded to their component sets via `expand_names()`. +3. `requested -= removed`; unknown names are rejected. +4. **Transitive closure with removal cascade** (fixed-point loop): for each + component, pull in its `depends`; if a dependency is in the removed set, + drop the dependent (and add it to the removed set so its own dependents + cascade too). This is why `--remove comgr` also drops `hipamd`, + `rocdbgapi`, etc. +5. **Topological sort** (`topo_sort()`): a deterministic Kahn's algorithm where + ready nodes are always taken in *declaration order*. Because packages are + declared in canonical `build_aomp.sh` order, the result reproduces that + canonical order while still honoring real dependency edges. A cycle is a + hard error. + +### Task elaboration + +`elaborate_tasks()` expands the ordered component list into a flat task list: + +1. For each component, locate its script via `script_path()` (honoring + `x-dir`). +2. Query `list_configs`; pick the configs to build via `select_variants()` + (see [Build variants](#build-variants)). +3. Query `list`; parse each `task_ [cfg]` line. +4. Keep a task if either it has no config (init/fini tasks such as `precheck`, + `patch`, `unpatch` always run) or its config is in the selected set. +5. Drop `clean` tasks unless `-C/--clean` was given (incremental by default). + +Each surviving task is recorded as a `Task` (component, action, config, script +path, and the exact `script_args` to pass back). Its display name is +`component/action`. + +### Execution + +`select_tasks()` applies the selector grammar to produce a list of task +indices; `run_tasks()` runs them: + +- Creates the log directory. +- For each task, opens `NNN-component-action.log`, writes a header + (number, command, start time), runs `bash build_.sh task_ + [cfg]` with stdout+stderr redirected to the log, and writes a footer (end + time, return code). +- On a non-zero return code, prints the failure and tails the log to stderr, + then returns that code (stops the run). +- `--dry-run` prints the planned command and log path instead of executing. + +### Environment discovery and child environment + +- `discover_env()` sources `aomp_utils` + `aomp_common_vars` in a subshell and + reads back `BUILD_DIR`, `AOMP_REPOS`, and `AOMP_REPO_NAME` — used only to + locate the default log and manifest directories. +- `build_child_env()` starts from the current environment and overlays the + values implied by the build-knob flags (`-j`, `--ninja`, `--ccache`, + `--gfx`, `--build-type`, `--sudo`). This same environment is used for every + child script invocation (introspection, execution, and git/manifest probes), + so introspection sees the same configs that will actually be built. + +--- + +## Troubleshooting + +**A component shows no tasks in `list`.** +Its `list` produced no `task_*` lines — usually the component self-disables in +the current environment (e.g. `llvm-classic`/`flang-classic` when the classic +LLVM source is absent). Such components emit a warning on **stderr** and exit +cleanly, so they simply contribute nothing. Confirm by running the script +directly: `bash build_.sh list`. + +**`unknown component(s): …`.** +A name passed to `--add`/`--remove` (or in the config's `request:`) is neither +a package nor a feature. Check spelling against `--components` and the config. + +**`dependency cycle among: …`.** +The `depends:` edges in the config form a cycle. Fix the config. + +**Import refuses with "local modifications".** +A target repo is dirty. Commit/stash/clean it, or drop it from the resolved set +(`--remove`), then retry the import. + +**A task fails.** +Read the tailed log (path printed on failure, under the log dir). After fixing, +resume with ` continue`. + +--- + +## Extending + +- **Add a component:** create `build_.sh` implementing the + [task interface](#the-taskified-component-interface), then add a `package:` + stanza (with `depends:` and `x-dir:`) to the config. Declare it in canonical + build position so the topological sort places it correctly. +- **Add a feature:** add a `feature:` stanza with an `expands:` list. +- **Change the default set:** edit the `request:` stanza, or keep the config + fixed and use `--add`/`--remove` at the command line. +- **Use a different config:** `-c /path/to/other.cudf`. The manifest's default + filename follows the config's basename. diff --git a/bin/aomp_build.py b/bin/aomp_build.py index 30c28dd173..1020140639 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -125,13 +125,21 @@ def flush(stanza: dict[str, str]) -> None: # Feature expansion + dependency resolution # --------------------------------------------------------------------------- # def expand_names(names: list[str], cfg: Config) -> set[str]: - """Expand a list of component/feature names into a set of components.""" + """Expand component/feature names into a set of components. + + Each entry may itself be a comma-separated list (so `--add a,b` and + `--add a --add b` are equivalent), and any entry naming a feature is + expanded to that feature's components. + """ result: set[str] = set() - for name in names: - if name in cfg.features: - result.update(cfg.features[name]) - else: - result.add(name) + for entry in names: + for name in (n.strip() for n in entry.split(",")): + if not name: + continue + if name in cfg.features: + result.update(cfg.features[name]) + else: + result.add(name) return result @@ -364,24 +372,66 @@ def brace_expand(token: str) -> list[str]: def select_tasks(tasks: list[Task], selectors: list[str]) -> list[int]: """Return the indices (into tasks) selected by the positional selectors. - Grammar (mirrors amd-build): + Grammar (mirrors amd-build, with a trailing `continue`): * no selectors -> all tasks * N -> task number N (1-based) * N--M -> inclusive range - * continue [N|name] -> from the given task to the end * glob (with {a,b} braces)-> substring/glob match on "comp/action" + * ... X continue -> trailing `continue` turns the preceding + selector X into a "from X to the end" anchor; + any earlier selectors are selected normally. + e.g. `comp1 comp2 continue` runs comp1's + tasks then everything from comp2 onward. """ if not selectors: return list(range(len(tasks))) names = [t.name for t in tasks] + selectors = list(selectors) + + # `continue` is a trailing modifier: it must be the final token and turns + # the selector immediately before it into a continue-to-the-end anchor. + continue_from_last = False + if selectors and selectors[-1] == "continue": + selectors.pop() + if not selectors: + sys.exit( + "aomp_build: trailing 'continue' requires a preceding task " + "number or name (e.g. 'comp2 continue')" + ) + continue_from_last = True + if "continue" in selectors: + sys.exit( + "aomp_build: 'continue' must be the last selector " + "(e.g. 'comp1 comp2 continue' builds comp1 then continues from comp2)" + ) + selected: list[int] = [] def add(idx: int) -> None: if 0 <= idx < len(tasks) and idx not in selected: selected.append(idx) - def resolve_point(token: str) -> int: + def match_indices(sel: str) -> list[int]: + """Indices matched by a single (non-continue) selector.""" + if sel.isdigit(): + return [int(sel) - 1] + if "--" in sel: + lo_s, hi_s = sel.split("--", 1) + lo, hi = match_point(lo_s), match_point(hi_s) + if lo > hi: + lo, hi = hi, lo + return list(range(lo, hi + 1)) + out: list[int] = [] + for pat in brace_expand(sel): + for idx, nm in enumerate(names): + if fnmatch.fnmatch(nm, pat) or pat == nm or pat in nm: + out.append(idx) + if not out: + sys.exit(f"aomp_build: selector '{sel}' matched no task") + return out + + def match_point(token: str) -> int: if token.isdigit(): return int(token) - 1 for i, nm in enumerate(names): @@ -389,40 +439,16 @@ def resolve_point(token: str) -> int: return i sys.exit(f"aomp_build: selector '{token}' matched no task") - i = 0 - while i < len(selectors): - sel = selectors[i] - if sel == "continue": - if i + 1 >= len(selectors): - sys.exit("aomp_build: 'continue' requires a task number or name") - start = resolve_point(selectors[i + 1]) + last = len(selectors) - 1 + for i, sel in enumerate(selectors): + if continue_from_last and i == last: + # Anchor: from this selector's first matched task to the end. + start = min(match_indices(sel)) for idx in range(start, len(tasks)): add(idx) - i += 2 - continue - if "--" in sel: - lo_s, hi_s = sel.split("--", 1) - lo, hi = resolve_point(lo_s), resolve_point(hi_s) - if lo > hi: - lo, hi = hi, lo - for idx in range(lo, hi + 1): + else: + for idx in match_indices(sel): add(idx) - i += 1 - continue - if sel.isdigit(): - add(int(sel) - 1) - i += 1 - continue - # Glob / substring match (with brace expansion). - matched = False - for pat in brace_expand(sel): - for idx, nm in enumerate(names): - if fnmatch.fnmatch(nm, pat) or pat == nm or pat in nm: - add(idx) - matched = True - if not matched: - sys.exit(f"aomp_build: selector '{sel}' matched no task") - i += 1 selected.sort() return selected @@ -629,17 +655,22 @@ def build_arg_parser() -> argparse.ArgumentParser: " list print the numbered task list and exit\n" " N run task number N (1-based)\n" " N--M run the inclusive range of tasks N..M\n" - " continue X run from task X (number or name) to the end\n" " comp/action glob/substring match (supports {a,b} braces)\n" + " ... X continue trailing 'continue' makes the preceding selector\n" + " X a 'from X to the end' anchor, e.g.\n" + " 'comp1 comp2 continue' builds comp1 then continues\n" + " from comp2 onward\n" ), ) parser.add_argument("selectors", nargs="*", help="task selector(s); see below") parser.add_argument("-c", "--config", default=DEFAULT_CONFIG, help=f"CUDF config file (default: {DEFAULT_CONFIG})") - parser.add_argument("--add", action="append", default=[], metavar="NAME", - help="add a component or feature (repeatable)") - parser.add_argument("--remove", action="append", default=[], metavar="NAME", - help="remove a component or feature (repeatable)") + parser.add_argument("--add", action="append", default=[], metavar="NAMES", + help="add component(s)/feature(s); comma-separated and/or " + "repeatable") + parser.add_argument("--remove", action="append", default=[], metavar="NAMES", + help="remove component(s)/feature(s); comma-separated " + "and/or repeatable") parser.add_argument("--variant", action="append", default=[], metavar="SPEC", help="build variant: 'cfg' (global) or 'comp=cfg' " "(per-component); repeatable") diff --git a/bin/configs/aomp.cudf b/bin/configs/aomp.cudf index b96c6b7af3..354d10cdf2 100644 --- a/bin/configs/aomp.cudf +++ b/bin/configs/aomp.cudf @@ -218,6 +218,7 @@ x-dir: rocmlibs #----------------------------------------------------------------------------- # Classic Flang and the LLVM it depends on (build_aomp.sh AOMP_SKIP_FLANG==0). +# Deprecated and omitted from the default request; re-enable with --add flang. feature: flang expands: llvm-classic, flang-classic, pgmath, flang, flang_runtime @@ -240,12 +241,12 @@ expands: rocm-cmake, rocBLAS, rocPRIM, rocSPARSE, rocSOLVER, hipBLAS-common, #----------------------------------------------------------------------------- # Default requested build set: the standalone x86_64 AOMP build from -# build_aomp.sh (with classic Flang, without the optional debug/hipfort -# components and without rocmlibs). Modify with --add / --remove. +# build_aomp.sh, omitting the deprecated classic Flang stack (llvm-classic, +# flang-classic, pgmath, flang, flang_runtime; re-add with --add flang) and the +# optional debug/hipfort components and rocmlibs. Modify with --add / --remove. #----------------------------------------------------------------------------- request: install: prereq, project, rocprofiler-register, rocr, llvm_runtimes_standalone, - extras, comgr, rocminfo, rocm_smi_lib, amdsmi, llvm-classic, - flang-classic, pgmath, flang, flang_runtime, hipcc, hipamd, hipify, + extras, comgr, rocminfo, rocm_smi_lib, amdsmi, hipcc, hipamd, hipify, rocprofiler-sdk From c992eafbe22790653d839de8d4165ee722a4c821 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 05:46:13 -0500 Subject: [PATCH 54/71] Make --variant a strict filter; support comma lists - --variant now strictly filters configs: a component builds only the requested variants it advertises, and is skipped entirely (no init/fini tasks) when none match. So '--variant default' builds each component's default and skips llvm_runtimes_standalone (its default libs come from the project build). - Accept comma-separated variant lists, e.g. '--variant debug,asan' and '--variant comp1=debug,comp2=asan'. - Update --help text and AOMP_BUILD.md accordingly. --- bin/AOMP_BUILD.md | 68 ++++++++++++++++++++++++++++-------------- bin/aomp_build.py | 76 ++++++++++++++++++++++++++++++----------------- 2 files changed, 94 insertions(+), 50 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index e292a104ed..3c1d796865 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -76,7 +76,7 @@ cd $AOMP_REPOS/aomp/bin ./aomp_build.py 'comgr/*' # Resume from a component after fixing a failure (trailing 'continue'). -./aomp_build.py comgr/cmake continue +./aomp_build.py comgr/default/cmake continue ``` --- @@ -127,7 +127,7 @@ aomp_build.py [options] [selector ...] | `-c`, `--config FILE` | CUDF config file. Default: `bin/configs/aomp.cudf`. | | `--add NAMES` | Add component(s) or feature(s). Comma-separated and/or repeatable. | | `--remove NAMES` | Remove component(s) or feature(s) (cascades to dependents). Comma-separated and/or repeatable. | -| `--variant SPEC` | Build variant: `cfg` (global) or `comp=cfg` (per-component). Repeatable. | +| `--variant SPEC` | Strict variant filter: `cfg` (global) or `comp=cfg` (per-component). Comma-separated and/or repeatable. Components with no matching config are skipped (so `--variant default` skips the runtimes). See [Build variants](#build-variants). | | `-C`, `--clean` | Include `clean` tasks (skipped by default for incremental builds). | ### Build environment knobs (exported to child build scripts) @@ -163,12 +163,15 @@ run. The grammar mirrors `amd-build`: | `list` | Print the numbered task list and exit (does not run anything). | | `N` | Run task number `N` (1-based, as shown by `list`). | | `N--M` | Run the inclusive range of tasks `N` through `M`. | -| `comp/action` | Glob/substring match on task names; supports `{a,b}` brace expansion. | +| `comp/variant/stage` | Glob/substring match on task names; supports `{a,b}` brace expansion. | | `... X continue` | Trailing `continue` turns the preceding selector `X` into a "from `X` to the end" anchor. Any earlier selectors are selected normally. | Multiple selectors can be combined; the union of matched tasks runs in task -order. Names take the form `component/action` (e.g. `comgr/cmake`, -`flang/build`). +order. Task names take the form `component/variant/stage` for build tasks +(e.g. `comgr/default/cmake`, `llvm_runtimes_standalone/asan/build`) and +`component/stage` for the config-less init/fini tasks (`precheck`, `patch`, +`unpatch` — e.g. `comgr/patch`). Putting the variant in the middle makes it +easy to glob a whole variant across components, e.g. `*/asan/*`. `continue` is a **trailing** keyword: it must be the last argument, and it applies to the selector immediately before it. `X` may be a task number or a @@ -181,12 +184,13 @@ Examples: ./aomp_build.py 5 # just task 5 ./aomp_build.py 5--12 # tasks 5 through 12 ./aomp_build.py 30 continue # from task 30 to the end -./aomp_build.py flang/cmake continue # from flang's cmake task onward +./aomp_build.py rocr/default/cmake continue # from rocr's cmake task onward ./aomp_build.py comgr continue # from comgr's first task to the end -./aomp_build.py project/build comgr continue # project's build, then comgr onward +./aomp_build.py project/default/build comgr continue # project's build, then comgr onward ./aomp_build.py 'comgr/*' # every comgr task -./aomp_build.py '*/install' # every install task -./aomp_build.py '{comgr,rocr}/build' # comgr build + rocr build +./aomp_build.py '*/install' # every install task (any component/variant) +./aomp_build.py '*/asan/*' # every asan-variant task +./aomp_build.py '{comgr,rocr}/*/build' # comgr build + rocr build ``` > Tip: quote selectors containing `*`, `?`, or `{}` so your shell doesn't try @@ -210,19 +214,36 @@ Each component advertises one or more *configs* (variants) through its Selection policy: - **No `--variant`:** build `default` if the component offers it; otherwise - build **every** advertised config (faithful to style B). -- **`--variant cfg` (global):** build config `cfg` for every component that - advertises it. Components that don't advertise `cfg` fall back to `default` - (or all advertised configs if they have no `default`). -- **`--variant comp=cfg` (per-component):** override the variant for `comp` - only. Repeatable to request multiple configs for one component - (`--variant llvm_runtimes_standalone=asan --variant llvm_runtimes_standalone=perf`). + build **every** advertised config (faithful to style B — this is the normal + full build, including the runtimes matrix). +- **`--variant` (any explicit value):** a **strict filter**. Each component + builds only the requested configs it advertises (in the requested order). A + component with **no** matching config is **skipped entirely** (no tasks, not + even `precheck`/`patch`). In particular, `--variant default` builds just the + `default` config of each component and therefore **skips + `llvm_runtimes_standalone`** (its default runtime libraries are produced by + the `project`/LLVM build itself). + +Forms (all combinable, comma-separated and/or repeated): + +| Form | Meaning | +|------|---------| +| `--variant cfg` | Apply `cfg` globally (every component that advertises it). | +| `--variant cfg1,cfg2` | Multiple global variants (e.g. `debug,asan`). | +| `--variant comp=cfg` | Override one component only. | +| `--variant comp1=cfg1,comp2=cfg2` | Per-component overrides in one value. | + +When only per-component overrides are given (no global value), components not +named build their normal default. Examples: ```bash +./aomp_build.py --variant default # default everywhere; skips the runtimes +./aomp_build.py --variant debug,asan # only debug + asan library variants ./aomp_build.py --variant asan list ./aomp_build.py --variant llvm_runtimes_standalone=perf list +./aomp_build.py --variant rocr=debug,llvm_runtimes_standalone=asan ``` --- @@ -316,9 +337,11 @@ Manifests live under `/manifests/` by default Each executed task writes a numbered log: ``` -/NNN-component-action.log +/NNN-component-variant-stage.log ``` +(config-less init/fini tasks are `NNN-component-stage.log`.) + where `NNN` is the global task number (matching `list`) and `` defaults to `/aomp_build_logs`. Each log begins with the task number, the exact command, and a start timestamp, and ends with an end @@ -352,7 +375,7 @@ cd $AOMP_REPOS/aomp/bin ```bash ./aomp_build.py 'comgr/*' # all comgr tasks (incremental: no clean) ./aomp_build.py -C 'comgr/*' # force a clean rebuild of comgr -./aomp_build.py comgr/build # just re-run comgr's build step +./aomp_build.py comgr/default/build # just re-run comgr's build step ``` ### Resume after a failure @@ -361,7 +384,7 @@ A task fails; its log is tailed to your terminal. Fix the issue, then resume with a trailing `continue`: ```bash -./aomp_build.py comgr/cmake continue # re-run from comgr's cmake onward +./aomp_build.py comgr/default/cmake continue # re-run from comgr's cmake onward # or by number, using the value shown in `list`: ./aomp_build.py 30 continue ``` @@ -485,7 +508,8 @@ component list: 1. For each component, locate its script via `script_path()` (honoring `x-dir`). 2. Query `list_configs`; pick the configs to build via `select_variants()` - (see [Build variants](#build-variants)). + (see [Build variants](#build-variants)). If an explicit `--variant` filter + matches none of the component's configs, the component is skipped entirely. 3. Query `list`; parse each `task_ [cfg]` line. 4. Keep a task if either it has no config (init/fini tasks such as `precheck`, `patch`, `unpatch` always run) or its config is in the selected set. @@ -493,7 +517,7 @@ component list: Each surviving task is recorded as a `Task` (component, action, config, script path, and the exact `script_args` to pass back). Its display name is -`component/action`. +`component/variant/stage` (or `component/stage` when the task has no config). ### Execution @@ -501,7 +525,7 @@ path, and the exact `script_args` to pass back). Its display name is indices; `run_tasks()` runs them: - Creates the log directory. -- For each task, opens `NNN-component-action.log`, writes a header +- For each task, opens `NNN-component-variant-stage.log`, writes a header (number, command, start time), runs `bash build_.sh task_ [cfg]` with stdout+stderr redirected to the log, and writes a footer (end time, return code). diff --git a/bin/aomp_build.py b/bin/aomp_build.py index 1020140639..f05b6a40e1 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -269,6 +269,10 @@ class Task: @property def name(self) -> str: + # "component/variant/stage" for config-bearing tasks; config-less + # init/fini tasks (precheck/patch/unpatch) are "component/stage". + if self.cfgname: + return f"{self.comp}/{self.cfgname}/{self.action}" return f"{self.comp}/{self.action}" @@ -286,9 +290,17 @@ def select_variants( Components advertise their configs via `list_configs`. Two styles exist: style-A always offers a plain "default" plus opt-in variants (asan/debug); style-B (e.g. the runtimes) derives its config set from the environment and - has no "default". So with no explicit --variant we build "default" when it - is offered, otherwise every advertised config (the intended normal build - for style-B). An explicit --variant is intersected with the advertised set. + has no "default" because its default build is produced by the compiler + (project) build itself. + + Selection: + * No explicit --variant: build "default" when offered, otherwise every + advertised config (the intended normal build for style-B). + * Explicit --variant (global and/or per-component): a strict filter - + build only the requested configs the component advertises, in the + requested order. A component with no matching config yields an empty + list and is skipped entirely. So `--variant default` builds just the + default config and skips components that have none (e.g. the runtimes). """ if comp in per_comp: wanted = per_comp[comp] @@ -302,14 +314,7 @@ def select_variants( return ["default"] return list(available) - chosen = [v for v in wanted if v in available] - if chosen: - return chosen - # Explicit variant request didn't match this component: fall back to a - # plain default if it has one, else all advertised configs. - if "default" in available: - return ["default"] - return list(available) + return [v for v in wanted if v in available] def elaborate_tasks( @@ -326,6 +331,10 @@ def elaborate_tasks( wanted = select_variants( comp, available, global_variants, per_comp_variants ) + # An explicit --variant filter that matches none of this component's + # configs skips the component outright (no init/fini tasks either). + if available and not wanted: + continue listing = run_script_capture(script, ["list"], env).splitlines() for line in listing: toks = line.split() @@ -376,7 +385,8 @@ def select_tasks(tasks: list[Task], selectors: list[str]) -> list[int]: * no selectors -> all tasks * N -> task number N (1-based) * N--M -> inclusive range - * glob (with {a,b} braces)-> substring/glob match on "comp/action" + * glob (with {a,b} braces)-> substring/glob match on + "comp/variant/stage" (or "comp/stage") * ... X continue -> trailing `continue` turns the preceding selector X into a "from X to the end" anchor; any earlier selectors are selected normally. @@ -478,10 +488,7 @@ def run_tasks( safe = task.name.replace("/", "-") log_path = os.path.join(log_dir, f"{num:03d}-{safe}.log") cmd = ["bash", task.script, *task.script_args] - header = ( - f"[{count}/{total}] task {num}: {task.name}" - f"{(' (' + task.cfgname + ')') if task.cfgname else ''}" - ) + header = f"[{count}/{total}] task {num}: {task.name}" if dry_run: print(f"{header}\n {' '.join(cmd)} > {log_path}") continue @@ -606,17 +613,27 @@ def import_manifest( def parse_variant_specs(specs: list[str]) -> tuple[list[str], dict[str, list[str]]]: """Split --variant values into global variants and per-component overrides. - A bare value (e.g. "asan") applies globally; "comp=cfg" overrides one - component. Repeatable; "comp=cfg" accumulates multiple configs per comp. + Each --variant value may be a comma-separated list, and the option is + repeatable, so these are all equivalent ways to ask for two variants: + --variant debug,asan + --variant debug --variant asan + An entry of the form "comp=cfg" overrides a single component; bare entries + apply globally. Both forms can be mixed in one comma-separated value, e.g. + --variant comp1=debug,comp2=asan + Multiple "comp=cfg" entries for the same component accumulate. """ global_variants: list[str] = [] per_comp: dict[str, list[str]] = {} for spec in specs: - if "=" in spec: - comp, _, val = spec.partition("=") - per_comp.setdefault(comp.strip(), []).append(val.strip()) - else: - global_variants.append(spec.strip()) + for entry in spec.split(","): + entry = entry.strip() + if not entry: + continue + if "=" in entry: + comp, _, val = entry.partition("=") + per_comp.setdefault(comp.strip(), []).append(val.strip()) + else: + global_variants.append(entry) return global_variants, per_comp @@ -655,7 +672,8 @@ def build_arg_parser() -> argparse.ArgumentParser: " list print the numbered task list and exit\n" " N run task number N (1-based)\n" " N--M run the inclusive range of tasks N..M\n" - " comp/action glob/substring match (supports {a,b} braces)\n" + " comp/variant/stage glob/substring match (supports {a,b} braces);\n" + " config-less init/fini tasks are comp/stage\n" " ... X continue trailing 'continue' makes the preceding selector\n" " X a 'from X to the end' anchor, e.g.\n" " 'comp1 comp2 continue' builds comp1 then continues\n" @@ -672,8 +690,11 @@ def build_arg_parser() -> argparse.ArgumentParser: help="remove component(s)/feature(s); comma-separated " "and/or repeatable") parser.add_argument("--variant", action="append", default=[], metavar="SPEC", - help="build variant: 'cfg' (global) or 'comp=cfg' " - "(per-component); repeatable") + help="strict variant filter: 'cfg' (global) or " + "'comp=cfg' (per-component). Comma-separated and/or " + "repeatable (e.g. 'debug,asan'). Components with no " + "matching config are skipped; 'default' thus skips " + "the runtimes build.") parser.add_argument("-C", "--clean", action="store_true", help="include 'clean' tasks (default: skip for " "incremental builds)") @@ -753,8 +774,7 @@ def main(argv: list[str]) -> int: if args.selectors and args.selectors[0] == "list": width = len(str(len(tasks))) for i, task in enumerate(tasks, start=1): - cfgstr = f" [{task.cfgname}]" if task.cfgname else "" - print(f"{i:>{width}} {task.name}{cfgstr}") + print(f"{i:>{width}} {task.name}") return 0 indices = select_tasks(tasks, args.selectors) From 622086bd68de1caa329b979d61679f59271de9c3 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 05:56:14 -0500 Subject: [PATCH 55/71] Always include default variant; build all variants by default - With no --variant, build every advertised config per component (default plus all variants like asan/debug/perf), not just default. - With --variant, always include the 'default' baseline where offered, so '--variant debug' means default+debug: default-only components still build, components offering the variant add it, and components without a default (the runtimes) build just the requested variant. Components offering neither default nor any requested variant are still skipped (so '--variant default' skips the runtimes). - Update --help and AOMP_BUILD.md. --- bin/AOMP_BUILD.md | 39 ++++++++++++++++++++-------------- bin/aomp_build.py | 54 +++++++++++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index 3c1d796865..f2eb52227f 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -127,7 +127,7 @@ aomp_build.py [options] [selector ...] | `-c`, `--config FILE` | CUDF config file. Default: `bin/configs/aomp.cudf`. | | `--add NAMES` | Add component(s) or feature(s). Comma-separated and/or repeatable. | | `--remove NAMES` | Remove component(s) or feature(s) (cascades to dependents). Comma-separated and/or repeatable. | -| `--variant SPEC` | Strict variant filter: `cfg` (global) or `comp=cfg` (per-component). Comma-separated and/or repeatable. Components with no matching config are skipped (so `--variant default` skips the runtimes). See [Build variants](#build-variants). | +| `--variant SPEC` | Variant filter: `cfg` (global) or `comp=cfg` (per-component). Comma-separated and/or repeatable. `default` is always built when offered (so `--variant debug` = default+debug); components offering neither are skipped (so `--variant default` skips the runtimes). See [Build variants](#build-variants). | | `-C`, `--clean` | Include `clean` tasks (skipped by default for incremental builds). | ### Build environment knobs (exported to child build scripts) @@ -207,22 +207,29 @@ Each component advertises one or more *configs* (variants) through its variants such as `asan` and `debug`. - **Style B** (e.g. `llvm_runtimes_standalone`): derive their config set from the environment (`AOMP_BUILD_SANITIZER`, `AOMP_BUILD_PERF`, - `AOMP_BUILD_DEBUG`) and have **no** plain `default`; the advertised set is - the normal build (e.g. `asan`, `perf`, `perf+asan`, `debug`, plus - `*-devicertl` device-runtime passes). + `AOMP_BUILD_DEBUG`) and have **no** plain `default` — their default runtime + libraries are produced by the `project`/LLVM build itself. The advertised set + is the extra instrumented variants (e.g. `asan`, `perf`, `perf+asan`, + `debug`, plus `*-devicertl` device-runtime passes). + +The `default` config is the baseline an installable build needs, so it is +**always built when a component offers it**. Selection policy: -- **No `--variant`:** build `default` if the component offers it; otherwise - build **every** advertised config (faithful to style B — this is the normal - full build, including the runtimes matrix). -- **`--variant` (any explicit value):** a **strict filter**. Each component - builds only the requested configs it advertises (in the requested order). A - component with **no** matching config is **skipped entirely** (no tasks, not - even `precheck`/`patch`). In particular, `--variant default` builds just the - `default` config of each component and therefore **skips - `llvm_runtimes_standalone`** (its default runtime libraries are produced by - the `project`/LLVM build itself). +- **No `--variant`:** build **every** advertised config for every component + (the full build — `default` plus all variants such as `asan`/`debug`/`perf`, + including the runtimes matrix). +- **`--variant` (any explicit value):** build `default` (where offered) **plus** + the requested variants each component advertises. So `--variant debug` means + `default,debug` everywhere: default-only components (e.g. `comgr`) still build + their `default`, components offering `debug` add it, and components offering + no `default` (e.g. the runtimes) build just their `debug`. A component that + offers **neither** `default` **nor** any requested variant is **skipped + entirely** (no tasks, not even `precheck`/`patch`). In particular, + `--variant default` builds only the `default` config of each component and + therefore **skips `llvm_runtimes_standalone`** (its default runtime libraries + are produced by the `project`/LLVM build itself). Forms (all combinable, comma-separated and/or repeated): @@ -240,8 +247,8 @@ Examples: ```bash ./aomp_build.py --variant default # default everywhere; skips the runtimes -./aomp_build.py --variant debug,asan # only debug + asan library variants -./aomp_build.py --variant asan list +./aomp_build.py --variant debug,asan # default + debug + asan (where offered) +./aomp_build.py --variant asan list # default + asan ./aomp_build.py --variant llvm_runtimes_standalone=perf list ./aomp_build.py --variant rocr=debug,llvm_runtimes_standalone=asan ``` diff --git a/bin/aomp_build.py b/bin/aomp_build.py index f05b6a40e1..e5ffa4a374 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -293,28 +293,33 @@ def select_variants( has no "default" because its default build is produced by the compiler (project) build itself. + The "default" config is the baseline an installable build needs, so it is + always built when the component offers it. + Selection: - * No explicit --variant: build "default" when offered, otherwise every - advertised config (the intended normal build for style-B). - * Explicit --variant (global and/or per-component): a strict filter - - build only the requested configs the component advertises, in the - requested order. A component with no matching config yields an empty - list and is skipped entirely. So `--variant default` builds just the - default config and skips components that have none (e.g. the runtimes). + * No --variant anywhere: build *every* advertised config (the full build: + default plus all variants the component offers). + * --variant given: build "default" (when offered) plus the requested + variants the component advertises. Requested variants apply globally, + or to a single component via "comp=cfg" (which overrides the global + list for that component). A component that offers neither "default" nor + any requested variant yields an empty list and is skipped entirely - so + `--variant default` builds just the default config and skips components + that have none (e.g. the runtimes, built by the project build). """ - if comp in per_comp: - wanted = per_comp[comp] - elif global_variants: - wanted = global_variants - else: - wanted = None # no explicit request - - if wanted is None: - if "default" in available: - return ["default"] + if not global_variants and not per_comp: + # No filter at all: build everything the component advertises. return list(available) - return [v for v in wanted if v in available] + requested = per_comp[comp] if comp in per_comp else global_variants + + wanted: list[str] = [] + if "default" in available: + wanted.append("default") + for variant in requested: + if variant in available and variant not in wanted: + wanted.append(variant) + return wanted def elaborate_tasks( @@ -690,11 +695,14 @@ def build_arg_parser() -> argparse.ArgumentParser: help="remove component(s)/feature(s); comma-separated " "and/or repeatable") parser.add_argument("--variant", action="append", default=[], metavar="SPEC", - help="strict variant filter: 'cfg' (global) or " - "'comp=cfg' (per-component). Comma-separated and/or " - "repeatable (e.g. 'debug,asan'). Components with no " - "matching config are skipped; 'default' thus skips " - "the runtimes build.") + help="variant filter: 'cfg' (global) or 'comp=cfg' " + "(per-component). Comma-separated and/or repeatable " + "(e.g. 'debug,asan'). 'default' is always built when " + "offered, so '--variant debug' means default+debug; " + "components offering neither default nor a requested " + "variant are skipped (so '--variant default' skips " + "the runtimes). With no --variant, all advertised " + "configs are built.") parser.add_argument("-C", "--clean", action="store_true", help="include 'clean' tasks (default: skip for " "incremental builds)") From 0d14ea397343df292f21545653049a643d9e5f87 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 06:01:27 -0500 Subject: [PATCH 56/71] Use short task names for default-only components When a component advertises only the "default" config, drop the variant segment from its task names (e.g. prereq/build instead of prereq/default/build), matching the form already used for config-less init/fini tasks. Multi-config components keep component/variant/stage. Update AOMP_BUILD.md. --- bin/AOMP_BUILD.md | 20 ++++++++++++++------ bin/aomp_build.py | 13 ++++++++++--- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index f2eb52227f..c4b2349967 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -168,10 +168,16 @@ run. The grammar mirrors `amd-build`: Multiple selectors can be combined; the union of matched tasks runs in task order. Task names take the form `component/variant/stage` for build tasks -(e.g. `comgr/default/cmake`, `llvm_runtimes_standalone/asan/build`) and -`component/stage` for the config-less init/fini tasks (`precheck`, `patch`, -`unpatch` — e.g. `comgr/patch`). Putting the variant in the middle makes it -easy to glob a whole variant across components, e.g. `*/asan/*`. +(e.g. `comgr/default/cmake`, `llvm_runtimes_standalone/asan/build`). The variant +segment is dropped (giving `component/stage`) for: + +- the config-less init/fini tasks (`precheck`, `patch`, `unpatch` — e.g. + `comgr/patch`), and +- components whose only advertised config is `default` (e.g. `prereq/build`, + `rocminfo/cmake`). + +Putting the variant in the middle makes it easy to glob a whole variant across +components, e.g. `*/asan/*`. `continue` is a **trailing** keyword: it must be the last argument, and it applies to the selector immediately before it. `X` may be a task number or a @@ -347,7 +353,8 @@ Each executed task writes a numbered log: /NNN-component-variant-stage.log ``` -(config-less init/fini tasks are `NNN-component-stage.log`.) +(config-less init/fini tasks and default-only components are +`NNN-component-stage.log`.) where `NNN` is the global task number (matching `list`) and `` defaults to `/aomp_build_logs`. Each log begins with the task @@ -524,7 +531,8 @@ component list: Each surviving task is recorded as a `Task` (component, action, config, script path, and the exact `script_args` to pass back). Its display name is -`component/variant/stage` (or `component/stage` when the task has no config). +`component/variant/stage`, shortened to `component/stage` when the task has no +config or when the component advertises only the `default` config. ### Execution diff --git a/bin/aomp_build.py b/bin/aomp_build.py index e5ffa4a374..f9d366d050 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -266,12 +266,15 @@ class Task: cfgname: str | None # build config/variant, e.g. "default" / "asan" script: str # path to build_.sh script_args: list[str] # args to pass back to the script + single_config: bool = False # component advertises only "default" @property def name(self) -> str: - # "component/variant/stage" for config-bearing tasks; config-less - # init/fini tasks (precheck/patch/unpatch) are "component/stage". - if self.cfgname: + # "component/variant/stage" for config-bearing tasks. The variant + # segment is dropped (-> "component/stage") for the config-less + # init/fini tasks (precheck/patch/unpatch) and for components whose only + # advertised config is "default". + if self.cfgname and not self.single_config: return f"{self.comp}/{self.cfgname}/{self.action}" return f"{self.comp}/{self.action}" @@ -340,6 +343,9 @@ def elaborate_tasks( # configs skips the component outright (no init/fini tasks either). if available and not wanted: continue + # Components whose only advertised config is "default" use the short + # two-element task name (comp/stage) instead of comp/default/stage. + single_config = available == ["default"] listing = run_script_capture(script, ["list"], env).splitlines() for line in listing: toks = line.split() @@ -363,6 +369,7 @@ def elaborate_tasks( cfgname=taskcfg, script=script, script_args=toks, + single_config=single_config, ) ) return tasks From 13d4093d0240ee3803bab49cd0527ba88d2d6070 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 06:15:17 -0500 Subject: [PATCH 57/71] Support per-component --build-type --build-type now uses the same scoped grammar as --variant: a bare value applies globally, 'comp=type' sets one component's build type, and values are comma-separated and/or repeatable (e.g. 'project=Debug,comgr=Debug'). The build type is applied as BUILD_TYPE on each task's subprocess at execution time, so components can build with different CMake build types. Update AOMP_BUILD.md. --- bin/AOMP_BUILD.md | 26 +++++++++++++---- bin/aomp_build.py | 74 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index c4b2349967..3ac0e6b792 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -138,9 +138,21 @@ aomp_build.py [options] [selector ...] | `--ninja` / `--no-ninja` | `AOMP_USE_NINJA=1` / `0` | Use the Ninja generator. | | `--ccache` / `--no-ccache` | `AOMP_USE_CCACHE=1` / `0` | Use ccache. | | `--gfx LIST` | `GFXLIST` | GPU target list. | -| `--build-type TYPE` | `BUILD_TYPE` | CMake build type. | +| `--build-type SPEC` | `BUILD_TYPE` | CMake build type; global or per-component (see below). | | `--sudo` | `SUDO=yes` | Install with sudo. | +`--build-type` uses the same scoped grammar as `--variant`: a bare value applies +globally, while `comp=type` sets the build type for one component only. It is +comma-separated and/or repeatable, and per-component values override the global +one. The type is applied to each component's tasks via the `BUILD_TYPE` +environment variable at execution time (it does not affect other components): + +```bash +./aomp_build.py --build-type RelWithDebInfo # global +./aomp_build.py --build-type project=Debug,comgr=Debug # per-component +./aomp_build.py --build-type Release,project=Debug # global Release, project Debug +``` + ### Logging | Option | Description | @@ -554,10 +566,14 @@ indices; `run_tasks()` runs them: reads back `BUILD_DIR`, `AOMP_REPOS`, and `AOMP_REPO_NAME` — used only to locate the default log and manifest directories. - `build_child_env()` starts from the current environment and overlays the - values implied by the build-knob flags (`-j`, `--ninja`, `--ccache`, - `--gfx`, `--build-type`, `--sudo`). This same environment is used for every - child script invocation (introspection, execution, and git/manifest probes), - so introspection sees the same configs that will actually be built. + values implied by the global build-knob flags (`-j`, `--ninja`, `--ccache`, + `--gfx`, `--sudo`). This same environment is used for every child script + invocation (introspection, execution, and git/manifest probes), so + introspection sees the same configs that will actually be built. +- `--build-type` is resolved separately into a global value plus per-component + overrides and applied as the `BUILD_TYPE` variable on each task's subprocess + at execution time (`run_tasks`), so different components can build with + different CMake build types. --- diff --git a/bin/aomp_build.py b/bin/aomp_build.py index f9d366d050..af6a05f467 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -490,8 +490,10 @@ def tail_file(path: str, n: int = 40) -> str: def run_tasks( tasks: list[Task], indices: list[int], env: dict[str, str], log_dir: str, - dry_run: bool, + dry_run: bool, build_type_global: str | None = None, + build_type_per_comp: dict[str, str] | None = None, ) -> int: + build_type_per_comp = build_type_per_comp or {} os.makedirs(log_dir, exist_ok=True) total = len(indices) for count, idx in enumerate(indices, start=1): @@ -500,18 +502,29 @@ def run_tasks( safe = task.name.replace("/", "-") log_path = os.path.join(log_dir, f"{num:03d}-{safe}.log") cmd = ["bash", task.script, *task.script_args] + # Per-component BUILD_TYPE override (per-component wins over global). + build_type = build_type_per_comp.get(task.comp, build_type_global) + task_env = env + if build_type: + task_env = dict(env) + task_env["BUILD_TYPE"] = build_type header = f"[{count}/{total}] task {num}: {task.name}" + bt_note = f" BUILD_TYPE={build_type}" if build_type else "" if dry_run: - print(f"{header}\n {' '.join(cmd)} > {log_path}") + print(f"{header}\n {' '.join(cmd)}{bt_note} > {log_path}") continue - print(f"{header} -> {log_path}", flush=True) + print(f"{header}{bt_note} -> {log_path}", flush=True) start = datetime.datetime.now() with open(log_path, "w", encoding="utf-8") as log: log.write(f"### task {num}: {task.name}\n") log.write(f"### command: {' '.join(cmd)}\n") + if build_type: + log.write(f"### env: BUILD_TYPE={build_type}\n") log.write(f"### start: {start.isoformat()}\n\n") log.flush() - proc = subprocess.run(cmd, stdout=log, stderr=subprocess.STDOUT, env=env) + proc = subprocess.run( + cmd, stdout=log, stderr=subprocess.STDOUT, env=task_env + ) end = datetime.datetime.now() log.write(f"\n### end: {end.isoformat()} (rc={proc.returncode})\n") if proc.returncode != 0: @@ -622,19 +635,19 @@ def import_manifest( # --------------------------------------------------------------------------- # # Environment / CLI flag mapping # --------------------------------------------------------------------------- # -def parse_variant_specs(specs: list[str]) -> tuple[list[str], dict[str, list[str]]]: - """Split --variant values into global variants and per-component overrides. +def parse_scoped_specs(specs: list[str]) -> tuple[list[str], dict[str, list[str]]]: + """Split scoped option values into global values and per-component overrides. - Each --variant value may be a comma-separated list, and the option is - repeatable, so these are all equivalent ways to ask for two variants: + Used by both --variant and --build-type. Each value may be a comma-separated + list, and the option is repeatable, so these are equivalent: --variant debug,asan --variant debug --variant asan - An entry of the form "comp=cfg" overrides a single component; bare entries - apply globally. Both forms can be mixed in one comma-separated value, e.g. + An entry of the form "comp=value" applies to a single component; bare + entries apply globally. Both forms can be mixed in one value, e.g. --variant comp1=debug,comp2=asan - Multiple "comp=cfg" entries for the same component accumulate. + Multiple "comp=value" entries for the same component accumulate, in order. """ - global_variants: list[str] = [] + global_values: list[str] = [] per_comp: dict[str, list[str]] = {} for spec in specs: for entry in spec.split(","): @@ -645,8 +658,21 @@ def parse_variant_specs(specs: list[str]) -> tuple[list[str], dict[str, list[str comp, _, val = entry.partition("=") per_comp.setdefault(comp.strip(), []).append(val.strip()) else: - global_variants.append(entry) - return global_variants, per_comp + global_values.append(entry) + return global_values, per_comp + + +def parse_build_type_specs(specs: list[str]) -> tuple[str | None, dict[str, str]]: + """Resolve --build-type into a single global type and per-component types. + + Same grammar as --variant (global value or 'comp=type', comma-separated + and/or repeatable), but a build type is a single value per scope, so the + last value wins if several are given for the same scope. + """ + global_values, per_comp_lists = parse_scoped_specs(specs) + global_bt = global_values[-1] if global_values else None + per_comp_bt = {comp: vals[-1] for comp, vals in per_comp_lists.items()} + return global_bt, per_comp_bt def build_child_env(args: argparse.Namespace) -> dict[str, str]: @@ -663,8 +689,8 @@ def setenv(name: str, value: str) -> None: setenv("AOMP_USE_CCACHE", "1" if args.ccache else "0") if args.gfx: setenv("GFXLIST", args.gfx) - if args.build_type: - setenv("BUILD_TYPE", args.build_type) + # BUILD_TYPE is applied per-component at execution time (see run_tasks), + # so it is intentionally not set in the shared child environment here. if args.sudo: setenv("SUDO", "yes") return env @@ -733,8 +759,11 @@ def build_arg_parser() -> argparse.ArgumentParser: help="do not use ccache (AOMP_USE_CCACHE=0)") parser.add_argument("--gfx", default=None, metavar="LIST", help="GPU target list (GFXLIST)") - parser.add_argument("--build-type", default=None, metavar="TYPE", - help="CMake build type (BUILD_TYPE)") + parser.add_argument("--build-type", action="append", default=[], + metavar="SPEC", + help="CMake build type (BUILD_TYPE): 'type' (global) or " + "'comp=type' (per-component). Comma-separated and/or " + "repeatable, e.g. 'project=Debug,comgr=Debug'.") parser.add_argument("--sudo", action="store_true", help="install with sudo (SUDO=yes)") # Version manifest. @@ -779,7 +808,8 @@ def main(argv: list[str]) -> int: if rc != 0: return rc - global_variants, per_comp_variants = parse_variant_specs(args.variant) + global_variants, per_comp_variants = parse_scoped_specs(args.variant) + build_type_global, build_type_per_comp = parse_build_type_specs(args.build_type) tasks = elaborate_tasks( cfg, components, child_env, global_variants, per_comp_variants, include_clean=args.clean, @@ -797,7 +827,11 @@ def main(argv: list[str]) -> int: print("aomp_build: no tasks selected") return 0 - return run_tasks(tasks, indices, child_env, log_dir, args.dry_run) + return run_tasks( + tasks, indices, child_env, log_dir, args.dry_run, + build_type_global=build_type_global, + build_type_per_comp=build_type_per_comp, + ) if __name__ == "__main__": From b721bb2efa6045b7a212d5328871f3c7ea89e72e Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 06:43:42 -0500 Subject: [PATCH 58/71] Isolate child env, add install/build/prereq dir options Build child scripts now run in an environment constructed by the orchestrator rather than inheriting the caller's, so build-affecting state is under aomp_build.py's control. PATH defaults to standard system locations (fixing cases where a Homebrew pkg-config shadowed the system one); --inherit-path and --pass-env opt back in to caller values. Add -i/--install (AOMP), -b/--build (BUILD_AOMP), and -p/--prereq (AOMP_SUPP) to set the core directory layout, exported as absolute paths to every child script. Make the directory options apply consistently by replacing hard-coded $HOME/local references with $AOMP_SUPP in build_rocprofiler.sh, build_rocprofiler-sdk.sh, build_hipamd.sh, build_emissary.sh, build_rccl.sh, and build_qmcpack.sh. Send the aomp_common_vars "using system cmake" warning to stderr so it no longer pollutes list_configs introspection. --- bin/AOMP_BUILD.md | 88 ++++++++++++++++++++++++++++++--- bin/aomp_build.py | 96 ++++++++++++++++++++++++++++++++++-- bin/aomp_common_vars | 4 +- bin/build_emissary.sh | 4 +- bin/build_hipamd.sh | 6 +-- bin/build_qmcpack.sh | 8 +-- bin/build_rocprofiler-sdk.sh | 8 +-- bin/build_rocprofiler.sh | 8 +-- bin/rocmlibs/build_rccl.sh | 4 +- 9 files changed, 192 insertions(+), 34 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index 3ac0e6b792..9bd353b946 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -130,6 +130,17 @@ aomp_build.py [options] [selector ...] | `--variant SPEC` | Variant filter: `cfg` (global) or `comp=cfg` (per-component). Comma-separated and/or repeatable. `default` is always built when offered (so `--variant debug` = default+debug); components offering neither are skipped (so `--variant default` skips the runtimes). See [Build variants](#build-variants). | | `-C`, `--clean` | Include `clean` tasks (skipped by default for incremental builds). | +### Directory layout (exported to child build scripts) + +| Option | Environment variable | Notes | +|--------|----------------------|-------| +| `-i`, `--install DIR` | `AOMP` | Install root. The versioned install dir `AOMP_` (`AOMP_INSTALL_DIR`) derives from it. Default: `$HOME/rocm/aomp`. | +| `-b`, `--build DIR` | `BUILD_AOMP` | Where cmake/make run and object files go (also `BUILD_DIR`, used for the default log/manifest locations). Default: the repo dir (`AOMP_REPOS`). | +| `-p`, `--prereq DIR` | `AOMP_SUPP` | Prerequisite/supplemental root. Its build (`AOMP_SUPP_BUILD`), install (`AOMP_SUPP_INSTALL`), and the prereq `cmake` all derive from it. Default: `$HOME/local`. | + +Each is expanded to an absolute path (with `~`) before being handed to the +child scripts, so they resolve identically regardless of working directory. + ### Build environment knobs (exported to child build scripts) | Option | Environment variable | Notes | @@ -153,15 +164,50 @@ environment variable at execution time (it does not affect other components): ./aomp_build.py --build-type Release,project=Debug # global Release, project Debug ``` +### Environment isolation + +Child build scripts run in an **isolated environment built from scratch** by the +orchestrator, not a copy of your shell's environment. This keeps *what* gets +built under the orchestrator's control and prevents stray exports (a Homebrew +`pkg-config` ahead of the system one, a leftover `CC`/`LD_LIBRARY_PATH`, a stale +`PKG_CONFIG_PATH`, etc.) from silently changing the build. + +What the child environment contains: + +- A controlled `PATH` of standard system locations only: + `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`. +- A curated pass-through of identity/locale/terminal variables that do not + affect *what* is compiled: `HOME`, `USER`, `LOGNAME`, `SHELL`, `TERM`, `LANG`, + `LANGUAGE`, `LC_*`, `TZ`, `TMPDIR`, `DISPLAY`, `XAUTHORITY`, and the `SSH_*` + variables (so git-over-ssh and your `~/.gitconfig` keep working). +- The build knobs set by the flags above (`AOMP_JOB_THREADS`, `GFXLIST`, ...). + +Everything else (`CC`, `CXX`, `LD_LIBRARY_PATH`, `PKG_CONFIG_*`, `AOMP_*`, +`ROCM_*`, ...) is **dropped** unless the orchestrator sets it from a flag or you +opt in explicitly: + +| Option | Description | +|--------|-------------| +| `--inherit-path` | Use your shell's `PATH` for child scripts instead of the controlled default. | +| `--pass-env VARS` | Leak named variable(s) into the child environment. Comma-separated and/or repeatable, e.g. `--pass-env CC,CXX,LD_LIBRARY_PATH`. | + +```bash +./aomp_build.py --inherit-path # let my PATH through +./aomp_build.py --pass-env LD_LIBRARY_PATH # leak one var +./aomp_build.py --inherit-path --pass-env CC,CXX # both +``` + +Because the classic `AOMP_*` overrides are no longer inherited automatically, +drive non-flag knobs either with `--pass-env` or by exporting them and letting a +flag carry them. (`AOMP_JOB_THREADS=32 ./aomp_build.py` no longer leaks through; +use `-j 32` instead.) + ### Logging | Option | Description | |--------|-------------| | `--log-dir DIR` | Directory for per-task logs. Default: `/aomp_build_logs`. | -Any variable not set via a flag is inherited from the environment, so you can -still drive the build the "classic" way (`AOMP_JOB_THREADS=32 ./aomp_build.py`). - --- ## Selectors @@ -435,8 +481,21 @@ with a trailing `continue`: ```bash ./aomp_build.py -j 32 --ninja --ccache # threads + ninja + ccache ./aomp_build.py --gfx "gfx90a;gfx942" # specific GPU targets +./aomp_build.py --inherit-path # use my PATH (not the clean default) +./aomp_build.py --pass-env CC,CXX,LD_LIBRARY_PATH # leak specific env vars ``` +### Use custom install / build / prereq directories + +```bash +./aomp_build.py -i /opt/aomp -b /scratch/aompbuild -p /opt/aomp-supp +``` + +`-i/--install` sets the install root (`AOMP`), `-b/--build` sets where builds run +and object files go (`BUILD_AOMP`, and the default log/manifest location), and +`-p/--prereq` sets the supplemental/prerequisite root (`AOMP_SUPP`). All three +are made absolute and exported to every child script. + ### Reproduce an earlier build ```bash @@ -565,11 +624,16 @@ indices; `run_tasks()` runs them: - `discover_env()` sources `aomp_utils` + `aomp_common_vars` in a subshell and reads back `BUILD_DIR`, `AOMP_REPOS`, and `AOMP_REPO_NAME` — used only to locate the default log and manifest directories. -- `build_child_env()` starts from the current environment and overlays the - values implied by the global build-knob flags (`-j`, `--ninja`, `--ccache`, - `--gfx`, `--sudo`). This same environment is used for every child script - invocation (introspection, execution, and git/manifest probes), so - introspection sees the same configs that will actually be built. +- `build_child_env()` builds the child environment **from scratch** (it does not + copy the caller's environment): a curated pass-through of identity/locale vars + (`ENV_PASSTHROUGH` + `LC_*`), a controlled `PATH` (`DEFAULT_CHILD_PATH`, or the + caller's PATH with `--inherit-path`), any vars named by `--pass-env`, the + directory knobs (`-i`/`AOMP`, `-b`/`BUILD_AOMP`, `-p`/`AOMP_SUPP`, made + absolute), and then the values implied by the global build-knob flags (`-j`, + `--ninja`, `--ccache`, `--gfx`, `--sudo`). This same environment is used for every child + script invocation (introspection, execution, and git/manifest probes), so + introspection sees the same configs that will actually be built — and isolates + the build from stray exports on the caller's side. - `--build-type` is resolved separately into a global value plus per-component overrides and applied as the `BUILD_TYPE` variable on each task's subprocess at execution time (`run_tasks`), so different components can build with @@ -601,6 +665,14 @@ A target repo is dirty. Commit/stash/clean it, or drop it from the resolved set Read the tailed log (path printed on failure, under the log dir). After fixing, resume with ` continue`. +**A tool isn't found, or the wrong one is picked up.** +Child scripts use a controlled `PATH` and a clean environment by default (see +[Environment isolation](#environment-isolation)), so a tool living only in a +non-standard location (e.g. a Homebrew prefix) won't be on `PATH`, and +build-affecting exports like `PKG_CONFIG_PATH`, `CC`, or `LD_LIBRARY_PATH` are +not inherited. Use `--inherit-path` to restore your `PATH`, and/or +`--pass-env VAR[,VAR...]` to leak the specific variables the build needs. + --- ## Extending diff --git a/bin/aomp_build.py b/bin/aomp_build.py index af6a05f467..fd4c2661b4 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -36,6 +36,28 @@ BIN_DIR = os.path.dirname(os.path.abspath(__file__)) DEFAULT_CONFIG = os.path.join(BIN_DIR, "configs", "aomp.cudf") +# Child build scripts run in an isolated environment built from scratch by this +# orchestrator, so that what gets built is under the orchestrator's control and +# not at the mercy of whatever the caller happened to have exported. Only the +# variables below are passed through unchanged: these are identity / locale / +# terminal settings that affect *how* things look or *who* git acts as, not +# *what* gets compiled. Everything else (CC, CXX, LD_LIBRARY_PATH, PKG_CONFIG_*, +# AOMP_*, ROCM_*, ...) is dropped unless the orchestrator sets it explicitly or +# the user opts in with --pass-env. Any variable named LC_* is also passed +# through (locale categories). +ENV_PASSTHROUGH = ( + "HOME", "USER", "LOGNAME", "SHELL", "TERM", + "LANG", "LANGUAGE", "TZ", "TMPDIR", + "DISPLAY", "XAUTHORITY", + "SSH_AUTH_SOCK", "SSH_CONNECTION", "SSH_CLIENT", "SSH_TTY", +) + +# Deterministic PATH handed to child build scripts. Standard system locations +# only, so tool resolution is predictable and not shadowed by whatever the +# caller put earlier on their PATH (e.g. a Homebrew pkg-config that cannot see +# the system .pc files). Override with --inherit-path to use the caller's PATH. +DEFAULT_CHILD_PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + # --------------------------------------------------------------------------- # # Config model + CUDF parser @@ -237,15 +259,20 @@ def run_script_capture(path: str, args: list[str], env: dict[str, str]) -> str: return proc.stdout -def discover_env() -> dict[str, str]: - """Source aomp_utils + aomp_common_vars to learn BUILD_DIR/AOMP_REPOS.""" +def discover_env(env: dict[str, str] | None = None) -> dict[str, str]: + """Source aomp_utils + aomp_common_vars to learn BUILD_DIR/AOMP_REPOS. + + The same isolated child environment used for the build is passed in, so the + discovered values reflect any -i/-b/-p directory overrides (e.g. BUILD_DIR + follows --build, used for the default log/manifest locations). + """ snippet = ( f'. "{BIN_DIR}/aomp_utils" >/dev/null 2>&1; ' f'. "{BIN_DIR}/aomp_common_vars" >/dev/null 2>&1; ' 'printf "%s\\n" "$BUILD_DIR" "$AOMP_REPOS" "$AOMP_REPO_NAME"' ) proc = subprocess.run( - ["bash", "-c", snippet], capture_output=True, text=True + ["bash", "-c", snippet], capture_output=True, text=True, env=env ) out = proc.stdout.splitlines() out += [""] * (3 - len(out)) @@ -676,11 +703,48 @@ def parse_build_type_specs(specs: list[str]) -> tuple[str | None, dict[str, str] def build_child_env(args: argparse.Namespace) -> dict[str, str]: - env = dict(os.environ) + """Construct the isolated environment for child build scripts. + + Rather than inheriting the caller's environment wholesale, the env is built + from scratch: a curated pass-through of identity/locale vars (ENV_PASSTHROUGH + plus LC_*), a controlled PATH, and the build knobs derived from CLI flags. + --inherit-path leaks the caller's PATH through; --pass-env leaks named vars. + """ + src = os.environ + env: dict[str, str] = {} + + for name in ENV_PASSTHROUGH: + if name in src: + env[name] = src[name] + for name, value in src.items(): + if name.startswith("LC_"): + env[name] = value + + # PATH: controlled by default, optionally inherited from the caller. + if args.inherit_path: + env["PATH"] = src.get("PATH", DEFAULT_CHILD_PATH) + else: + env["PATH"] = DEFAULT_CHILD_PATH + + # Escape hatch: explicitly leak named variables for machine-specific needs. + for name in args.pass_env: + for var in (n.strip() for n in name.split(",")): + if var and var in src: + env[var] = src[var] def setenv(name: str, value: str) -> None: env[name] = value + def setdir(name: str, value: str | None) -> None: + # Directory knobs are made absolute (with ~ expansion) so child scripts + # resolve them identically regardless of their working directory. + if value is not None: + env[name] = os.path.abspath(os.path.expanduser(value)) + + setdir("AOMP", args.install) + setdir("BUILD_AOMP", args.build) + setdir("AOMP_SUPP", args.prereq) + if args.jobs is not None: setenv("AOMP_JOB_THREADS", str(args.jobs)) if args.ninja is not None: @@ -721,6 +785,18 @@ def build_arg_parser() -> argparse.ArgumentParser: parser.add_argument("selectors", nargs="*", help="task selector(s); see below") parser.add_argument("-c", "--config", default=DEFAULT_CONFIG, help=f"CUDF config file (default: {DEFAULT_CONFIG})") + # Core directory layout (exported to child build scripts). + parser.add_argument("-i", "--install", default=None, metavar="DIR", + help="installation directory root (AOMP); the versioned " + "install dir AOMP_ derives from it. " + "Default: $HOME/rocm/aomp") + parser.add_argument("-b", "--build", default=None, metavar="DIR", + help="directory where builds run / object files go " + "(BUILD_AOMP). Default: the repo dir (AOMP_REPOS)") + parser.add_argument("-p", "--prereq", default=None, metavar="DIR", + help="prerequisite/supplemental component root (AOMP_SUPP); " + "its build/install subdirs and the prereq cmake " + "derive from it. Default: $HOME/local") parser.add_argument("--add", action="append", default=[], metavar="NAMES", help="add component(s)/feature(s); comma-separated and/or " "repeatable") @@ -766,6 +842,16 @@ def build_arg_parser() -> argparse.ArgumentParser: "repeatable, e.g. 'project=Debug,comgr=Debug'.") parser.add_argument("--sudo", action="store_true", help="install with sudo (SUDO=yes)") + # Environment isolation. + parser.add_argument("--inherit-path", action="store_true", + help="use the caller's PATH for child build scripts " + "instead of the controlled default " + f"({DEFAULT_CHILD_PATH})") + parser.add_argument("--pass-env", action="append", default=[], metavar="VARS", + help="leak named environment variable(s) from the caller " + "into the otherwise-isolated child environment; " + "comma-separated and/or repeatable " + "(e.g. --pass-env CC,CXX,LD_LIBRARY_PATH)") # Version manifest. parser.add_argument("--export-manifest", nargs="?", const="", metavar="FILE", help="export a git fingerprint manifest and exit " @@ -780,8 +866,8 @@ def main(argv: list[str]) -> int: cfg = parse_cudf(args.config) config_name = os.path.splitext(os.path.basename(args.config))[0] - env_info = discover_env() child_env = build_child_env(args) + env_info = discover_env(child_env) components = resolve_components(cfg, args.add, args.remove) diff --git a/bin/aomp_common_vars b/bin/aomp_common_vars index 0e30014d20..2d0c842e81 100644 --- a/bin/aomp_common_vars +++ b/bin/aomp_common_vars @@ -165,8 +165,8 @@ if [ ! -f "$AOMP_CMAKE" ] ; then exit 1 else # FIXME: Add version check here for system cmake. - echo "WARNING: Using system cmake $AOMP_CMAKE " - echo " consider building cmake with: ./build_prereq.sh cmake" + echo "WARNING: Using system cmake $AOMP_CMAKE " >&2 + echo " consider building cmake with: ./build_prereq.sh cmake" >&2 fi fi diff --git a/bin/build_emissary.sh b/bin/build_emissary.sh index 74889d202a..5037c5f7ec 100755 --- a/bin/build_emissary.sh +++ b/bin/build_emissary.sh @@ -55,7 +55,7 @@ declare -a extra_cmake_opts=() if [ "$_sname" == "build_emissary_mpi.sh" ] ; then EMISSARY_SRC_SUBDIR=MPI EMISSARY_BUILD_SUBDIR=emissary_mpi - extra_cmake_opts+=("-DLLVM_EXTERNAL_EMISSARY_MPI_INSTALL=$HOME/local/rocmopenmpi") + extra_cmake_opts+=("-DLLVM_EXTERNAL_EMISSARY_MPI_INSTALL=$AOMP_SUPP/rocmopenmpi") elif [ "$_sname" == "build_emissary_hdf5.sh" ] ; then EMISSARY_SRC_SUBDIR=HDF5 EMISSARY_BUILD_SUBDIR=emissary_hdf5 @@ -68,7 +68,7 @@ fi # Install EMISSARY in the compiler directory of ROCm INSTALL_EMISSARY=${INSTALL_EMISSARY:-$AOMP_INSTALL_DIR}/lib/llvm REPO_DIR="$(cfgvar AOMP_REPOS)/emissary" -export OPENMPI_DIR=$HOME/local/rocmopenmpi +export OPENMPI_DIR=$AOMP_SUPP/rocmopenmpi if [ "$1" == "-h" ] || [ "$1" == "help" ] || [ "$1" == "-help" ] ; then echo " " diff --git a/bin/build_hipamd.sh b/bin/build_hipamd.sh index 21271fda1b..42fb67a22d 100755 --- a/bin/build_hipamd.sh +++ b/bin/build_hipamd.sh @@ -219,7 +219,7 @@ task_cmake() { export ROCM_RPATH="$AOMP_ORIGIN_RPATH_LIST" CMAKEOPTS=("${MYCMAKEOPTS[@]}" "${AOMP_ASAN_ORIGIN_RPATH[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR/lib/asan/cmake;$AOMP_INSTALL_DIR;$AOMP_SUPP/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" -DCMAKE_INSTALL_LIBDIR=lib/asan -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" @@ -230,7 +230,7 @@ task_cmake() { CMAKEOPTS=("${MYCMAKEOPTS[@]}" "${AOMP_DEBUG_ORIGIN_RPATH[@]}" -DCMAKE_BUILD_TYPE=DEBUG - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$AOMP_SUPP/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" -DCMAKE_INSTALL_LIBDIR=lib-debug -DCMAKE_C_COMPILER="$LLVM_INSTALL_LOC/bin/clang" -DCMAKE_CXX_COMPILER="$LLVM_INSTALL_LOC/bin/clang++" @@ -239,7 +239,7 @@ task_cmake() { -DCMAKE_C_FLAGS="$(cmquot -g "${_prefix_map[@]}")") else CMAKEOPTS=("${MYCMAKEOPTS[@]}" - -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$HOME/local/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" + -DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$AOMP_SUPP/openclicdloader;$BuildRoot/hipamd/opencl/khronos/icd" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_CXX_FLAGS=-I"${AOMP_INSTALL_DIR}/include/amd_comgr" -DCMAKE_CXX_FLAGS=-Wno-error=deprecated-declarations diff --git a/bin/build_qmcpack.sh b/bin/build_qmcpack.sh index 2fd3880dc8..926e53d44a 100755 --- a/bin/build_qmcpack.sh +++ b/bin/build_qmcpack.sh @@ -53,10 +53,10 @@ else # Need the following packaages from ubuntu: libxml2-dev, libfftw3-dev, libboost-dev BOOST_ROOT=${BOOST_ROOT:-/usr/lib/x86_64-linux-gnu} # We now get FFTW, OPENMPI, and HDF5 from AOMP supplemental component installs. - # run build_supp.sh to install supplemental components into $HOME/local. - FFTW_HOME=${FFTW_HOME:-$HOME/local/fftw} - OPENMPI_INSTALL=${OPENMPI_INSTALL:-$HOME/local/openmpi} - HDF5_ROOT=${HDF5_ROOT:-$HOME/local/hdf5} + # run build_supp.sh to install supplemental components into $AOMP_SUPP. + FFTW_HOME=${FFTW_HOME:-$AOMP_SUPP/fftw} + OPENMPI_INSTALL=${OPENMPI_INSTALL:-$AOMP_SUPP/openmpi} + HDF5_ROOT=${HDF5_ROOT:-$AOMP_SUPP/hdf5} export BOOST_ROOT FFTW_HOME HDF5_ROOT fi diff --git a/bin/build_rocprofiler-sdk.sh b/bin/build_rocprofiler-sdk.sh index 81cb0953aa..9065f35dc4 100755 --- a/bin/build_rocprofiler-sdk.sh +++ b/bin/build_rocprofiler-sdk.sh @@ -130,7 +130,7 @@ task_cmake() { exit 1 fi - MYCMAKEOPTS=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$HOME/local/aqlprofile" + MYCMAKEOPTS=(-DCMAKE_PREFIX_PATH="$AOMP_INSTALL_DIR;$AOMP_SUPP/aqlprofile" -DCMAKE_INSTALL_PREFIX="$InstallDir" -DCMAKE_BUILD_TYPE=Release -DROCM_ROOT_DIR="$AOMP_INSTALL_DIR" @@ -198,9 +198,9 @@ task_postinstall() { local InstallDir InstallDir="$(get_install_dir "$Cfg")" - if [ -d "$HOME/local/aqlprofile/lib" ]; then - echo "Copying aqlprofile libraries from $HOME/local/aqlprofile/lib to $InstallDir/lib" - cp -r "$HOME"/local/aqlprofile/lib/* "$InstallDir"/lib + if [ -d "$AOMP_SUPP/aqlprofile/lib" ]; then + echo "Copying aqlprofile libraries from $AOMP_SUPP/aqlprofile/lib to $InstallDir/lib" + cp -r "$AOMP_SUPP"/aqlprofile/lib/* "$InstallDir"/lib else echo "Error: rocprofiler-sdk needs aqlprofile libraries to exist in $InstallDir/lib. Please run ./build_prereq.sh first." exit 1 diff --git a/bin/build_rocprofiler.sh b/bin/build_rocprofiler.sh index 59a7b0b342..454a5f1df4 100755 --- a/bin/build_rocprofiler.sh +++ b/bin/build_rocprofiler.sh @@ -121,7 +121,7 @@ task_cmake() { export HIP_CLANG_PATH="$LLVM_INSTALL_LOC/bin" export ROCM_PATH="$AOMP_INSTALL_DIR" export CMAKE_BUILD_TYPE=Release - export CMAKE_PREFIX_PATH="$ROCM_DIR/roctracer/include/ext;$ROCM_DIR/include/platform;$ROCM_DIR/include;$ROCM_DIR/lib;$ROCM_DIR;$HOME/.local/bin;$HOME/local/aqlprofile;$LLVM_INSTALL_LOC" + export CMAKE_PREFIX_PATH="$ROCM_DIR/roctracer/include/ext;$ROCM_DIR/include/platform;$ROCM_DIR/include;$ROCM_DIR/lib;$ROCM_DIR;$HOME/.local/bin;$AOMP_SUPP/aqlprofile;$LLVM_INSTALL_LOC" export PATH=$HOME/.local/bin:$InstallDir/bin:$PATH CMAKE_WITH_EXPERIMENTAL=() @@ -148,9 +148,9 @@ task_cmake() { -DPROF_API_HEADER_PATH="$InstallDir/include/roctracer/ext" -DHIP_ROOT_DIR="$InstallDir/hip" -DAQLPROFILE_LIB="$(cfgvar AOMP_SUPP)/aqlprofile/lib/libhsa-amd-aqlprofile64.so" - -DCMAKE_CXX_FLAGS="-I$HOME/local/rocmsmilib/include" - -DHIP_HIPCC_FLAGS="-I$HOME/local/rocmsmilib/include" - -DCMAKE_EXE_LINKER_FLAGS="-L$HOME/local/rocmsmilib/lib -L$HOME/local/rocmsmilib/lib64 -Wl,--disable-new-dtags") + -DCMAKE_CXX_FLAGS="-I$AOMP_SUPP/rocmsmilib/include" + -DHIP_HIPCC_FLAGS="-I$AOMP_SUPP/rocmsmilib/include" + -DCMAKE_EXE_LINKER_FLAGS="-L$AOMP_SUPP/rocmsmilib/lib -L$AOMP_SUPP/rocmsmilib/lib64 -Wl,--disable-new-dtags") mkdir -p "$BuildDir" pushd "$BuildDir" >& /dev/null || exit diff --git a/bin/rocmlibs/build_rccl.sh b/bin/rocmlibs/build_rccl.sh index 3c358098e2..eb50356d92 100755 --- a/bin/rocmlibs/build_rccl.sh +++ b/bin/rocmlibs/build_rccl.sh @@ -31,7 +31,7 @@ cfgbool() { } _repo_dir="$(cfgvar AOMP_REPOS)/rocmlibs/rccl" -_rocm_core_info="$HOME/local/rocm-core/.info" +_rocm_core_info="$AOMP_SUPP/rocm-core/.info" get_src_dir() { echo "$_repo_dir" @@ -71,7 +71,7 @@ setup_env() { # rccl needs cmake 3.25, so put prereq cmake first in path export PATH="$AompSupp/cmake/bin:$AOMP_INSTALL_DIR/bin:$PATH" export NUM_PROC="$Jobs" - export CXXFLAGS="-I$HOME/local/rocm-core/include" + export CXXFLAGS="-I$AompSupp/rocm-core/include" export LDFLAGS="-fPIC" EXPLICIT_ROCM_VERSION=$(grep -E "[0-9]+\.[0-9]+\.[0-9]+" < "$_rocm_core_info/version") export EXPLICIT_ROCM_VERSION From ca2f5b80f1aa5145aa6eaaf604e9a22b770fa74e Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 06:53:20 -0500 Subject: [PATCH 59/71] Add -s/--source option; tidy progress lines Add -s/--source to set the repo/source root (AOMP_REPOS), exported as an absolute path to every child script alongside the other directory knobs. All build scripts already derive their repo path from AOMP_REPOS, so the override applies consistently with no script changes. Drop the redundant "task N:" from progress lines and show the per-task log path relative to the build root for brevity (falling back to the absolute path when the log dir lies elsewhere). --- bin/AOMP_BUILD.md | 19 +++++++++++-------- bin/aomp_build.py | 20 +++++++++++++++++--- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index 9bd353b946..8033959ba6 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -134,6 +134,7 @@ aomp_build.py [options] [selector ...] | Option | Environment variable | Notes | |--------|----------------------|-------| +| `-s`, `--source DIR` | `AOMP_REPOS` | Source/repo root holding the cloned component repos. The build dir (`BUILD_AOMP`) defaults to it unless `-b` is given. Default: `$HOME/git/aomp`. | | `-i`, `--install DIR` | `AOMP` | Install root. The versioned install dir `AOMP_` (`AOMP_INSTALL_DIR`) derives from it. Default: `$HOME/rocm/aomp`. | | `-b`, `--build DIR` | `BUILD_AOMP` | Where cmake/make run and object files go (also `BUILD_DIR`, used for the default log/manifest locations). Default: the repo dir (`AOMP_REPOS`). | | `-p`, `--prereq DIR` | `AOMP_SUPP` | Prerequisite/supplemental root. Its build (`AOMP_SUPP_BUILD`), install (`AOMP_SUPP_INSTALL`), and the prereq `cmake` all derive from it. Default: `$HOME/local`. | @@ -485,16 +486,18 @@ with a trailing `continue`: ./aomp_build.py --pass-env CC,CXX,LD_LIBRARY_PATH # leak specific env vars ``` -### Use custom install / build / prereq directories +### Use custom source / install / build / prereq directories ```bash -./aomp_build.py -i /opt/aomp -b /scratch/aompbuild -p /opt/aomp-supp +./aomp_build.py -s /scratch/aomp-src -i /opt/aomp -b /scratch/aompbuild -p /opt/aomp-supp ``` -`-i/--install` sets the install root (`AOMP`), `-b/--build` sets where builds run -and object files go (`BUILD_AOMP`, and the default log/manifest location), and -`-p/--prereq` sets the supplemental/prerequisite root (`AOMP_SUPP`). All three -are made absolute and exported to every child script. +`-s/--source` sets the repo/source root (`AOMP_REPOS`), `-i/--install` sets the +install root (`AOMP`), `-b/--build` sets where builds run and object files go +(`BUILD_AOMP`, and the default log/manifest location), and `-p/--prereq` sets the +supplemental/prerequisite root (`AOMP_SUPP`). All are made absolute and exported +to every child script. Note `BUILD_AOMP` defaults to `AOMP_REPOS`, so `-s` +without `-b` puts builds under the source root. ### Reproduce an earlier build @@ -628,8 +631,8 @@ indices; `run_tasks()` runs them: copy the caller's environment): a curated pass-through of identity/locale vars (`ENV_PASSTHROUGH` + `LC_*`), a controlled `PATH` (`DEFAULT_CHILD_PATH`, or the caller's PATH with `--inherit-path`), any vars named by `--pass-env`, the - directory knobs (`-i`/`AOMP`, `-b`/`BUILD_AOMP`, `-p`/`AOMP_SUPP`, made - absolute), and then the values implied by the global build-knob flags (`-j`, + directory knobs (`-s`/`AOMP_REPOS`, `-i`/`AOMP`, `-b`/`BUILD_AOMP`, + `-p`/`AOMP_SUPP`, made absolute), and then the values implied by the global build-knob flags (`-j`, `--ninja`, `--ccache`, `--gfx`, `--sudo`). This same environment is used for every child script invocation (introspection, execution, and git/manifest probes), so introspection sees the same configs that will actually be built — and isolates diff --git a/bin/aomp_build.py b/bin/aomp_build.py index fd4c2661b4..7eea6bfb52 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -519,6 +519,7 @@ def run_tasks( tasks: list[Task], indices: list[int], env: dict[str, str], log_dir: str, dry_run: bool, build_type_global: str | None = None, build_type_per_comp: dict[str, str] | None = None, + log_base: str | None = None, ) -> int: build_type_per_comp = build_type_per_comp or {} os.makedirs(log_dir, exist_ok=True) @@ -535,12 +536,19 @@ def run_tasks( if build_type: task_env = dict(env) task_env["BUILD_TYPE"] = build_type - header = f"[{count}/{total}] task {num}: {task.name}" + header = f"[{count}/{total}] {task.name}" bt_note = f" BUILD_TYPE={build_type}" if build_type else "" + # Show the log path relative to the build root (where logs live) for + # brevity; fall back to the absolute path if it lies elsewhere. + rel_log = log_path + if log_base: + candidate = os.path.relpath(log_path, log_base) + if not candidate.startswith(".."): + rel_log = candidate if dry_run: - print(f"{header}\n {' '.join(cmd)}{bt_note} > {log_path}") + print(f"{header}\n {' '.join(cmd)}{bt_note} > {rel_log}") continue - print(f"{header}{bt_note} -> {log_path}", flush=True) + print(f"{header}{bt_note} -> {rel_log}", flush=True) start = datetime.datetime.now() with open(log_path, "w", encoding="utf-8") as log: log.write(f"### task {num}: {task.name}\n") @@ -741,6 +749,7 @@ def setdir(name: str, value: str | None) -> None: if value is not None: env[name] = os.path.abspath(os.path.expanduser(value)) + setdir("AOMP_REPOS", args.source) setdir("AOMP", args.install) setdir("BUILD_AOMP", args.build) setdir("AOMP_SUPP", args.prereq) @@ -786,6 +795,10 @@ def build_arg_parser() -> argparse.ArgumentParser: parser.add_argument("-c", "--config", default=DEFAULT_CONFIG, help=f"CUDF config file (default: {DEFAULT_CONFIG})") # Core directory layout (exported to child build scripts). + parser.add_argument("-s", "--source", default=None, metavar="DIR", + help="source/repo root (AOMP_REPOS) holding the cloned " + "component repos. The build dir defaults to it " + "unless -b is given. Default: $HOME/git/aomp") parser.add_argument("-i", "--install", default=None, metavar="DIR", help="installation directory root (AOMP); the versioned " "install dir AOMP_ derives from it. " @@ -917,6 +930,7 @@ def main(argv: list[str]) -> int: tasks, indices, child_env, log_dir, args.dry_run, build_type_global=build_type_global, build_type_per_comp=build_type_per_comp, + log_base=build_dir, ) From 9447a391d7271e035dd57603543331d39fe647b9 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 08:15:54 -0500 Subject: [PATCH 60/71] Number progress lines by absolute task position Make the [NNN/TTT] progress counter relative to the whole build: the first number is the task's absolute 1-based position in the full elaborated list and the total is the full task count, so running a subset still reports its real task numbers (zero-padded to width). --- bin/aomp_build.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bin/aomp_build.py b/bin/aomp_build.py index 7eea6bfb52..66f41bb487 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -523,8 +523,12 @@ def run_tasks( ) -> int: build_type_per_comp = build_type_per_comp or {} os.makedirs(log_dir, exist_ok=True) - total = len(indices) - for count, idx in enumerate(indices, start=1): + # The progress counter is relative to the whole build: num is the task's + # absolute position (1-based) in the full elaborated task list and total is + # the full count, so a selected subset still reports its real task numbers. + total = len(tasks) + width = len(str(total)) + for idx in indices: task = tasks[idx] num = idx + 1 safe = task.name.replace("/", "-") @@ -536,7 +540,7 @@ def run_tasks( if build_type: task_env = dict(env) task_env["BUILD_TYPE"] = build_type - header = f"[{count}/{total}] {task.name}" + header = f"[{num:0{width}d}/{total}] {task.name}" bt_note = f" BUILD_TYPE={build_type}" if build_type else "" # Show the log path relative to the build root (where logs live) for # brevity; fall back to the absolute path if it lies elsewhere. From 072a4474cae1d9ee18c0c76f18e8294ec6469e4a Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 08:55:49 -0500 Subject: [PATCH 61/71] Fix llvm-lit path rewrite sed escaping The post-install step rewrote ../../../ paths in the copied llvm-lit using a slash-delimited sed with hand-escaped slashes from $AOMP_REPOS. The escaping doubled the backslashes, producing an unescaped delimiter that aborted with "unknown option to 's'" on ordinary absolute paths. Switch to a '|' sed delimiter so the path slashes need no escaping, and drop the stray '-ie' backup suffix. --- bin/build_project.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bin/build_project.sh b/bin/build_project.sh index c1a14076ff..cedbf8be86 100755 --- a/bin/build_project.sh +++ b/bin/build_project.sh @@ -417,9 +417,11 @@ task_install() { # add executables forgot by make install but needed for testing $SUDO cp -p "$BuildDir/bin/llvm-lit" "$LLVM_INSTALL_LOC/bin/llvm-lit" - # update map_config and llvm_source_root paths in the copied llvm-lit file - SED_AOMP_REPOS=$(echo "$Repos" | sed -e 's/\//\\\\\//g') - sed -ie "s/..\/..\/..\//$SED_AOMP_REPOS\//g" "$LLVM_INSTALL_LOC/bin/llvm-lit" + # update map_config and llvm_source_root paths in the copied llvm-lit file. + # Use a sed delimiter ('|') that cannot occur in a path so the slashes in + # $Repos need no escaping (the old slash-escaping was buggy and broke on + # ordinary absolute paths). + sed -i "s|\.\./\.\./\.\./|$Repos/|g" "$LLVM_INSTALL_LOC/bin/llvm-lit" $SUDO cp -p "$BuildDir/bin/FileCheck" "$LLVM_INSTALL_LOC/bin/FileCheck" $SUDO cp -p "$BuildDir/bin/count" "$LLVM_INSTALL_LOC/bin/count" From 5812538dc689faa9739286bc6b7c4ba85bb9ed89 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 10:19:30 -0500 Subject: [PATCH 62/71] Add task completion stamps and bare 'continue' Each task records a .start stamp when it begins and a .done stamp on success, under a stamps/ dir beside the logs. 'list' shows a green check for completed tasks and a red cross for started-but-unfinished ones. Bare 'continue' resumes from the first task that is not marked done through to the end. Any run clears stamps from the lowest selected task index onward, so a full build resets all stamps and a subset/continue resets that point onward. --- bin/AOMP_BUILD.md | 30 +++++++++++++++- bin/aomp_build.py | 91 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 115 insertions(+), 6 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index 8033959ba6..40a2f53ded 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -114,7 +114,7 @@ aomp_build.py [options] [selector ...] | Option | Description | |--------|-------------| -| `list` (selector) | Print the numbered task list and exit. | +| `list` (selector) | Print the numbered task list and exit (`[NNN] [✓] component/stage`; the tick marks completed tasks, see [Completion stamps](#completion-stamps)). | | `--components` | Print the resolved, dependency-ordered component list and exit. | | `-n`, `--dry-run` | Show what would run (command + log path per task) without executing. | | `--export-manifest [FILE]` | Write a git fingerprint manifest and exit. Default path: `/manifests/-manifest.json`. | @@ -223,6 +223,7 @@ run. The grammar mirrors `amd-build`: | `N` | Run task number `N` (1-based, as shown by `list`). | | `N--M` | Run the inclusive range of tasks `N` through `M`. | | `comp/variant/stage` | Glob/substring match on task names; supports `{a,b}` brace expansion. | +| `continue` | On its own, resume from the first task that is not marked complete (see [Completion stamps](#completion-stamps)) through to the end. | | `... X continue` | Trailing `continue` turns the preceding selector `X` into a "from `X` to the end" anchor. Any earlier selectors are selected normally. | Multiple selectors can be combined; the union of matched tasks runs in task @@ -424,6 +425,33 @@ On failure, the orchestrator prints the failing task and tails the log to stderr, then stops (non-zero exit). Re-run with ` continue` after fixing the problem. +### Completion stamps + +Each task records its progress with two stamp files in a `stamps/` directory +alongside the log dir (e.g. `/stamps/`): + +- `component-stage.start` — written when the task begins, and +- `component-stage.done` — written when it finishes successfully. + +The `list` selector reflects this with a colored mark: + +| Mark | Meaning | Stamps | +|------|---------|--------| +| green `✓` | completed | `.done` present | +| red `✗` | started but did not finish (failed/interrupted) | `.start` only | +| (blank) | not built | neither | + +``` +[005] [✓] project/cmake +[006] [✗] project/build +[007] [ ] project/install +``` + +**Clearing.** Any run clears the stamps for every task from the lowest task +index being run through to the end, *before* executing. So a full build (no +selector) resets all stamps, and running a subset or `continue` resets that +point onward. Deleting the `stamps/` directory also resets everything. + --- ## User workflows diff --git a/bin/aomp_build.py b/bin/aomp_build.py index 66f41bb487..184ce88b8b 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -515,14 +515,63 @@ def tail_file(path: str, n: int = 40) -> str: return "".join(lines[-n:]) +def stamp_path(stamp_dir: str, task: Task, kind: str) -> str: + """Path of a task's stamp file (keyed by its stable name). kind is one of + 'start' (written when the task begins) or 'done' (written on success).""" + return os.path.join(stamp_dir, task.name.replace("/", "-") + "." + kind) + + +def task_state(stamp_dir: str | None, task: Task) -> str: + """Completion state inferred from the stamps: + + 'done' -> the task finished (a 'done' stamp is present) + 'incomplete' -> it started but did not finish ('start' only) + 'none' -> no stamp at all + """ + if not stamp_dir: + return "none" + if os.path.exists(stamp_path(stamp_dir, task, "done")): + return "done" + if os.path.exists(stamp_path(stamp_dir, task, "start")): + return "incomplete" + return "none" + + +def render_mark(state: str) -> str: + """A mark for a task state: green check (done), red cross (incomplete), + or a blank of the same width (none).""" + tty = sys.stdout.isatty() + if state == "done": + return "\033[32m\u2713\033[0m" if tty else "\u2713" + if state == "incomplete": + return "\033[31m\u2717\033[0m" if tty else "\u2717" + return " " + + +def clear_stamps_from(stamp_dir: str, tasks: list[Task], start_index: int) -> None: + """Remove both stamps for every task at index >= start_index.""" + for task in tasks[start_index:]: + for kind in ("start", "done"): + try: + os.remove(stamp_path(stamp_dir, task, kind)) + except FileNotFoundError: + pass + + def run_tasks( tasks: list[Task], indices: list[int], env: dict[str, str], log_dir: str, dry_run: bool, build_type_global: str | None = None, build_type_per_comp: dict[str, str] | None = None, - log_base: str | None = None, + log_base: str | None = None, stamp_dir: str | None = None, ) -> int: build_type_per_comp = build_type_per_comp or {} os.makedirs(log_dir, exist_ok=True) + # Any run clears stamps from the lowest task index onward (a full run thus + # resets everything), so the stamps reflect only the current build attempt. + if stamp_dir and not dry_run: + os.makedirs(stamp_dir, exist_ok=True) + if indices: + clear_stamps_from(stamp_dir, tasks, min(indices)) # The progress counter is relative to the whole build: num is the task's # absolute position (1-based) in the full elaborated task list and total is # the full count, so a selected subset still reports its real task numbers. @@ -554,6 +603,12 @@ def run_tasks( continue print(f"{header}{bt_note} -> {rel_log}", flush=True) start = datetime.datetime.now() + # Mark the task as started (start stamp without a done stamp == an + # incomplete/failed build until the done stamp is written below). + if stamp_dir: + with open(stamp_path(stamp_dir, task, "start"), "w", + encoding="utf-8") as st: + st.write(start.isoformat() + "\n") with open(log_path, "w", encoding="utf-8") as log: log.write(f"### task {num}: {task.name}\n") log.write(f"### command: {' '.join(cmd)}\n") @@ -574,6 +629,11 @@ def run_tasks( print(f"--- tail of {log_path} ---", file=sys.stderr) print(tail_file(log_path), file=sys.stderr) return proc.returncode + # Mark the task complete. + if stamp_dir: + with open(stamp_path(stamp_dir, task, "done"), "w", + encoding="utf-8") as st: + st.write(end.isoformat() + "\n") return 0 @@ -789,10 +849,15 @@ def build_arg_parser() -> argparse.ArgumentParser: " N--M run the inclusive range of tasks N..M\n" " comp/variant/stage glob/substring match (supports {a,b} braces);\n" " config-less init/fini tasks are comp/stage\n" + " continue on its own, resume from the first task not marked\n" + " complete (by its stamp) through to the end\n" " ... X continue trailing 'continue' makes the preceding selector\n" " X a 'from X to the end' anchor, e.g.\n" " 'comp1 comp2 continue' builds comp1 then continues\n" " from comp2 onward\n" + "\n" + "Any run clears completion stamps from the lowest selected task\n" + "onward; 'list' shows a green check (done) or red cross (incomplete).\n" ), ) parser.add_argument("selectors", nargs="*", help="task selector(s); see below") @@ -895,6 +960,8 @@ def main(argv: list[str]) -> int: build_dir = env_info["BUILD_DIR"] log_dir = args.log_dir or os.path.join(build_dir, "aomp_build_logs") + # Completion stamps live alongside the log dir. + stamp_dir = os.path.join(os.path.dirname(os.path.abspath(log_dir)), "stamps") manifest_dir = os.path.join(build_dir, "manifests") # Manifest export is a standalone action. @@ -918,14 +985,28 @@ def main(argv: list[str]) -> int: include_clean=args.clean, ) - # `list` selector: print the numbered task list and exit. + # `list` selector: print the numbered task list and exit. A green check + # marks completed tasks, a red cross marks started-but-unfinished ones. if args.selectors and args.selectors[0] == "list": width = len(str(len(tasks))) for i, task in enumerate(tasks, start=1): - print(f"{i:>{width}} {task.name}") + mark = render_mark(task_state(stamp_dir, task)) + print(f"[{i:0{width}d}] [{mark}] {task.name}") return 0 - indices = select_tasks(tasks, args.selectors) + # Bare `continue`: resume from the first task that is not yet done. + if args.selectors == ["continue"]: + resume = next( + (i for i, t in enumerate(tasks) + if task_state(stamp_dir, t) != "done"), + None, + ) + if resume is None: + print("aomp_build: all tasks already complete") + return 0 + indices = list(range(resume, len(tasks))) + else: + indices = select_tasks(tasks, args.selectors) if not indices: print("aomp_build: no tasks selected") return 0 @@ -934,7 +1015,7 @@ def main(argv: list[str]) -> int: tasks, indices, child_env, log_dir, args.dry_run, build_type_global=build_type_global, build_type_per_comp=build_type_per_comp, - log_base=build_dir, + log_base=build_dir, stamp_dir=stamp_dir, ) From fd0702e88f032a372ae38719d56904ba69605801 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 10:55:33 -0500 Subject: [PATCH 63/71] Make -C wipe the install dir; always list clean tasks -C/--clean now prepends an 'install/clean' pseudo-task that wipes the versioned install dir (the symlink target) and drops the symlink, rather than gating the per-component clean tasks. Per-component 'clean' tasks are now always elaborated (before each cmake) and run unconditionally. --- bin/AOMP_BUILD.md | 16 +++++--- bin/aomp_build.py | 95 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 90 insertions(+), 21 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index 40a2f53ded..9ac73104af 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -88,7 +88,7 @@ cd $AOMP_REPOS/aomp/bin | **Component** | A buildable unit with a `build_.sh` script (e.g. `project`, `comgr`, `flang`, `rocBLAS`). | | **Feature** | A named alias expanding to a set of components (e.g. `flang`, `rocmlibs`), used by `--add`/`--remove`. | | **Config / variant** | A build configuration a component advertises (e.g. `default`, `asan`, `perf`, `debug`, `*-devicertl`). | -| **Task** | A single step of a component build: `precheck`, `patch`, `clean`, `cmake`, `build`, `install`, `postinstall`, `unpatch`. | +| **Task** | A single step of a component build: `precheck`, `patch`, `clean`, `cmake`, `build`, `install`, `postinstall`, `unpatch`. A `clean` task wipes that component's build dir and is listed right before its `cmake`. | | **Request** | The default set of components to build, declared in the config's `request:` stanza. | | **Selector** | A positional argument that picks which elaborated tasks to run. | @@ -128,7 +128,7 @@ aomp_build.py [options] [selector ...] | `--add NAMES` | Add component(s) or feature(s). Comma-separated and/or repeatable. | | `--remove NAMES` | Remove component(s) or feature(s) (cascades to dependents). Comma-separated and/or repeatable. | | `--variant SPEC` | Variant filter: `cfg` (global) or `comp=cfg` (per-component). Comma-separated and/or repeatable. `default` is always built when offered (so `--variant debug` = default+debug); components offering neither are skipped (so `--variant default` skips the runtimes). See [Build variants](#build-variants). | -| `-C`, `--clean` | Include `clean` tasks (skipped by default for incremental builds). | +| `-C`, `--clean` | Prepend an `install/clean` task that wipes the install directory — the versioned symlink *target* (`AOMP_INSTALL_DIR`), then the symlink itself — before building. Per-component `clean` tasks (build dirs) are always listed and run like any other task. | ### Directory layout (exported to child build scripts) @@ -474,8 +474,9 @@ cd $AOMP_REPOS/aomp/bin ### Rebuild a single component ```bash -./aomp_build.py 'comgr/*' # all comgr tasks (incremental: no clean) -./aomp_build.py -C 'comgr/*' # force a clean rebuild of comgr +./aomp_build.py 'comgr/*' # all comgr tasks (includes its clean) +./aomp_build.py comgr/default/cmake continue # reconfigure comgr, then onward +./aomp_build.py -C # wipe the install dir, then full build ./aomp_build.py comgr/default/build # just re-run comgr's build step ``` @@ -629,7 +630,12 @@ component list: 3. Query `list`; parse each `task_ [cfg]` line. 4. Keep a task if either it has no config (init/fini tasks such as `precheck`, `patch`, `unpatch` always run) or its config is in the selected set. -5. Drop `clean` tasks unless `-C/--clean` was given (incremental by default). + +`clean` tasks (which wipe a component's build dir) are kept like any other +task — they sit right before each `cmake`. With `-C/--clean`, a single +`install/clean` pseudo-task is prepended to the whole list; it wipes the +install directory (the versioned symlink target, then the symlink) and is run +by the orchestrator itself (no backing script). Each surviving task is recorded as a `Task` (component, action, config, script path, and the exact `script_args` to pass back). Its display name is diff --git a/bin/aomp_build.py b/bin/aomp_build.py index 184ce88b8b..ed8f34a34e 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -269,17 +269,22 @@ def discover_env(env: dict[str, str] | None = None) -> dict[str, str]: snippet = ( f'. "{BIN_DIR}/aomp_utils" >/dev/null 2>&1; ' f'. "{BIN_DIR}/aomp_common_vars" >/dev/null 2>&1; ' - 'printf "%s\\n" "$BUILD_DIR" "$AOMP_REPOS" "$AOMP_REPO_NAME"' + 'printf "%s\\n" "$BUILD_DIR" "$AOMP_REPOS" "$AOMP_REPO_NAME" ' + '"$AOMP_INSTALL_DIR" "$AOMP"' ) proc = subprocess.run( ["bash", "-c", snippet], capture_output=True, text=True, env=env ) out = proc.stdout.splitlines() - out += [""] * (3 - len(out)) + out += [""] * (5 - len(out)) return { "BUILD_DIR": out[0] or os.path.join(os.path.expanduser("~"), "git", "aomp"), "AOMP_REPOS": out[1] or os.path.join(os.path.expanduser("~"), "git", "aomp"), "AOMP_REPO_NAME": out[2] or "aomp", + # The versioned install dir (the real target the scripts symlink to) and + # the symlink itself; used by -C/--clean to wipe a stale installation. + "AOMP_INSTALL_DIR": out[3], + "AOMP": out[4], } @@ -294,6 +299,11 @@ class Task: script: str # path to build_.sh script_args: list[str] # args to pass back to the script single_config: bool = False # component advertises only "default" + # Builtin (orchestrator-run) tasks have no backing script. Currently only + # "install_clean": wipe the install dir. `targets` then holds the paths it + # operates on ([install_dir, symlink]). + builtin: str | None = None + targets: list[str] = field(default_factory=list) @property def name(self) -> str: @@ -355,7 +365,6 @@ def select_variants( def elaborate_tasks( cfg: Config, components: list[str], env: dict[str, str], global_variants: list[str], per_comp_variants: dict[str, list[str]], - include_clean: bool, ) -> list[Task]: tasks: list[Task] = [] for comp in components: @@ -387,8 +396,6 @@ def elaborate_tasks( # config-less tasks (init/fini such as patch/unpatch) always run. if taskcfg is not None and taskcfg not in wanted: continue - if action == "clean" and not include_clean: - continue tasks.append( Task( comp=comp, @@ -558,6 +565,49 @@ def clear_stamps_from(stamp_dir: str, tasks: list[Task], start_index: int) -> No pass +def make_install_clean_task(env_info: dict[str, str]) -> Task: + """The -C/--clean pseudo-task: wipe the install directory (the versioned + symlink *target*, not just the symlink). Inserted at the front of the task + list so a stale/partially-installed tree is removed before anything builds. + """ + install_dir = env_info.get("AOMP_INSTALL_DIR", "") + symlink = env_info.get("AOMP", "") + return Task( + comp="install", action="clean", cfgname=None, + script="", script_args=[], single_config=True, + builtin="install_clean", targets=[install_dir, symlink], + ) + + +def run_install_clean(targets: list[str], env: dict[str, str], log) -> int: + """Wipe the install dir (targets[0]) and drop the symlink (targets[1]) if it + is a distinct symlink. Honors SUDO (the install may be root-owned).""" + install_dir = targets[0] if targets else "" + symlink = targets[1] if len(targets) > 1 else "" + + abs_install = os.path.abspath(install_dir) if install_dir else "" + if not abs_install or abs_install in ("/", os.path.abspath(os.path.expanduser("~"))): + log.write(f"ERROR: refusing to wipe unsafe install dir '{install_dir}'\n") + log.flush() + return 1 + + sudo = env.get("SUDO", "") + prefix = ["sudo"] if sudo in ("set", "yes", "YES") else [] + + def run(cmd: list[str]) -> int: + log.write(" ".join(cmd) + "\n") + log.flush() + return subprocess.run( + cmd, stdout=log, stderr=subprocess.STDOUT, env=env + ).returncode + + rc = run(prefix + ["rm", "-rf", "--", install_dir]) + # If the symlink is distinct from the target, remove the dangling link too. + if rc == 0 and symlink and symlink != install_dir and os.path.islink(symlink): + rc = run(prefix + ["rm", "-f", "--", symlink]) + return rc + + def run_tasks( tasks: list[Task], indices: list[int], env: dict[str, str], log_dir: str, dry_run: bool, build_type_global: str | None = None, @@ -582,7 +632,10 @@ def run_tasks( num = idx + 1 safe = task.name.replace("/", "-") log_path = os.path.join(log_dir, f"{num:03d}-{safe}.log") - cmd = ["bash", task.script, *task.script_args] + if task.builtin == "install_clean": + cmd = ["rm", "-rf", *(t for t in task.targets if t)] + else: + cmd = ["bash", task.script, *task.script_args] # Per-component BUILD_TYPE override (per-component wins over global). build_type = build_type_per_comp.get(task.comp, build_type_global) task_env = env @@ -616,19 +669,22 @@ def run_tasks( log.write(f"### env: BUILD_TYPE={build_type}\n") log.write(f"### start: {start.isoformat()}\n\n") log.flush() - proc = subprocess.run( - cmd, stdout=log, stderr=subprocess.STDOUT, env=task_env - ) + if task.builtin == "install_clean": + rc = run_install_clean(task.targets, task_env, log) + else: + rc = subprocess.run( + cmd, stdout=log, stderr=subprocess.STDOUT, env=task_env + ).returncode end = datetime.datetime.now() - log.write(f"\n### end: {end.isoformat()} (rc={proc.returncode})\n") - if proc.returncode != 0: + log.write(f"\n### end: {end.isoformat()} (rc={rc})\n") + if rc != 0: print( - f"\naomp_build: FAILED task {num} ({task.name}), rc={proc.returncode}", + f"\naomp_build: FAILED task {num} ({task.name}), rc={rc}", file=sys.stderr, ) print(f"--- tail of {log_path} ---", file=sys.stderr) print(tail_file(log_path), file=sys.stderr) - return proc.returncode + return rc # Mark the task complete. if stamp_dir: with open(stamp_path(stamp_dir, task, "done"), "w", @@ -895,8 +951,11 @@ def build_arg_parser() -> argparse.ArgumentParser: "the runtimes). With no --variant, all advertised " "configs are built.") parser.add_argument("-C", "--clean", action="store_true", - help="include 'clean' tasks (default: skip for " - "incremental builds)") + help="prepend an 'install/clean' task that wipes the " + "install directory (the versioned symlink target, " + "not just the symlink) before building. Per-" + "component 'clean' tasks (build dirs) are always " + "listed and run like any other task.") parser.add_argument("-n", "--dry-run", action="store_true", help="show what would run without executing") parser.add_argument("--components", action="store_true", @@ -982,8 +1041,12 @@ def main(argv: list[str]) -> int: build_type_global, build_type_per_comp = parse_build_type_specs(args.build_type) tasks = elaborate_tasks( cfg, components, child_env, global_variants, per_comp_variants, - include_clean=args.clean, ) + # -C/--clean prepends a pseudo-task that wipes the install directory so a + # stale install is removed before anything builds. Per-component build-dir + # "clean" tasks are always in the list and run like any other task. + if args.clean: + tasks.insert(0, make_install_clean_task(env_info)) # `list` selector: print the numbered task list and exit. A green check # marks completed tasks, a red cross marks started-but-unfinished ones. From d12c4bb87f3679da2b852f9f6d5796741fa55edb Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 11:01:00 -0500 Subject: [PATCH 64/71] Default ALTAOMP to LLVM_INSTALL_LOC in runtimes build build_llvm_runtimes_standalone.sh read ALTAOMP without a default, so an unset ALTAOMP made CMAKE_C_COMPILER collapse to /bin/clang and cmake failed. Fall back to the just-installed compiler (LLVM_INSTALL_LOC), as build_openmp.sh and build_offload.sh already do. --- bin/build_llvm_runtimes_standalone.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/build_llvm_runtimes_standalone.sh b/bin/build_llvm_runtimes_standalone.sh index c4edc4a44a..68e219b5f1 100755 --- a/bin/build_llvm_runtimes_standalone.sh +++ b/bin/build_llvm_runtimes_standalone.sh @@ -252,6 +252,9 @@ task_cmake() { UseNinja="$(cfgbool AOMP_USE_NINJA)" Standalone="$(cfgbool AOMP_STANDALONE_BUILD)" Altaomp="$(cfgvar ALTAOMP)" + # Build the runtimes with the just-installed AOMP compiler by default (same + # as build_openmp.sh/build_offload.sh); an explicit ALTAOMP still wins. + Altaomp="${Altaomp:-$LLVM_INSTALL_LOC}" if "$UseNinja"; then AOMP_SET_NINJA_GEN=(-G Ninja) From f8386276ddb3424eef0d131f995274e5b95da067 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 11:07:32 -0500 Subject: [PATCH 65/71] Fix gpurun copy in build_extras for upstream dir restructure offload/utils/gpurun is now a directory (script + CMakeLists), so the plain cp failed with "-r not specified". Copy the gpurun script out of the directory so it still lands as build/extras/gpurun. --- bin/build_extras.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/build_extras.sh b/bin/build_extras.sh index 79ce1595d6..a36c2d69a8 100755 --- a/bin/build_extras.sh +++ b/bin/build_extras.sh @@ -136,7 +136,10 @@ task_build() { echo "----- Copy util scripts to $BuildDir -----" cp "$SrcDir"/utils/* "$BuildDir" - cp "$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROJECT_REPO_NAME)"/offload/utils/gpurun "$BuildDir" + # gpurun was restructured upstream from a single file into a directory + # (offload/utils/gpurun/) holding the script plus its CMakeLists; copy the + # script itself out of it. + cp "$(cfgvar AOMP_REPOS)/$(cfgvar AOMP_PROJECT_REPO_NAME)"/offload/utils/gpurun/gpurun "$BuildDir" for util in $install_list; do if [ "$util" == "rebundle_hip_lib.sh" ]; then From 0ad2ae2ab6a24e6bc3ab2a657e5f8230fa3b60c4 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 12:05:55 -0500 Subject: [PATCH 66/71] Fix rocBLAS patch step for rocm-7.1 sources build_rocBLAS.sh unconditionally cat'd rocBLAS/tensile_tag.txt to pin the Tensile commit, but that file is deprecated/removed in rocBLAS rocm-7.1; guard on its existence and otherwise build the checked-out Tensile. Also add the missing rocmlibs patch-control-file_23.0.txt (mirrors 22.0); all referenced patches were verified to apply cleanly to the 7.1 sources. --- bin/rocmlibs/build_rocBLAS.sh | 16 ++++++++++++---- bin/rocmlibs/patches/patch-control-file_23.0.txt | 8 ++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 bin/rocmlibs/patches/patch-control-file_23.0.txt diff --git a/bin/rocmlibs/build_rocBLAS.sh b/bin/rocmlibs/build_rocBLAS.sh index 118959487d..2db989f563 100755 --- a/bin/rocmlibs/build_rocBLAS.sh +++ b/bin/rocmlibs/build_rocBLAS.sh @@ -97,12 +97,20 @@ task_precheck() { task_patch() { local _tensile_commit_sha + local _tensile_tag_file="$_repo_dir/tensile_tag.txt" if "$(cfgbool AOMP_BUILD_TENSILE)"; then cd "$_tensile_repo_dir" || exit - # Read the commit SHA from the file rocBLAS/tensile_tag.txt - _tensile_commit_sha=$(cat "$_repo_dir/tensile_tag.txt") - echo "Checking out Tensile commit $_tensile_commit_sha" - git checkout "$_tensile_commit_sha" + # rocBLAS historically pinned the Tensile commit in rocBLAS/tensile_tag.txt. + # That file is deprecated and removed in recent rocBLAS (>= rocm 7.1); when + # it is absent, build against the Tensile revision the manifest already + # checked out rather than failing on a missing file. + if [ -f "$_tensile_tag_file" ]; then + _tensile_commit_sha=$(cat "$_tensile_tag_file") + echo "Checking out Tensile commit $_tensile_commit_sha" + git checkout "$_tensile_commit_sha" + else + echo "No $_tensile_tag_file (deprecated); using checked-out Tensile revision $(git rev-parse --short HEAD)" + fi patchrepo "$_tensile_repo_dir" fi patchrepo "$_repo_dir" diff --git a/bin/rocmlibs/patches/patch-control-file_23.0.txt b/bin/rocmlibs/patches/patch-control-file_23.0.txt new file mode 100644 index 0000000000..020af96a0d --- /dev/null +++ b/bin/rocmlibs/patches/patch-control-file_23.0.txt @@ -0,0 +1,8 @@ +Tensile: tensile.patch +rocBLAS: rocblas.patch +rocPRIM: rocprim.patch +rocSPARSE: rocsparse.patch +rocSOLVER: rocsolver.patch +hipBLAS: hipblas.patch +rccl: rccl.patch +PowerInfer: powerinfer.patch From 0ede58afa137097ad51eac8c52291266083a41cd Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Wed, 17 Jun 2026 12:31:01 -0500 Subject: [PATCH 67/71] Fix hipRAND CMAKE_CXX_FLAGS separator (semicolon -> space) The two flags in CMAKE_CXX_FLAGS were joined with ';', which CMake treats as a list separator, breaking the compile line so the shell tried to run '-D__HIP_PLATFORM_AMD__=1' as a command. Use a space, matching rocRAND and the other rocmlibs scripts. --- bin/rocmlibs/build_hipRAND.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/rocmlibs/build_hipRAND.sh b/bin/rocmlibs/build_hipRAND.sh index 9a09caeac4..809cdcf136 100755 --- a/bin/rocmlibs/build_hipRAND.sh +++ b/bin/rocmlibs/build_hipRAND.sh @@ -111,7 +111,7 @@ task_cmake() { setup_env MYCMAKEOPTS=(-DCMAKE_CXX_COMPILER="$CXX" - -DCMAKE_CXX_FLAGS="-I$LLVM_INSTALL_LOC/include;-D__HIP_PLATFORM_AMD__=1" + -DCMAKE_CXX_FLAGS="-I$LLVM_INSTALL_LOC/include -D__HIP_PLATFORM_AMD__=1" -DROCM_DIR="$AOMP_INSTALL_DIR" -DBUILD_FORTRAN_WRAPPER=ON -DROCM_PATH="$AOMP_INSTALL_DIR" From 5e00df6c157de1889006ff18837affb9644fd4ae Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Thu, 18 Jun 2026 05:30:17 -0500 Subject: [PATCH 68/71] Add hipfort to default build set and fix its flang dependency hipfort was defined but omitted from the default request: stanza, so aomp_build.py builds did not include it (unlike build_aomp.sh). Add it to the default install list. Also fix hipfort's declared dependency: it was depends: hipamd, flang_runtime, where flang_runtime is the deprecated classic Flang runtime. That caused --add hipfort to drag in the entire classic Flang stack (llvm-classic, flang-classic, pgmath, flang, flang_runtime). build_hipfort.sh actually compiles with the modern LLVM flang ($LLVM_INSTALL_LOC/bin/flang from the project build), so depend on hipamd, project instead. The resolved default set now matches the legacy shell build with no classic Flang components. --- bin/configs/aomp.cudf | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/configs/aomp.cudf b/bin/configs/aomp.cudf index 354d10cdf2..060a6455a9 100644 --- a/bin/configs/aomp.cudf +++ b/bin/configs/aomp.cudf @@ -130,7 +130,10 @@ x-dir: . package: hipfort version: 1 -depends: hipamd, flang_runtime +# hipfort builds with the modern LLVM flang (project) and HIP (hipamd); it does +# not need the deprecated classic flang_runtime stack (build_hipfort.sh uses +# $LLVM_INSTALL_LOC/bin/flang). +depends: hipamd, project x-dir: . package: rocdbgapi @@ -243,10 +246,10 @@ expands: rocm-cmake, rocBLAS, rocPRIM, rocSPARSE, rocSOLVER, hipBLAS-common, # Default requested build set: the standalone x86_64 AOMP build from # build_aomp.sh, omitting the deprecated classic Flang stack (llvm-classic, # flang-classic, pgmath, flang, flang_runtime; re-add with --add flang) and the -# optional debug/hipfort components and rocmlibs. Modify with --add / --remove. +# optional debug components and rocmlibs. Modify with --add / --remove. #----------------------------------------------------------------------------- request: install: prereq, project, rocprofiler-register, rocr, llvm_runtimes_standalone, extras, comgr, rocminfo, rocm_smi_lib, amdsmi, hipcc, hipamd, hipify, - rocprofiler-sdk + hipfort, rocprofiler-sdk From 4c8640ee148628fe5cc22aa0ec61e40e98a28810 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Thu, 18 Jun 2026 06:09:55 -0500 Subject: [PATCH 69/71] Manifest: record all repos (LLVM/comgr/SPIRV) and keep extras at HEAD Several components were missing from the manifest because git_facts() required .git directly inside the source dir. The LLVM project, comgr, hipcc and llvm_runtimes_standalone all build from subdirectories of the single llvm-project checkout, so all four (LLVM being the largest) were silently dropped. - Resolve the enclosing repository via `git rev-parse --show-toplevel` so subdir sources are recorded, and add a "subdir" field (via the symlink-safe --show-prefix) identifying the build subtree. - Add an "externals" manifest section for repos pulled into a build but not standalone components; record SPIRV-LLVM-Translator there. LLVM, comgr and the SPIRV translator are tightly coupled and a frequent source of build breakage, so their exact versions are now captured. - On import, restore externals too and dedupe components that share the llvm-project checkout so it is moved only once. - Keep the "extras" component (the AOMP build-scripts repo) at HEAD on import instead of rolling it back; its dirty state no longer blocks the import. The scripts are meant to build arbitrary AOMP/ROCm versions, so pinning them would change the build logic mid-flight. Docs (AOMP_BUILD.md) updated to describe subdir/externals and the floating extras behavior. --- bin/AOMP_BUILD.md | 41 +++++++++++++-- bin/aomp_build.py | 127 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 139 insertions(+), 29 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index 9ac73104af..e5c1447465 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -118,7 +118,7 @@ aomp_build.py [options] [selector ...] | `--components` | Print the resolved, dependency-ordered component list and exit. | | `-n`, `--dry-run` | Show what would run (command + log path per task) without executing. | | `--export-manifest [FILE]` | Write a git fingerprint manifest and exit. Default path: `/manifests/-manifest.json`. | -| `--import-manifest FILE` | Check out recorded git SHAs before building (refuses if any repo is dirty). | +| `--import-manifest FILE` | Check out recorded git SHAs before building (refuses if any repo is dirty; `extras` is kept at HEAD). | ### Component selection @@ -382,22 +382,57 @@ The JSON records, per component that has a git source: "sha": "…", "repo": "https://github.com/…", "branch": "amd-staging", + "dirty": false, + "subdir": "llvm" + }, + "comgr": { + "sha": "…", + "repo": "https://github.com/…", + "branch": "amd-staging", + "dirty": false, + "subdir": "amd/comgr" + } + }, + "externals": { + "SPIRV-LLVM-Translator": { + "sha": "…", + "repo": "https://github.com/…", + "branch": "amd-staging-npi", "dirty": false } } } ``` +- The git fingerprint is taken from the repository that **contains** a + component's source, so components that build from a subdirectory of a shared + checkout are all recorded. The LLVM `project`, `comgr`, `hipcc` and + `llvm_runtimes_standalone` all live in the single `llvm-project` repo (same + `sha`/`branch`), distinguished by their `subdir` (`llvm`, `amd/comgr`, + `amd/hipcc`, `runtimes`). +- `externals` records repos that are pulled into a component build but are not + standalone components (e.g. `SPIRV-LLVM-Translator`, consumed by the LLVM + build via `LLVM_EXTERNAL_PROJECTS`). These are tightly coupled to the + LLVM/comgr toolchain and a frequent source of build breakage, so their exact + versions are worth recording alongside LLVM and comgr. + Import (a pre-step before building): ```bash ./aomp_build.py --import-manifest m.json [selectors...] ``` -- For each component in the manifest that is also in the resolved set, the - recorded SHA is checked out (`git checkout `). +- For each component in the manifest that is also in the resolved set (plus the + recorded `externals`), the recorded SHA is checked out (`git checkout `). + Components that share a repository (the `llvm-project` family) are deduped, so + the shared checkout is moved once. +- **`extras` stays at HEAD.** The `extras` component is the AOMP build-scripts + repo (this tree); it is never rolled back, since the scripts are meant to + build arbitrary AOMP/ROCm versions and pinning them would change the build + logic mid-flight. - **Safety:** if any target repo has local modifications, the import is **refused** entirely (nothing is checked out) and the dirty repos are listed. + `extras` being dirty does not block the import. - Components without a git source (e.g. `prereq`) are skipped. Manifests live under `/manifests/` by default diff --git a/bin/aomp_build.py b/bin/aomp_build.py index ed8f34a34e..5559ee806b 100755 --- a/bin/aomp_build.py +++ b/bin/aomp_build.py @@ -696,22 +696,62 @@ def run_tasks( # --------------------------------------------------------------------------- # # Version manifest (git fingerprint) # --------------------------------------------------------------------------- # +# Repositories consumed by component builds (e.g. via LLVM_EXTERNAL_PROJECTS) +# that are not standalone components. Paths are relative to AOMP_REPOS. These +# are recorded under the manifest "externals" section and restored on import +# because they are tightly coupled to the LLVM/comgr toolchain and are a +# frequent source of build breakage, so their exact versions matter. +EXTERNAL_REPOS = { + "SPIRV-LLVM-Translator": "SPIRV-LLVM-Translator", +} + +# Components whose source must never be rolled back on import: their checkout +# is meant to track HEAD. "extras" is the AOMP build-scripts repo (this very +# tree) -- pinning it would change the build logic mid-flight, and the scripts +# are intended to (eventually) build arbitrary AOMP/ROCm versions. +FLOATING_COMPONENTS = {"extras"} + + +def _git(src: str, *args: str) -> str: + proc = subprocess.run( + ["git", "-C", src, *args], capture_output=True, text=True + ) + return proc.stdout.strip() if proc.returncode == 0 else "" + + +def git_toplevel(src: str) -> str: + """Absolute path of the git repository containing `src` (or "").""" + if not src or not os.path.isdir(src): + return "" + return _git(src, "rev-parse", "--show-toplevel") + + def git_facts(src: str) -> dict | None: - if not src or not os.path.isdir(os.path.join(src, ".git")): - return None + """Git fingerprint of the repository containing `src`. - def git(*args: str) -> str: - proc = subprocess.run( - ["git", "-C", src, *args], capture_output=True, text=True - ) - return proc.stdout.strip() if proc.returncode == 0 else "" + `src` may be a subdirectory of its repository: the LLVM project, comgr, + hipcc and the standalone runtimes all build from different subdirs of the + single llvm-project checkout. We resolve the enclosing repository root via + `git rev-parse --show-toplevel` so each such component is recorded, and + note the build subdir (relative to that root) when it is not the root. + """ + top = git_toplevel(src) + if not top: + return None - return { - "sha": git("rev-parse", "HEAD"), - "repo": git("config", "--get", "remote.origin.url"), - "branch": git("rev-parse", "--abbrev-ref", "HEAD"), - "dirty": bool(git("status", "--porcelain")), + facts = { + "sha": _git(src, "rev-parse", "HEAD"), + "repo": _git(src, "config", "--get", "remote.origin.url"), + "branch": _git(src, "rev-parse", "--abbrev-ref", "HEAD"), + "dirty": bool(_git(src, "status", "--porcelain")), } + # Build subdir relative to the repo root (handles src being a subdir of a + # shared repo, e.g. llvm-project/{llvm,amd/comgr,amd/hipcc,runtimes}). + # `--show-prefix` is symlink-safe, unlike relpath against --show-toplevel. + subdir = _git(src, "rev-parse", "--show-prefix").rstrip("/") + if subdir: + facts["subdir"] = subdir + return facts def component_src_dir(cfg: Config, comp: str, env: dict[str, str]) -> str: @@ -730,18 +770,28 @@ def export_manifest( "config": config_name, "order": components, "components": {}, + "externals": {}, } for comp in components: src = component_src_dir(cfg, comp, env) facts = git_facts(src) if facts is not None: manifest["components"][comp] = facts + + # External (non-component) repos consumed by the LLVM/comgr toolchain. + repos = discover_env(env)["AOMP_REPOS"] + for name, rel in EXTERNAL_REPOS.items(): + facts = git_facts(os.path.join(repos, rel)) + if facts is not None: + manifest["externals"][name] = facts + os.makedirs(os.path.dirname(os.path.abspath(path)), exist_ok=True) with open(path, "w", encoding="utf-8") as handle: json.dump(manifest, handle, indent=2, sort_keys=True) handle.write("\n") print(f"aomp_build: wrote manifest for {len(manifest['components'])} " - f"component(s) to {path}") + f"component(s) and {len(manifest['externals'])} external repo(s) " + f"to {path}") def import_manifest( @@ -754,20 +804,45 @@ def import_manifest( sys.exit(f"aomp_build: cannot read manifest '{path}': {exc}") recorded = manifest.get("components", {}) - targets = [c for c in components if c in recorded] + recorded_ext = manifest.get("externals", {}) - # First pass: refuse if any target repo has local modifications. - plan: list[tuple[str, str, str]] = [] # (comp, src, sha) + # First pass: build a checkout plan and refuse if any target repo is dirty. + # Several components (project, comgr, hipcc, runtimes) share the single + # llvm-project checkout, so we dedupe by repository root to avoid repeated + # (and redundant) checkouts/dirty reports. + plan: list[tuple[str, str, str]] = [] # (label, src, sha) dirty: list[str] = [] - for comp in targets: - src = component_src_dir(cfg, comp, env) + seen_tops: set[str] = set() + + def schedule(label: str, src: str, sha: str) -> None: facts = git_facts(src) if facts is None: - print(f"aomp_build: skipping '{comp}' (no git source at {src})") - continue + print(f"aomp_build: skipping '{label}' (no git source at {src})") + return + top = git_toplevel(src) + if top in seen_tops: + return + seen_tops.add(top) if facts["dirty"]: - dirty.append(comp) - plan.append((comp, src, recorded[comp]["sha"])) + dirty.append(label) + plan.append((label, src, sha)) + + # Components, in build order. Floating components track HEAD and are never + # rolled back. + for comp in components: + if comp not in recorded: + continue + if comp in FLOATING_COMPONENTS: + print(f"aomp_build: keeping '{comp}' at HEAD (floating; not rolled back)") + continue + schedule(comp, component_src_dir(cfg, comp, env), recorded[comp]["sha"]) + + # External repos (e.g. SPIRV-LLVM-Translator). + repos = discover_env(env)["AOMP_REPOS"] + for name, rel in EXTERNAL_REPOS.items(): + if name not in recorded_ext: + continue + schedule(name, os.path.join(repos, rel), recorded_ext[name]["sha"]) if dirty: sys.exit( @@ -776,14 +851,14 @@ def import_manifest( ) # Second pass: check out recorded SHAs. - for comp, src, sha in plan: + for label, src, sha in plan: if not sha: - print(f"aomp_build: skipping '{comp}' (no recorded sha)") + print(f"aomp_build: skipping '{label}' (no recorded sha)") continue - print(f"aomp_build: checking out {comp} @ {sha[:12]} in {src}") + print(f"aomp_build: checking out {label} @ {sha[:12]} in {src}") proc = subprocess.run(["git", "-C", src, "checkout", sha]) if proc.returncode != 0: - sys.exit(f"aomp_build: git checkout failed for '{comp}'") + sys.exit(f"aomp_build: git checkout failed for '{label}'") return 0 From 1d9689bbaf2612a014ec52d6e564ffabe8b4fd9e Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Thu, 18 Jun 2026 08:44:18 -0500 Subject: [PATCH 70/71] Add ROCm debugger (rocdbgapi, rocgdb) to default build set build_aomp.sh builds the debugger by default (AOMP_BUILD_DEBUG defaults to 1), but the orchestrator's default request omitted the "debug" feature, so aomp_build.py builds were missing rocdbgapi and rocgdb (the only real difference left in a full-build audit). Add them to the default request, ordered as in build_aomp.sh (after hipfort, before rocprofiler-sdk). The resolved default set now matches the legacy shell build. Re-exclude with --remove rocgdb,rocdbgapi if not wanted. --- bin/configs/aomp.cudf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/configs/aomp.cudf b/bin/configs/aomp.cudf index 060a6455a9..e017ba5c2e 100644 --- a/bin/configs/aomp.cudf +++ b/bin/configs/aomp.cudf @@ -245,11 +245,11 @@ expands: rocm-cmake, rocBLAS, rocPRIM, rocSPARSE, rocSOLVER, hipBLAS-common, #----------------------------------------------------------------------------- # Default requested build set: the standalone x86_64 AOMP build from # build_aomp.sh, omitting the deprecated classic Flang stack (llvm-classic, -# flang-classic, pgmath, flang, flang_runtime; re-add with --add flang) and the -# optional debug components and rocmlibs. Modify with --add / --remove. +# flang-classic, pgmath, flang, flang_runtime; re-add with --add flang) and +# rocmlibs. Modify with --add / --remove. #----------------------------------------------------------------------------- request: install: prereq, project, rocprofiler-register, rocr, llvm_runtimes_standalone, extras, comgr, rocminfo, rocm_smi_lib, amdsmi, hipcc, hipamd, hipify, - hipfort, rocprofiler-sdk + hipfort, rocdbgapi, rocgdb, rocprofiler-sdk From c3dda560a4ded80026b2a70fb8faf43329fb588b Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Thu, 18 Jun 2026 08:47:21 -0500 Subject: [PATCH 71/71] docs: reflect hipfort and debugger in the default build set Update AOMP_BUILD.md now that hipfort and the debug feature (rocdbgapi, rocgdb) are part of the default request: the default-set description no longer lists them as omitted, the debug feature row notes it is in the default set, and the examples use --remove debug instead of --add debug. --- bin/AOMP_BUILD.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/bin/AOMP_BUILD.md b/bin/AOMP_BUILD.md index e5c1447465..e2a1122f79 100644 --- a/bin/AOMP_BUILD.md +++ b/bin/AOMP_BUILD.md @@ -324,10 +324,11 @@ Examples: ## Components and features The default component set is the `request:` stanza of the config — the -standalone x86_64 AOMP build from `build_aomp.sh`, **omitting the deprecated -classic Flang stack** (`llvm-classic`, `flang-classic`, `pgmath`, `flang`, -`flang_runtime`) as well as the optional debug/hipfort components and the ROCm -math libraries. Re-enable classic Flang with `--add flang`. +standalone x86_64 AOMP build from `build_aomp.sh` (including `hipfort` and the +`rocdbgapi`/`rocgdb` debugger), **omitting the deprecated classic Flang stack** +(`llvm-classic`, `flang-classic`, `pgmath`, `flang`, `flang_runtime`) and the +ROCm math libraries. Re-enable classic Flang with `--add flang` and the math +libraries with `--add rocmlibs`. Adjust it with `--add` / `--remove`, which accept **component** names or **feature** names. Each option is repeatable and also accepts a comma-separated @@ -338,7 +339,7 @@ equivalent. Features defined in the default config: |---------|-----------| | `flang` | `llvm-classic`, `flang-classic`, `pgmath`, `flang`, `flang_runtime` (deprecated classic Flang; not in the default set) | | `hip` | `hipcc`, `hipamd`, `hipify` | -| `debug` | `rocdbgapi`, `rocgdb` | +| `debug` | `rocdbgapi`, `rocgdb` (the ROCm debugger; in the default set — drop with `--remove debug`) | | `profiler` | `rocprofiler-register`, `rocprofiler-sdk` | | `rocmlibs` | `rocm-cmake`, `rocBLAS`, `rocPRIM`, `rocSPARSE`, `rocSOLVER`, `hipBLAS-common`, `hipBLAS`, `rocRAND`, `hipRAND`, `rccl`, `half`, `hipSOLVER` | @@ -350,10 +351,10 @@ Resolution rules: depends on them** (the removal cascades). ```bash -./aomp_build.py --add rocmlibs --components # core AOMP + ROCm libraries +./aomp_build.py --add rocmlibs --components # default set + ROCm math libraries ./aomp_build.py --remove flang --components # drop the whole Flang group -./aomp_build.py --add rocgdb --components # adds rocdbgapi too (dependency) -./aomp_build.py --add rocmlibs,debug --components # comma-separated list +./aomp_build.py --remove debug --components # drop the debugger (rocgdb + rocdbgapi) +./aomp_build.py --add rocmlibs --remove debug --components # combine adds and removes ``` --- @@ -529,9 +530,9 @@ with a trailing `continue`: ### Build extra component sets ```bash -./aomp_build.py --add rocmlibs # core AOMP + ROCm math libs +./aomp_build.py --add rocmlibs # default set + ROCm math libs ./aomp_build.py --add rocmlibs 'rocBLAS/*' # only rocBLAS tasks (deps still resolved) -./aomp_build.py --add debug # add rocdbgapi + rocgdb +./aomp_build.py --remove debug # drop the debugger (rocdbgapi + rocgdb) ``` ### Build a sanitizer / perf / debug variant