Summary
Building MPAS standalone with the intel-cray target fails during preprocessing of components/mpas-framework/src/framework/mpas_dmpar.F when the Intel compiler is oneAPI (ifx) rather than classic ifort. On Perlmutter this started after PrgEnv-intel/8.6.0 began loading intel/2025.3, so the Cray ftn wrapper now invokes ifx (IFX) 2025.3.0 (classic ifort is gone).
Error
mpas_dmpar.F(7859): #error: number of arguments doesn't match.
mpas_dmpar.F(7896): #error: number of arguments doesn't match.
make[3]: *** [Makefile:130: mpas_dmpar.o] Error 2
Both lines are DMPAR_DEBUG_WRITE(...) calls (a debug-logging macro that is disabled by default).
Root cause
The framework uses a standard, portable cpp idiom to pass a comma-containing list as a single argument to a function-like macro:
#define COMMA ,
#define DMPAR_DEBUG_WRITE(M) !call mpas_log_write( M )
...
DMPAR_DEBUG_WRITE(' -- Starting recv: ' COMMA commListPtr % procID COMMA commListPtr % nList COMMA size(commListPtr % rbuffer) )
A conforming preprocessor collects function-like macro arguments by scanning for literal top-level commas before expanding object-like macros, so COMMA does not split the argument (it is one argument M, and COMMA expands to , afterward). ifx's built-in fpp expands COMMA too early, sees four arguments for a one-argument macro, and errors. The replacement text being a Fortran comment is irrelevant — the error fires at argument collection.
Minimal reproducer
cmatest.F:
#define COMMA ,
#define DBG(M) !call foo( M )
subroutine bar()
DBG('x: ' COMMA a COMMA b COMMA c )
end subroutine
| Preprocessor |
Result |
ifx -E -fpp cmatest.F / fpp cmatest.F (oneAPI 2025.3) |
#error: number of arguments doesn't match |
cpp -P -traditional (GNU) |
correct → one argument |
gfortran -E -cpp |
correct → one argument |
standard C cpp |
correct → one argument |
Scope
The COMMA idiom is used across the framework (7 files; 24 DMPAR_DEBUG_WRITE calls in mpas_dmpar.F alone), so mpas_dmpar.F(7859/7896) are just the first sites the compiler reaches. The intel-mpi target is expected to hit the same failure on oneAPI systems.
Why it only affects the Intel targets now
src/framework/Makefile compiles .F either via $(CPP) = cpp -P -traditional when GEN_F90=true (GNU cpp, handles the idiom), or directly with $(FC) when GEN_F90=false (the compiler's built-in fpp). The intel-cray/intel-mpi targets use the default GEN_F90=false, so they rely on ifx's broken fpp. This was latent under classic ifort and surfaced when the platform switched to ifx.
Suggested fix
Build the Intel/oneAPI targets with GEN_F90=true so .F files are preprocessed by GNU cpp instead of the compiler's fpp. Verified: adding "GEN_F90 = true" to the intel-cray target's recursive $(MAKE) all invocation preprocesses mpas_dmpar.F cleanly and the generated .f90 compiles with ifx. (Longer-term, filing the fpp conformance regression with Intel and/or reworking the COMMA idiom would also address it.)
Environment
Perlmutter (NERSC), PrgEnv-intel/8.6.0, intel/2025.3, ftn → ifx (IFX) 2025.3.0 20251023, MPAS-Framework at ae81cdecf9.
Summary
Building MPAS standalone with the
intel-craytarget fails during preprocessing ofcomponents/mpas-framework/src/framework/mpas_dmpar.Fwhen the Intel compiler is oneAPI (ifx) rather than classicifort. On Perlmutter this started afterPrgEnv-intel/8.6.0began loadingintel/2025.3, so the Crayftnwrapper now invokesifx (IFX) 2025.3.0(classicifortis gone).Error
Both lines are
DMPAR_DEBUG_WRITE(...)calls (a debug-logging macro that is disabled by default).Root cause
The framework uses a standard, portable cpp idiom to pass a comma-containing list as a single argument to a function-like macro:
A conforming preprocessor collects function-like macro arguments by scanning for literal top-level commas before expanding object-like macros, so
COMMAdoes not split the argument (it is one argumentM, andCOMMAexpands to,afterward).ifx's built-infppexpandsCOMMAtoo early, sees four arguments for a one-argument macro, and errors. The replacement text being a Fortran comment is irrelevant — the error fires at argument collection.Minimal reproducer
cmatest.F:ifx -E -fpp cmatest.F/fpp cmatest.F(oneAPI 2025.3)#error: number of arguments doesn't matchcpp -P -traditional(GNU)gfortran -E -cppcppScope
The
COMMAidiom is used across the framework (7 files; 24DMPAR_DEBUG_WRITEcalls inmpas_dmpar.Falone), sompas_dmpar.F(7859/7896)are just the first sites the compiler reaches. Theintel-mpitarget is expected to hit the same failure on oneAPI systems.Why it only affects the Intel targets now
src/framework/Makefilecompiles.Feither via$(CPP)=cpp -P -traditionalwhenGEN_F90=true(GNU cpp, handles the idiom), or directly with$(FC)whenGEN_F90=false(the compiler's built-infpp). Theintel-cray/intel-mpitargets use the defaultGEN_F90=false, so they rely onifx's brokenfpp. This was latent under classicifortand surfaced when the platform switched toifx.Suggested fix
Build the Intel/oneAPI targets with
GEN_F90=trueso.Ffiles are preprocessed by GNUcppinstead of the compiler'sfpp. Verified: adding"GEN_F90 = true"to theintel-craytarget's recursive$(MAKE) allinvocation preprocessesmpas_dmpar.Fcleanly and the generated.f90compiles withifx. (Longer-term, filing thefppconformance regression with Intel and/or reworking theCOMMAidiom would also address it.)Environment
Perlmutter (NERSC),
PrgEnv-intel/8.6.0,intel/2025.3,ftn→ifx (IFX) 2025.3.0 20251023, MPAS-Framework atae81cdecf9.