Skip to content

Commit 5b09725

Browse files
authored
CMake Fix split command flags to be correctly populated (#2108)
TYPE: bug fix KEYWORDS: cmake, mpi, compilation SOURCE: internal DESCRIPTION OF CHANGES: Problem: The `arch/configure_reader.py` does the job of parsing, organizing, and sanitizing input from configuration stanzas into a CMake toolchain file which can then be used to inform the build about which compilers, flags, and options to use. Occasionally, stanzas fields inject flags into a compiler or other command field (like `DM_FC`) so that the actual command is a command + flags. Part of the `arch/configure_reader.py` organization is breaking these up into separable sections automatically. With the example of `DM_FC = mpif90 -f90=gfortran` (`$(SFC)` already expanded) this _should_ be broken into `DM_FC = mpif90` and `DM_FC_FLAGS = -f90=gfortran`. Currently, the `*_FLAGS` field when split out for certain keys in a stanza is not populated due to using the wrong index from the Python `str.partition()` call. Secondly, when these fields are actually provided to CMake compilation breaks for MPI specifically. Since the MPI "compilers" are wrappers, they are then interrogated for the underlying flags and options meaning further adding the flags back into compilation results in things like `gfortran <all the other flags> -f90=gfortran`. This is incorrect, and instead the flags should be provided to the MPI flags used during wrapper interrogation on a per-language basis. Furthermore, for certain MPI implementations supplying any flags renders the query command (e.g. `-show`, `-showme`, or `-compileinfo`) useless. For instance, OpenMPI `mpif90 -f90=gfortran -show` only outputs `gfortran -f90=gfortran` which is also wrong. Solution: 1. The Python call to split the fields should take the actual values 2. MPI flags per language should be supplied to the interrogation flags `MPI_<LANG>_COMPILER_FLAGS` if needed 3. The `FindMPI` module already feeds in the underlying compiler specification for wrappers that support it so flags like `-f90=$(SFC)` should be filtered out from `DM_*_FLAGS` before being written to the `wrf_config.cmake` toolchain file TESTS CONDUCTED: 1. Flags in specific command fields are now split and appearing in the `wrf_config.cmake` file 2. MPI compilation works with compiler specification filtered out but correct underlying compiler still selected even when multiple compilers are in the same environment (note: this was the original behavior but now is deliberate)
1 parent 7195dc2 commit 5b09725

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

CMakeLists.txt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -405,23 +405,20 @@ if ( ${USE_MPI} )
405405
# Which may or may not get polluted by the environment
406406
# It still technically finds MPI but the output is nonintuitive
407407
# saying things like hdf5 or pthread
408-
find_package( MPI REQUIRED COMPONENTS Fortran C )
409-
list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS
410-
USE_MPI=1
411-
DM_PARALLEL
412-
)
413408

409+
# Supply any language-specific flags for interrogation
414410
if ( DEFINED WRF_MPI_Fortran_FLAGS AND NOT "${WRF_MPI_Fortran_FLAGS}" STREQUAL "" )
415-
list( APPEND PROJECT_COMPILE_OPTIONS_OPTIONS
416-
$<$<COMPILE_LANGUAGE:Fortran>:${WRF_MPI_Fortran_FLAGS}>
417-
)
411+
set( MPI_Fortran_COMPILER_FLAGS ${WRF_MPI_Fortran_FLAGS} )
418412
endif()
419413

420414
if ( DEFINED WRF_MPI_C_FLAGS AND NOT "${WRF_MPI_C_FLAGS}" STREQUAL "" )
421-
list( APPEND PROJECT_COMPILE_OPTIONS_OPTIONS
422-
$<$<COMPILE_LANGUAGE:C>:${WRF_MPI_C_FLAGS}>
423-
)
415+
set( MPI_C_COMPILER_FLAGS ${WRF_MPI_C_FLAGS} )
424416
endif()
417+
find_package( MPI REQUIRED COMPONENTS Fortran C )
418+
list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS
419+
USE_MPI=1
420+
DM_PARALLEL
421+
)
425422

426423
# Check if MPI in all its glory has forced IPO down our throats due to hard-coding the wrapper flags
427424
# https://www.open-mpi.org/faq/?category=mpi-apps#why-no-rpath LOL!

arch/configure_reader.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def splitIntoFieldAndFlags( self, field ) :
141141
fieldValue = self.kvPairs_[ field ]
142142

143143
self.kvPairs_[field] = fieldValue.partition(" ")[0]
144-
self.kvPairs_[field + "_FLAGS"] = fieldValue.partition(" ")[1]
144+
self.kvPairs_[field + "_FLAGS"] = fieldValue.partition(" ")[2]
145145

146146
######################################################################################################################
147147
##
@@ -182,6 +182,26 @@ def sanitize( self ) :
182182
# And for final measure strip
183183
self.kvPairs_[ key ] = self.kvPairs_[ key ].strip()
184184

185+
# Finally, further sanitize MPI compilers, we don't need to specify underlying
186+
# compiler since CMake already does that
187+
filters = [
188+
self.kvPairs_[ "SFC" ],
189+
self.kvPairs_[ "SCC" ],
190+
"-compiler"
191+
]
192+
keysToSanitize = [ "DM_FC_FLAGS", "DM_CC_FLAGS" ]
193+
194+
for keyToSan in keysToSanitize :
195+
if self.kvPairs_[ keyToSan ] :
196+
allFlags = self.kvPairs_[ keyToSan ].split( " " )
197+
newFlags = []
198+
for flag in allFlags :
199+
if not any( [ f in flag for f in filters ] ) :
200+
newFlags.append( flag )
201+
202+
# We always need this field updated
203+
self.kvPairs_[ keyToSan ] = " ".join( newFlags )
204+
185205
def serialCompilersAvailable( self ) :
186206
return which( self.kvPairs_["SFC"] ) is not None and which( self.kvPairs_["SCC"] ) is not None
187207

0 commit comments

Comments
 (0)