From 1b2165fa8889d06192f8536fdf85fddcd445a09d Mon Sep 17 00:00:00 2001 From: Jeff Hammond Date: Sat, 17 Oct 2026 17:55:31 +0200 Subject: [PATCH] Fortran CMake: make transpose-openmp-target-loop optional; build GA without ScaLAPACK gfortran lacks OpenMP 'target teams loop'/'loop', so probe for it and skip that target when unsupported. Pass --without-scalapack to the autobuilt GA so it doesn't pick up an unlinked system ScaLAPACK. Co-Authored-By: Claude Sonnet 5.5 --- FORTRAN/CMakeLists.txt | 12 ++++++++++-- cmake/AutobuildDeps.cmake | 2 +- cmake/PRKFortranFeatures.cmake | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/FORTRAN/CMakeLists.txt b/FORTRAN/CMakeLists.txt index 2cc63267b..e15e0263d 100644 --- a/FORTRAN/CMakeLists.txt +++ b/FORTRAN/CMakeLists.txt @@ -48,6 +48,9 @@ include("${CMAKE_CURRENT_LIST_DIR}/../cmake/PRKFortranFeatures.cmake") prk_check_coarray_single() prk_check_coarray_lib() prk_check_openmp_offload() +if(PRK_OPENMP_OFFLOAD_FLAG) + prk_check_openmp_target_loop() +endif() prk_check_openacc_links() set(PRK_WITH_COARRAY FALSE) @@ -162,10 +165,15 @@ if(PRK_WITH_OFFLOAD) prk_fortran_executable(transpose-openmp-target SOURCES transpose-openmp-target.F90 FLAGS ${PRK_OPENMP_OFFLOAD_FLAG}) prk_fortran_executable(nstream-openmp-target SOURCES nstream-openmp-target.F90 FLAGS ${PRK_OPENMP_OFFLOAD_FLAG}) prk_fortran_executable(dgemm-openmp-target SOURCES dgemm-openmp-target.F90 FLAGS ${PRK_OPENMP_OFFLOAD_FLAG}) - prk_fortran_executable(transpose-openmp-target-loop SOURCES transpose-openmp-target-loop.F90 FLAGS ${PRK_OPENMP_OFFLOAD_FLAG}) add_custom_target(fortran_target DEPENDS fortran_stencil-openmp-target fortran_transpose-openmp-target fortran_nstream-openmp-target - fortran_dgemm-openmp-target fortran_transpose-openmp-target-loop) + fortran_dgemm-openmp-target) + if(PRK_OPENMP_TARGET_LOOP_COMPILES) + prk_fortran_executable(transpose-openmp-target-loop SOURCES transpose-openmp-target-loop.F90 FLAGS ${PRK_OPENMP_OFFLOAD_FLAG}) + add_dependencies(fortran_target fortran_transpose-openmp-target-loop) + else() + message(STATUS "FORTRAN transpose-openmp-target-loop: skipped, compiler lacks OpenMP 'target teams loop'") + endif() else() message(STATUS "FORTRAN target (OpenMP offload): skipped, no working target-offload flags found") endif() diff --git a/cmake/AutobuildDeps.cmake b/cmake/AutobuildDeps.cmake index e45eec63f..143a15989 100644 --- a/cmake/AutobuildDeps.cmake +++ b/cmake/AutobuildDeps.cmake @@ -119,7 +119,7 @@ function(prk_autobuild_global_arrays) PREFIX "${_ga_prefix}" BUILD_IN_SOURCE TRUE CONFIGURE_COMMAND ${_prk_autoreconf} -vif - COMMAND /configure --with-armci=${_armci_install_dir} + COMMAND /configure --with-armci=${_armci_install_dir} --without-scalapack MPICC=${_prk_mpicc} MPIFC=${_prk_mpif90} MPIF77=${_prk_mpif90} --prefix= BUILD_COMMAND make diff --git a/cmake/PRKFortranFeatures.cmake b/cmake/PRKFortranFeatures.cmake index 9af455b45..2c93cf860 100644 --- a/cmake/PRKFortranFeatures.cmake +++ b/cmake/PRKFortranFeatures.cmake @@ -135,3 +135,17 @@ function(prk_check_openmp_offload) message(STATUS "Fortran OpenMP target offload: compiled but failed to run correctly (broken offload runtime)") endif() endfunction() + +# Some compilers (e.g. gfortran) accept `!$omp target` but not the OpenMP 5.0 +# `loop` construct used by transpose-openmp-target-loop.F90. Probe it +# separately (compile-only) so that one source can be skipped on its own. +function(prk_check_openmp_target_loop) + if(DEFINED PRK_OPENMP_TARGET_LOOP_COMPILES) + return() + endif() + set(_src "program main\n integer :: i, j\n real :: a(4,4)\n !$omp target teams loop collapse(2)\n do j=1,4\n do i=1,4\n a(i,j) = 0\n enddo\n enddo\n !$omp end target teams loop\nend program main\n") + string(REPLACE ";" " " _flags "${PRK_OPENMP_OFFLOAD_FLAG}") + set(CMAKE_REQUIRED_FLAGS "${_flags}") + check_fortran_source_compiles("${_src}" PRK_OPENMP_TARGET_LOOP_COMPILES SRC_EXT F90) + unset(CMAKE_REQUIRED_FLAGS) +endfunction()