From 8964f5c1da80f21f1702ad86a39274f344cc6798 Mon Sep 17 00:00:00 2001 From: HathewayWill <118180342+HathewayWill@users.noreply.github.com> Date: Wed, 20 May 2026 20:25:39 -0500 Subject: [PATCH 1/3] Add AOCC flang/clang build configuration for WPS on AMD Linux x86_64 TYPE: enhancement KEYWORDS: WPS, AOCC, flang, clang, AMD, x86_64, configure, dmpar, serial SOURCE: Will H ([affiliation]) DESCRIPTION OF CHANGES: Problem: WPS does not currently provide a configure option for building on AMD Linux x86_64 systems with the AMD Optimizing C/C++ and Fortran Compiler suite. Users who want to build WPS with AOCC flang, AOCC clang, AMD LibM, OpenMP, and AOCC/LLVM optimization options must manually edit the generated configure.wps file or maintain a local configuration stanza. This also makes WPS inconsistent with AOCC-based WRF builds, where AOCC-specific compiler and linker options can be selected through the configure system. Solution: Added a new WPS architecture stanza for: AMD Linux x86_64, AOCC flang compiler with AOCC clang The new stanza supports the following WPS build modes: serial serial_NO_GRIB2 dmpar dmpar_NO_GRIB2 The stanza defines AOCC flang as the serial Fortran compiler, AOCC clang as the serial C compiler, and the MPI compiler wrappers for distributed-memory builds. It also adds AOCC-oriented Fortran, C, preprocessing, archive, and link flags, including AMD Zen tuning, OpenMP, AMD LibM vector library support, byte swapping, and AOCC/LLVM link-time optimization options. The AOCC vectorization option used in LDFLAGS follows the spelling documented in the AOCC 4.0 User Guide: -vectorize-non-contiguous-memory-aggressively No WPS algorithms, data processing behavior, or scientific results are changed. This change only adds a supported configure path for AOCC builds. ISSUE: N/A LIST OF MODIFIED FILES: M arch/configure.defaults TESTS CONDUCTED: 1. Build/configure validation: [Replace with actual test result.] Suggested validation: - Run ./clean -a - Run ./configure - Select the new AOCC flang/clang option for serial and/or dmpar - Confirm that configure.wps is generated with flang, clang, mpifort, and mpicc as expected - Run ./compile - Confirm that the expected WPS executables are produced, such as geogrid.exe, ungrib.exe, and metgrid.exe 2. Jenkins tests: Not run locally. To be verified by the WPS automated test suite. RELEASE NOTE: Added a WPS configure option for AMD Linux x86_64 systems using AOCC flang and AOCC clang. The new stanza supports serial, serial_NO_GRIB2, dmpar, and dmpar_NO_GRIB2 builds, and includes AOCC-oriented optimization, OpenMP, AMD LibM, and AMD Zen tuning flags. The AOCC vectorization option follows the spelling documented in the AMD AOCC User Guide, Publication #57222, Revision #4.0, November 2022. --- arch/configure.defaults | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/configure.defaults b/arch/configure.defaults index cdb94071..e8a33552 100644 --- a/arch/configure.defaults +++ b/arch/configure.defaults @@ -892,6 +892,33 @@ CPPFLAGS = -D_UNDERSCORE -DBYTESWAP -DLINUX -DIO_NETCDF -DIO_BINARY - ARFLAGS = CC_TOOLS = +######################################################################################################################## +#ARCH AMD Linux x86_64, AOCC flang compiler with AOCC clang # serial serial_NO_GRIB2 dmpar dmpar_NO_GRIB2 +# +COMPRESSION_LIBS = CONFIGURE_COMP_L +COMPRESSION_INC = CONFIGURE_COMP_I +FDEFS = CONFIGURE_FDEFS +SFC = flang +SCC = clang +DM_FC = mpifort +DM_CC = mpicc +FC = CONFIGURE_FC +CC = CONFIGURE_CC +LD = $(FC) +FFLAGS = $(FORMAT_FREE) -Ofast -ffast-math -fPIC -Mbyteswapio -Mstack_arrays -funroll-loops -ftree-vectorize -fopenmp -march=znver3 -fveclib=AMDLIBM +F77FLAGS = $(FORMAT_FIXED) -Ofast -ffast-math -fPIC -Mbyteswapio -Mstack_arrays -funroll-loops -ftree-vectorize -fopenmp -march=znver3 -fveclib=AMDLIBM +FORMAT_FREE = -Mfreeform +FORMAT_FIXED = -Mfixed +FCSUFFIX = +FNGFLAGS = $(FFLAGS) +LDFLAGS = -m64 -Ofast -Mstack_arrays -fopenmp -lomp -march=znver3 -Wl,--allow-multiple-definition -Wl,-mllvm -Wl,-enable-loop-reversal -Wl,-mllvm -Wl,-enable-gather -Wl,-mllvm -Wl,-vectorize-non-contiguous-memory-aggressively -lamdlibm +CFLAGS = -w -O3 -fPIC -fopenmp -march=znver3 -D_UNDERSCORE +CPP = /usr/bin/cpp -P -traditional +CPPFLAGS = -D_UNDERSCORE -DBYTESWAP -DLINUX -DIO_NETCDF -DIO_BINARY -DIO_GRIB1 -DBIT32 -DNO_SIGNAL CONFIGURE_MPI +ARFLAGS = +RANLIB = llvm-ranlib +CC_TOOLS = + ######################################################################################################################## #ARCH NULL # serial serial_NO_GRIB2 dmpar dmpar_NO_GRIB2 From 75dcf96f6774b9e6f8e1ae9508811ea0a895fced Mon Sep 17 00:00:00 2001 From: HathewayWill <118180342+HathewayWill@users.noreply.github.com> Date: Fri, 22 May 2026 23:45:07 -0500 Subject: [PATCH 2/3] Update configure.defaults removing zen3 architecture requirement --- arch/configure.defaults | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/configure.defaults b/arch/configure.defaults index e8a33552..14e985fb 100644 --- a/arch/configure.defaults +++ b/arch/configure.defaults @@ -905,14 +905,14 @@ DM_CC = mpicc FC = CONFIGURE_FC CC = CONFIGURE_CC LD = $(FC) -FFLAGS = $(FORMAT_FREE) -Ofast -ffast-math -fPIC -Mbyteswapio -Mstack_arrays -funroll-loops -ftree-vectorize -fopenmp -march=znver3 -fveclib=AMDLIBM -F77FLAGS = $(FORMAT_FIXED) -Ofast -ffast-math -fPIC -Mbyteswapio -Mstack_arrays -funroll-loops -ftree-vectorize -fopenmp -march=znver3 -fveclib=AMDLIBM +FFLAGS = $(FORMAT_FREE) -Ofast -ffast-math -fPIC -Mbyteswapio -Mstack_arrays -funroll-loops -ftree-vectorize -fopenmp -fveclib=AMDLIBM +F77FLAGS = $(FORMAT_FIXED) -Ofast -ffast-math -fPIC -Mbyteswapio -Mstack_arrays -funroll-loops -ftree-vectorize -fopenmp -fveclib=AMDLIBM FORMAT_FREE = -Mfreeform FORMAT_FIXED = -Mfixed FCSUFFIX = FNGFLAGS = $(FFLAGS) -LDFLAGS = -m64 -Ofast -Mstack_arrays -fopenmp -lomp -march=znver3 -Wl,--allow-multiple-definition -Wl,-mllvm -Wl,-enable-loop-reversal -Wl,-mllvm -Wl,-enable-gather -Wl,-mllvm -Wl,-vectorize-non-contiguous-memory-aggressively -lamdlibm -CFLAGS = -w -O3 -fPIC -fopenmp -march=znver3 -D_UNDERSCORE +LDFLAGS = -m64 -Ofast -Mstack_arrays -fopenmp -lomp -Wl,--allow-multiple-definition -Wl,-mllvm -Wl,-enable-loop-reversal -Wl,-mllvm -Wl,-enable-gather -Wl,-mllvm -Wl,-vectorize-non-contiguous-memory-aggressively -lamdlibm +CFLAGS = -w -O3 -fPIC -fopenmp -D_UNDERSCORE CPP = /usr/bin/cpp -P -traditional CPPFLAGS = -D_UNDERSCORE -DBYTESWAP -DLINUX -DIO_NETCDF -DIO_BINARY -DIO_GRIB1 -DBIT32 -DNO_SIGNAL CONFIGURE_MPI ARFLAGS = From fb02d7a6237a2d7ec079e77ba490702883f288ca Mon Sep 17 00:00:00 2001 From: HathewayWill <118180342+HathewayWill@users.noreply.github.com> Date: Sun, 24 May 2026 00:32:03 -0500 Subject: [PATCH 3/3] Update compile for exe checks ## Summary This PR updates the WPS `compile` script to perform WRF-style executable checks after compilation. The script now verifies that each requested target produced the expected `.exe` file and reports a clear success or failure message for each build target. ## Changes - Added per-target executable checks after each WPS build step. - Added final executable summary checks for all requested targets. - Added explicit tracking of expected executables for `wps`, `util`, and individual compile targets. - Added failure reporting for missing executable files or missing symbolic links. - Updated the script to exit with a nonzero status if any requested executable is missing. - Preserved the existing WPS target-selection logic and build commands. ## Motivation Previously, the WPS `compile` script could finish without clearly reporting whether all requested executables were successfully created. This made it easier to miss failed builds, especially when compiling multiple targets such as `geogrid`, `ungrib`, `metgrid`, and utilities. This change makes the WPS compile output more consistent with the WRF build output, where expected executables are checked and a clear success or failure message is printed. ## Testing Tested compilation of a WPS utility target and confirmed that the updated script reports successful executable creation, including the linked executable path. Example successful output: ```text ---> int2nc.exe successfully built <--- --- compile | 221 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 163 insertions(+), 58 deletions(-) diff --git a/compile b/compile index dfee3b5d..bcda03a7 100755 --- a/compile +++ b/compile @@ -2,7 +2,7 @@ if ( ! -e configure.wps ) then echo "Do 'configure' first" - exit ( 1 ) + exit ( 1 ) endif if ( ( ! $?NETCDF ) && ( -d netcdf_links ) ) then @@ -13,23 +13,24 @@ else endif set DEV_TOP = `pwd` +set WRF_DIR_PRE = set first_char = `grep ^WRF_DIR configure.wps | awk '{print $3}' | cut -c -1` ## test for Cygwin on Windows grep CYGWIN_NT configure.wps >& /dev/null if ( $status == 0 ) then - ls -l */*/*cio.c | grep '^l' - if ( $status == 0 ) then - echo Symbolic links are not handled properly by pgcc on Windows. Run arch/fixlinks in this directory and try again. - exit - endif + ls -l */*/*cio.c | grep '^l' + if ( $status == 0 ) then + echo Symbolic links are not handled properly by pgcc on Windows. Run arch/fixlinks in this directory and try again. + exit(1) + endif else - if ( "$first_char" == "/" ) then - set WRF_DIR_PRE = - else - set WRF_DIR_PRE = ${DEV_TOP}/ - endif + if ( "$first_char" == "/" ) then + set WRF_DIR_PRE = + else + set WRF_DIR_PRE = ${DEV_TOP}/ + endif endif if ( ${#argv} == 0 ) then @@ -81,56 +82,68 @@ else if ( $1 == int2nc ) then set names = ( int2nc ) set NAMES = ( UTIL ) else - echo "*****" - echo " " + echo "*****" + echo " " echo "Unrecognized compile target $1." - echo " " - echo "Usage: compile [target]" - echo "where target is one of" - echo " wps" - echo " util" - echo " geogrid" - echo " ungrib" - echo " metgrid" - echo " g1print" - echo " g2print" - echo " plotfmt" - echo " rd_intermediate" - echo " plotgrids" - echo " mod_levs" - echo " avg_tsfc" - echo " calc_ecmwf_p" - echo " height_ukmo" - echo " int2nc" - echo " " - echo " or just run compile with no target to build everything." - echo " " - echo "*****" - exit(1) + echo " " + echo "Usage: compile [target]" + echo "where target is one of" + echo " wps" + echo " util" + echo " geogrid" + echo " ungrib" + echo " metgrid" + echo " g1print" + echo " g2print" + echo " plotfmt" + echo " rd_intermediate" + echo " plotgrids" + echo " mod_levs" + echo " avg_tsfc" + echo " calc_ecmwf_p" + echo " height_ukmo" + echo " int2nc" + echo " " + echo " or just run compile with no target to build everything." + echo " " + echo "*****" + exit(1) endif +# Build list of final executables that should exist for the selected target. +set expected_exes = ( ) +set count = 1 +foreach f ( $names ) + if ( ( "$NAMES[$count]" == "UTIL" ) || ( "$NAMES[$count]" == "GRIBUTIL" ) ) then + set expected_exes = ( $expected_exes util/${f}.exe ) + else + set expected_exes = ( $expected_exes ${f}.exe ) + endif + @ count ++ +end + # Print out WPS version, system info, and compiler/version echo "============================================================================================== " - echo " " - echo Version 4.6.0 - echo " " - uname -a - echo " " - set comp = ( `grep "^SFC" configure.wps | cut -d"=" -f2-` ) - if ( "$comp[1]" == "gfortran" ) then - gfortran --version - else if ( "$comp[1]" == "pgf90" ) then - pgf90 --version - else if ( "$comp[1]" == "ifort" ) then - ifort -V - else if ( "$comp[1]" == "ifx" ) then - ifx -V - else - echo "Not sure how to figure out the version of this compiler: $comp[1]" - endif - echo " " - echo "============================================================================================== " - echo " " +echo " " +echo Version 4.6.0 +echo " " +uname -a +echo " " +set comp = ( `grep "^SFC" configure.wps | cut -d"=" -f2-` ) +if ( "$comp[1]" == "gfortran" ) then + gfortran --version +else if ( "$comp[1]" == "pgf90" ) then + pgf90 --version +else if ( "$comp[1]" == "ifort" ) then + ifort -V +else if ( "$comp[1]" == "ifx" ) then + ifx -V +else + echo "Not sure how to figure out the version of this compiler: $comp[1]" +endif +echo " " +echo "============================================================================================== " +echo " " echo " " @@ -141,26 +154,118 @@ else endif echo " " +set START_OF_COMPILE = `date` +set build_failed = 0 + set count = 1 foreach f ( $names ) + + set exe_path = "" + set link_path = "" + if ("$NAMES[$count]" == "UTIL") then + ( cd util ; make -i -r WRF_DIR_PRE="${WRF_DIR_PRE}" DEV_TOP="${DEV_TOP}" TARGET="${f}.exe" CPP_TARGET="$NAMES[$count]" all ) + + set exe_path = "util/src/${f}.exe" + set link_path = "util/${f}.exe" + else if ("$NAMES[$count]" == "GRIBUTIL") then + ( cd ungrib ; make -i -r WRF_DIR_PRE="${WRF_DIR_PRE}" DEV_TOP="${DEV_TOP}" TARGET="${f}.exe" CPP_TARGET="$NAMES[$count]" all ) - if ( -e ungrib/src/${f}.exe ) then + + set exe_path = "ungrib/src/${f}.exe" + set link_path = "util/${f}.exe" + + if ( -e ${exe_path} ) then ( cd util ; ln -sf ../ungrib/src/${f}.exe . ) endif + else + ( cd $f ; make -i -r WRF_DIR_PRE="${WRF_DIR_PRE}" DEV_TOP="${DEV_TOP}" TARGET="${f}.exe" CPP_TARGET="$NAMES[$count]" all ) - if ( -e ${f}/src/${f}.exe ) then + + set exe_path = "${f}/src/${f}.exe" + set link_path = "${f}.exe" + + if ( -e ${exe_path} ) then ln -sf ${f}/src/${f}.exe . endif + + endif + + echo " " + echo "==========================================================================" + echo "build started: ${START_OF_COMPILE}" + echo "build completed:" `date` + echo " " + + if ( -e ${exe_path} && -e ${link_path} ) then + echo "---> ${f}.exe successfully built <---" + echo " " + ls -l ${exe_path} ${link_path} + else + echo "---> Problems building ${f}.exe, look for errors in the build log <---" + echo " " + if ( ! -e ${exe_path} ) then + echo "Missing executable: ${exe_path}" + endif + if ( ! -e ${link_path} ) then + echo "Missing linked executable: ${link_path}" + endif + set build_failed = 1 endif + + echo " " + echo "==========================================================================" + echo " " + @ count ++ + +end + +echo " " +echo "==========================================================================" +echo "Final WPS executable check" +echo "build started: ${START_OF_COMPILE}" +echo "build completed:" `date` +echo " " + +set final_failed = 0 + +foreach exe ( $expected_exes ) + if ( ! -e ${exe} ) then + set final_failed = 1 + endif end +if ( $final_failed == 0 ) then + echo "---> Requested executables successfully built <---" + echo " " + ls -l $expected_exes +else + echo "---> Problems building one or more requested executables, look for errors in the build log <---" + echo " " + foreach exe ( $expected_exes ) + if ( -e ${exe} ) then + ls -l ${exe} + else + echo "Missing executable: ${exe}" + endif + end + set build_failed = 1 +endif + +echo " " +echo "==========================================================================" +echo " " + if ( $temp_netcdf == 1 ) then unsetenv NETCDF endif +if ( $build_failed == 1 ) then + exit(1) +endif + exit(0)