diff --git a/bin/clone_aomp.sh b/bin/clone_aomp.sh
index fefddbbef9..2d00cff059 100755
--- a/bin/clone_aomp.sh
+++ b/bin/clone_aomp.sh
@@ -218,26 +218,15 @@ if [[ "$AOMP_VERSION" == "13.1" ]] || [[ $AOMP_MAJOR_VERSION -gt 13 ]] ; then
# However, we gave up on using the repo command to clone the repos.
# That is all done here by parsing the manifest file.
- # According to git documentation this ssh command should return 1 if authentication is successful
- ssh -T $AOMP_GIT_INTERNAL_IP 2> /dev/null
- if [ $? == 1 ] && [ "$AOMP_EXTERNAL_MANIFEST" != 1 ]; then
- # AMD internal repo file
- if [ "$AOMP_NEW" == "1" ]; then
- manifest_file=$thisdir/../manifests/aompi_new_${AOMP_VERSION}.xml
- else
- manifest_file=$thisdir/../manifests/aompi_${AOMP_VERSION}.xml
- fi
+ abranch=$(git branch | awk '/\*/ { print $2; }')
+ # Use release manifest if on release branch
+ if [ "$abranch" == "aomp-${AOMP_VERSION_STRING}" ]; then
+ manifest_file=$thisdir/../manifests/aomp_${AOMP_VERSION_STRING}.xml
else
- abranch=$(git branch | awk '/\*/ { print $2; }')
- # Use release manifest if on release branch
- if [ "$abranch" == "aomp-${AOMP_VERSION_STRING}" ]; then
- manifest_file=$thisdir/../manifests/aomp_${AOMP_VERSION_STRING}.xml
+ if [ "$AOMP_NEW" == "1" ]; then
+ manifest_file=$thisdir/../manifests/aomp_new_${AOMP_VERSION}.xml
else
- if [ "$AOMP_NEW" == "1" ]; then
- manifest_file=$thisdir/../manifests/aomp_new_${AOMP_VERSION}.xml
- else
- manifest_file=$thisdir/../manifests/aomp_${AOMP_VERSION}.xml
- fi
+ manifest_file=$thisdir/../manifests/aomp_${AOMP_VERSION}.xml
fi
fi
echo "USED manifest file: $manifest_file"
diff --git a/bin/run_composable-kernels.sh b/bin/run_composable-kernels.sh
index 0184330f2c..574d17077e 100755
--- a/bin/run_composable-kernels.sh
+++ b/bin/run_composable-kernels.sh
@@ -282,7 +282,14 @@ if [ ! -d "${CK_TOP}" ]; then
mkdir -p "${CK_TOP}" || exit 1
fi
-if [ ! -d "${CK_REPO}" ]; then
+# Validate that CK_REPO is an actual git checkout, not just an existing
+# directory. Alola periodically wipes the *contents* of old node-local dirs
+# while leaving the directory shells behind, which yields a CK_REPO that
+# exists but has no .git (and no CMakeLists.txt), breaking the build. A plain
+# "-d" test would skip the clone and then fail. Re-clone when the tree is
+# missing or not a valid repo; only pull when it is a healthy checkout.
+if ! git -C "${CK_REPO}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
+ rm -rf "${CK_REPO}"
git clone --single-branch --depth 1 ${CKRepoURL} "${CK_REPO}"
elif [ "${ShouldUpdateCKRepo}" == 'yes' ]; then
pushd "${CK_REPO}" || exit 1
diff --git a/manifests/aomp_23.0.xml b/manifests/aomp_23.0.xml
index e0119381b2..656ab15466 100644
--- a/manifests/aomp_23.0.xml
+++ b/manifests/aomp_23.0.xml
@@ -1,30 +1,20 @@
-
+
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/manifests/aompi_23.0.xml b/manifests/aompi_23.0.xml
deleted file mode 100644
index 656ab15466..0000000000
--- a/manifests/aompi_23.0.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/smoke-dev/HipDevCov/Makefile b/test/smoke-dev/HipDevCov/Makefile
index 749ada2af2..1fc8db22bb 100644
--- a/test/smoke-dev/HipDevCov/Makefile
+++ b/test/smoke-dev/HipDevCov/Makefile
@@ -21,10 +21,10 @@ LINK_FLAGS = -L$(ROCM_PATH)/lib -lamdhip64 -Wl,-rpath,$(ROCM_PATH)/lib
CC = $(AOMP)/bin/clang $(VERBOSE)
-RUNCMD = ./run_and_check.sh "$(AOMP)" "$(GPU_W_FEATURES)" "$(FILECHECK)" "$(ROCM_PATH)"
+RUNCMD = ./run_and_check.sh "$(AOMP)" "$(GPU_W_FEATURES)" "$(ROCM_PATH)"
include ../Makefile.rules
clean::
rm -f mod.co builder builder.*.host-* builder.*.hip-amdgcn-amd-amdhsa--* \
- *.profraw merged.profdata
+ *.profraw merged.profdata devcov-profile.txt DEVCOV-SKIPPED.txt
diff --git a/test/smoke-dev/HipDevCov/check.txt b/test/smoke-dev/HipDevCov/check.txt
deleted file mode 100644
index 5eccb5f9a5..0000000000
--- a/test/smoke-dev/HipDevCov/check.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Both kernels must appear in the merged host+device profile. host_kernel is the
-host-shadow path; mod_kernel (from the hipModuleLoad'd code object, no host
-shadow) can only be present if the HSA-introspection drain collected it.
-
-CHECK-DAG: host_kernel
-CHECK-DAG: mod_kernel
diff --git a/test/smoke-dev/HipDevCov/run_and_check.sh b/test/smoke-dev/HipDevCov/run_and_check.sh
index 9e72f4f453..3fc0a88b5e 100755
--- a/test/smoke-dev/HipDevCov/run_and_check.sh
+++ b/test/smoke-dev/HipDevCov/run_and_check.sh
@@ -4,40 +4,50 @@
# Args (passed from the Makefile):
# $1 = AOMP (LLVM dir containing bin/clang, llvm-profdata, llvm-objdump)
# $2 = GPU arch (e.g. gfx90a, may include :features)
-# $3 = FILECHECK (path to FileCheck)
-# $4 = ROCM_PATH (HIP/ROCm install for --rocm-path and libamdhip64)
+# $3 = ROCM_PATH (HIP/ROCm install for --rocm-path and libamdhip64)
#
-# Returns 0 only if BOTH the host-shadow kernel and the module-only kernel are
-# present in the merged profile (the latter requires the HSA drain).
+# Proves the HSA-introspection drain captured device coverage that the HIP
+# host-shadow drain cannot see. Verifies, against the actual merged profile:
+# * the HSA drain produced its own profraw (uniquely named *.hsa.*.profraw),
+# * mod_kernel (loaded via hipModuleLoad, no host shadow) is present with a
+# NONZERO function count -- only possible via the HSA drain,
+# * host_kernel (host-shadow path) is also present with a nonzero count.
+# The human-readable profile dump is left in devcov-profile.txt for inspection.
set -u
-AOMP="$1"; ARCH="$2"; FILECHECK="$3"; ROCM="$4"
+AOMP="$1"; ARCH="$2"; ROCM="$3"
CLANG="$AOMP/bin/clang"
PROFDATA="$AOMP/bin/llvm-profdata"
OBJDUMP="$AOMP/bin/llvm-objdump"
-COV="$AOMP/bin/llvm-cov"
here="$(cd "$(dirname "$0")" && pwd)"
cd "$here" || exit 1
-# Capability gate: skip cleanly on toolchains that do not ship the device
-# profile runtime / HSA drain yet (so this does not red-fail CI before the
-# feature lands). A real, drain-capable toolchain has the amdgcn device profile
-# RT and the host drain symbol.
+fail() { echo "FAIL HipDevCov: $*"; exit 1; }
+
+# Function count for a front-end-instrumented function in the --counts dump.
+func_count() {
+ awk -v fn="$1" '
+ $0 ~ ("^[ \t]*" fn ":$") { inblk = 1; next }
+ inblk && /Function count:/ { print $3; exit }
+ ' "$2"
+}
+
+# Capability gate: skip cleanly only when the toolchain truly cannot do device
+# PGO (no amdgcn device profile runtime / no host HSA-drain runtime). Leaves a
+# marker so the skip is visible in archived results rather than a silent pass.
resdir="$("$CLANG" -print-resource-dir 2>/dev/null)"
devrt="$resdir/lib/amdgcn-amd-amdhsa/libclang_rt.profile.a"
-if [ ! -f "$devrt" ]; then
- echo "SKIP HipDevCov: no device profile runtime at $devrt"
- exit 0
-fi
-if ! ls "$resdir"/lib/*/libclang_rt.profile_rocm*.a >/dev/null 2>&1; then
- echo "SKIP HipDevCov: no host profile_rocm runtime (HSA drain) in toolchain"
+rm -f DEVCOV-SKIPPED.txt
+if [ ! -f "$devrt" ] || ! ls "$resdir"/lib/*/libclang_rt.profile_rocm*.a >/dev/null 2>&1; then
+ echo "no device profile runtime / HSA-drain runtime in $resdir" > DEVCOV-SKIPPED.txt
+ echo "SKIP HipDevCov: $(cat DEVCOV-SKIPPED.txt)"
exit 0
fi
set -e
-rm -f ./*.profraw mod.co merged.profdata builder builder.*.host-* \
- builder.*.hip-amdgcn-amd-amdhsa--* 2>/dev/null || true
+rm -f ./*.profraw mod.co merged.profdata devcov-profile.txt builder \
+ builder.*.host-* builder.*.hip-amdgcn-amd-amdhsa--* 2>/dev/null || true
# 1. Build mod.hip as a full executable so the device link gets the device
# profile RT, then extract its device code object as the loadable mod.co.
@@ -47,35 +57,38 @@ rm -f ./*.profraw mod.co merged.profdata builder builder.*.host-* \
"$OBJDUMP" --offloading builder >/dev/null 2>&1 || true
shopt -s nullglob
extracted=(builder*.hip-amdgcn-amd-amdhsa--*gfx*)
-if [ ${#extracted[@]} -eq 0 ]; then
- echo "FAIL HipDevCov: could not extract device code object from builder"
- exit 1
-fi
+[ ${#extracted[@]} -gt 0 ] || fail "could not extract device code object from builder"
cp "${extracted[0]}" mod.co
-# 2. main is built by the smoke harness (TESTNAME=main). Build it here too if it
-# is missing, so the script also works when run standalone.
+# 2. main is built by the harness (TESTNAME=main); build it here if missing.
if [ ! -x ./main ]; then
"$CLANG" -x hip --offload-arch="$ARCH" -fno-gpu-rdc \
-fprofile-instr-generate -fcoverage-mapping --rocm-path="$ROCM" \
main.hip -o main -L"$ROCM/lib" -lamdhip64 -Wl,-rpath,"$ROCM/lib"
fi
-# 3. Run. Device .profraw files are written to CWD (arch-prefixed for the
-# host-shadow drain, arch.hsa-prefixed for the HSA drain); the host one
-# goes to LLVM_PROFILE_FILE.
+# 3. Run with mod.co in CWD.
rm -f ./*.profraw
LLVM_PROFILE_FILE="$here/host.profraw" \
LD_LIBRARY_PATH="$ROCM/lib:${LD_LIBRARY_PATH:-}" \
./main
-# 4. Merge host + all device profraws and assert both kernels are present.
+# 4. The HSA-introspection drain writes its own, uniquely-named profraw
+# (.hsa..profraw). Its presence is a direct fingerprint that
+# the HSA pass ran (the host-shadow drain names files [:feat].).
+hsa=(*.hsa[0-9]*.profraw)
+[ ${#hsa[@]} -gt 0 ] || fail "no HSA-drain profraw (*.hsa.*.profraw) produced"
+echo "HipDevCov: HSA-drain profraw(s): ${hsa[*]}"
+
+# 5. Merge and verify real counts from the dump.
"$PROFDATA" merge -sparse -o merged.profdata ./*.profraw
-"$PROFDATA" show --all-functions merged.profdata | "$FILECHECK" check.txt
+"$PROFDATA" show --all-functions --counts merged.profdata > devcov-profile.txt
-# 5. Sanity (non-fatal): llvm-cov can consume the merged device+host profile.
-# main's covmap only describes host_kernel/main, so llvm-cov warns about the
-# module-only function; that is expected, hence non-fatal.
-"$COV" report ./main -instr-profile=merged.profdata >/dev/null 2>&1 || true
+mc="$(func_count mod_kernel devcov-profile.txt)"
+hc="$(func_count _Z11host_kernelPii devcov-profile.txt)"
+[ -n "$mc" ] || fail "mod_kernel absent from merged profile (HSA drain did not capture it)"
+[ -n "$hc" ] || fail "host_kernel absent from merged profile"
+[ "$mc" -gt 0 ] 2>/dev/null || fail "mod_kernel function count is '$mc' (expected > 0)"
+[ "$hc" -gt 0 ] 2>/dev/null || fail "host_kernel function count is '$hc' (expected > 0)"
-echo "HipDevCov PASSED"
+echo "HipDevCov PASSED (mod_kernel=$mc via HSA drain, host_kernel=$hc)"
diff --git a/test/smoke-dev/OmpDevCov/Makefile b/test/smoke-dev/OmpDevCov/Makefile
index de216662ca..2a39e2f3e3 100644
--- a/test/smoke-dev/OmpDevCov/Makefile
+++ b/test/smoke-dev/OmpDevCov/Makefile
@@ -18,9 +18,9 @@ LINK_FLAGS = -Wl,-rpath,$(AOMP)/lib
CC = $(AOMP)/bin/clang $(VERBOSE)
-RUNCMD = ./run_and_check.sh "$(AOMP)" "$(GPU_W_FEATURES)" "$(FILECHECK)"
+RUNCMD = ./run_and_check.sh "$(AOMP)" "$(GPU_W_FEATURES)"
include ../Makefile.rules
clean::
- rm -f omp_pgo omp_pgo_use *.profraw merged.profdata
+ rm -f omp_pgo omp_pgo_use *.profraw merged.profdata devcov-profile.txt DEVCOV-SKIPPED.txt
diff --git a/test/smoke-dev/OmpDevCov/check.txt b/test/smoke-dev/OmpDevCov/check.txt
deleted file mode 100644
index 831fad5558..0000000000
--- a/test/smoke-dev/OmpDevCov/check.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-The merged profile must contain device-side counters that could only have been
-collected via the HSA-introspection drain (OpenMP offload has no host-shadow
-drain). The device offload entry and the device function classify both appear.
-
-CHECK-DAG: __omp_offloading_
-CHECK-DAG: classify
diff --git a/test/smoke-dev/OmpDevCov/run_and_check.sh b/test/smoke-dev/OmpDevCov/run_and_check.sh
index 424b6a0c24..175f70fb40 100755
--- a/test/smoke-dev/OmpDevCov/run_and_check.sh
+++ b/test/smoke-dev/OmpDevCov/run_and_check.sh
@@ -4,73 +4,82 @@
# Args (passed from the Makefile):
# $1 = AOMP (LLVM dir containing bin/clang, llvm-profdata)
# $2 = GPU arch (e.g. gfx90a, may include :features)
-# $3 = FILECHECK (path to FileCheck)
#
-# omp_pgo (the -fprofile-generate binary) is built by the harness. Here we:
-# 1. run it -> host default.profraw + device amdgcn-amd-amdhsa.*.profraw
-# (the device file is produced ONLY by the HSA drain),
-# 2. assert a device profraw was produced and merge,
-# 3. FileCheck the merged profile for the device offload function,
-# 4. rebuild with -fprofile-use and assert it consumes cleanly (no profile
-# mismatch / out-of-date diagnostics) and runs.
+# OpenMP offload has no host-shadow drain, so device counters can only reach the
+# profile through the HSA-introspection drain. omp_pgo (the -fprofile-generate
+# binary) is built by the harness. Here we verify, against the actual merged
+# profile, that:
+# * the HSA drain produced a device profraw (amdgcn-amd-amdhsa.*.profraw),
+# * the device function classify has NONZERO counts on BOTH branches of its
+# data-dependent if/else -- real device PGO data, not just a present symbol,
+# * -fprofile-use consumes the merged profile cleanly and runs.
+# The human-readable profile dump is left in devcov-profile.txt for inspection.
set -u
-AOMP="$1"; ARCH="$2"; FILECHECK="$3"
+AOMP="$1"; ARCH="$2"
CLANG="$AOMP/bin/clang"
PROFDATA="$AOMP/bin/llvm-profdata"
here="$(cd "$(dirname "$0")" && pwd)"
cd "$here" || exit 1
-# Capability gate: skip cleanly if the toolchain has no amdgcn device profile
-# runtime (i.e. no device PGO / HSA drain yet), so CI is not red before the
-# feature lands.
+fail() { echo "FAIL OmpDevCov: $*"; exit 1; }
+run_env() { LD_LIBRARY_PATH="$AOMP/lib:${LD_LIBRARY_PATH:-}" "$@"; }
+
+# Capability gate: skip cleanly only when there is no amdgcn device profile
+# runtime (no device PGO possible). Leave a marker so the skip is visible.
resdir="$("$CLANG" -print-resource-dir 2>/dev/null)"
+rm -f DEVCOV-SKIPPED.txt
if [ ! -f "$resdir/lib/amdgcn-amd-amdhsa/libclang_rt.profile.a" ]; then
- echo "SKIP OmpDevCov: no amdgcn device profile runtime in toolchain"
+ echo "no amdgcn device profile runtime in $resdir" > DEVCOV-SKIPPED.txt
+ echo "SKIP OmpDevCov: $(cat DEVCOV-SKIPPED.txt)"
exit 0
fi
set -e
-rm -f ./*.profraw merged.profdata omp_pgo_use 2>/dev/null || true
+rm -f ./*.profraw merged.profdata devcov-profile.txt omp_pgo_use 2>/dev/null || true
-run_env() { LD_LIBRARY_PATH="$AOMP/lib:${LD_LIBRARY_PATH:-}" "$@"; }
-
-# 1. Run the generate binary (built by the harness as ./omp_pgo). Build it here
-# too if missing, so the script also works standalone.
+# 1. Run the generate binary (built by the harness as ./omp_pgo).
if [ ! -x ./omp_pgo ]; then
"$CLANG" -fopenmp --offload-arch="$ARCH" -fprofile-generate \
omp_pgo.c -o omp_pgo -Wl,-rpath,"$AOMP/lib"
fi
run_env ./omp_pgo
-# 2. The HSA drain must have produced at least one device profraw.
+# 2. The HSA drain must have produced a device profraw.
shopt -s nullglob
dev=(amdgcn-amd-amdhsa*.profraw)
-if [ ${#dev[@]} -eq 0 ]; then
- echo "FAIL OmpDevCov: no device (amdgcn-amd-amdhsa) profraw -- HSA drain did not fire"
- ls -1 ./*.profraw 2>/dev/null || true
- exit 1
-fi
+[ ${#dev[@]} -gt 0 ] || fail "no device (amdgcn-amd-amdhsa) profraw -- HSA drain did not fire"
echo "OmpDevCov: device profraw(s): ${dev[*]}"
+# 3. Merge and verify real device counts: classify must have both branches
+# exercised on-device (nonzero, nonzero).
"$PROFDATA" merge -o merged.profdata ./*.profraw
+"$PROFDATA" show --all-functions --counts merged.profdata > devcov-profile.txt
-# 3. The merged profile must carry the device offload function counters.
-"$PROFDATA" show --all-functions merged.profdata | "$FILECHECK" check.txt
+# Pull classify's "Block counts: [a, b, ...]" line and require every counter > 0.
+bc="$(awk '/[;:]classify:$/ {f=1; next} f && /Block counts:/ {print; exit}' devcov-profile.txt)"
+[ -n "$bc" ] || fail "device function classify absent from merged profile (HSA drain did not capture it)"
+nums="$(printf '%s\n' "$bc" | grep -oE '[0-9]+')"
+[ -n "$nums" ] || fail "could not parse classify block counts from: $bc"
+for n in $nums; do
+ [ "$n" -gt 0 ] 2>/dev/null || fail "classify has a zero block count ($bc) -- device branch not profiled"
+done
+echo "OmpDevCov: classify $bc (all branches nonzero)"
# 4. -fprofile-use round trip: must consume the profile without a mismatch /
# out-of-date diagnostic, then run.
use_log="$(mktemp)"
"$CLANG" -fopenmp --offload-arch="$ARCH" -fprofile-use=merged.profdata \
omp_pgo.c -o omp_pgo_use -Wl,-rpath,"$AOMP/lib" 2> "$use_log" || {
- echo "FAIL OmpDevCov: -fprofile-use build failed"; cat "$use_log"; rm -f "$use_log"; exit 1; }
+ echo "--- profile-use build log ---"; cat "$use_log"; rm -f "$use_log"
+ fail "-fprofile-use build failed"; }
if grep -Eiq "out of date|profile data may be out of date|no profile data available|mismatch" "$use_log"; then
- echo "FAIL OmpDevCov: -fprofile-use reported stale/mismatched profile"
- cat "$use_log"; rm -f "$use_log"; exit 1
+ echo "--- profile-use build log ---"; cat "$use_log"; rm -f "$use_log"
+ fail "-fprofile-use reported a stale/mismatched profile"
fi
rm -f "$use_log"
run_env ./omp_pgo_use
-echo "OmpDevCov PASSED"
+echo "OmpDevCov PASSED (classify branches profiled on device, -fprofile-use round trip clean)"
diff --git a/test/smoke/helloworld%n/Makefile b/test/smoke/helloworld%n/Makefile
index a1a8198587..51d5ebc578 100644
--- a/test/smoke/helloworld%n/Makefile
+++ b/test/smoke/helloworld%n/Makefile
@@ -5,6 +5,11 @@ TESTSRC_MAIN = helloworld.c
TESTSRC_AUX =
TESTSRC_ALL = $(TESTSRC_MAIN) $(TESTSRC_AUX)
+# The %n printf format does not work with libc printf so force emissary printf
+ifeq ($(shell echo 'int main() { return 0; }' | $(CC) -fuse-emissary-print -xc - 2>/dev/null && echo true), true)
+ EXTRA_CFLAGS=-fuse-emissary-print
+endif
+
CLANG ?= clang
OMP_BIN = $(AOMP)/bin/$(CLANG)
CC = $(OMP_BIN) $(VERBOSE)