diff --git a/Makefile b/Makefile index 93df9d6..c12af0a 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ LIBGRAY = $(LIBDIR)/libgray.so BINARIES = $(GRAY) $(GRAY)-convert LIBRARIES = $(LIBGRAY) MANPAGES = $(addprefix $(SHAREDIR)/,gray.1 gray-convert.1 gray.ini.5 \ - profiles.txt.5 beamdata.txt.5 magneticdata.txt.5) + profiles.txt.5 beamdata.txt.5 magneticdata.txt.5) ## ## Git information (used in the version string) @@ -73,14 +73,23 @@ DATE=$(shell LC_TIME=C date -d @$(SOURCE_DATE_EPOCH) '+%B %Y') ## Fortran compiler and flags ## -# Note: can't use ?= for FC because GNU Make defaults to f77 -FC = gfortran -LD = gfortran -FFLAGS += -J$(OBJDIR) -I$(INCDIR) -ffree-line-length-none -fPIC -frecursive -FFLAGS += -Wfatal-errors +LD = $(FC) +FFLAGS += -I$(INCDIR) -fpic LDFLAGS += -L$(LIBDIR) CPPFLAGS += -DREVISION=\"$(GIT_REV)$(GIT_DIRTY)\" -DPREFIX=\"$(PREFIX)\" +# Compiler-specific flags +ifdef GNU +FFLAGS += -J$(OBJDIR) -frecursive +FFLAGS += -fmax-errors=1 -ffree-line-length-none +CPPFLAGS += -DGNU +endif +ifdef INTEL +FFLAGS += -module $(OBJDIR) -assume recursion -heap-arrays +FFLAGS += -diag-error-limit=1 +CPPFLAGS += -DINTEL +endif + ifdef PARALLEL FFLAGS += -ftree-parallelize-loops=$(PARALLEL) -fopt-info-loop LDFLAGS += -fopenmp @@ -104,7 +113,7 @@ ifndef SEMISTATIC LDFLAGS += -static endif else -LDFLAGS += -Wl,-rpath '$$ORIGIN/../lib/' +LDFLAGS += -Wl,-rpath='$$ORIGIN/../lib/' endif # Debug build options @@ -227,7 +236,7 @@ vpath %.f90 $(SRCDIR):$(SRCDIR)/vendor # dependencies (ie. the dependency graph is a DAG); $(OBJDIR)/%.d: %.f90 | $(OBJDIR) @printf '$(@:d=o): $< \\\n' > '$@' - @grep -vE '^[[:blank:]]*use.*(intrinsic|iso_)' '$<' | \ + @grep -vE '^[[:blank:]]*use.*(intrinsic|iso_|ifport)' '$<' | \ sed -nE 's@^[[:blank:]]*use[[:blank:]]+'\ '([^,[:blank:]&]+).*@$(OBJDIR)/\1.o \\@p' | \ sort -u >> '$@' diff --git a/configure b/configure index e787e6c..c90ac25 100755 --- a/configure +++ b/configure @@ -13,6 +13,7 @@ VAR=VALUE. Defaults for the options are specified in brackets. Options: -h, --help display this help and exit --prefix=PREFIX install files in PREFIX [/usr/local] + --with-compiler=PROG use PROG as Fortran compiler [automatically detect] --enable-static statically link programs and libraries [no] --disable-static dynamically link programs and libraries [yes] --enable-deterministic try to make a bit-for-bit deterministic build [no] @@ -39,6 +40,7 @@ for arg in "$@"; do PREFIX="${arg#*=}" printf 'install prefix set to %s\n' "$PREFIX" ;; + --with-compiler=*) FC="${arg#*=}" ;; --enable-static) printf 'STATIC=1\n' >> configure.mk ;; --disable-static) ;; --enable-deterministic) printf 'DETERMINISTIC=1\n' >> configure.mk ;; @@ -74,7 +76,7 @@ printf 'Processor architecture %s\n' "$arch" printf '%s=%s\n' PREFIX "${PREFIX:-/usr/local}" >> configure.mk # Detect the Fortran compiler -for FC in "$FC" ifort gfortran f77; do +for FC in "$FC" ifx ifort gfortran f77; do check "$FC" && break done # shellcheck disable=SC2181 @@ -85,6 +87,11 @@ fi printf 'using %s as Fortran compiler\n' "$FC" printf '%s=%s\n' FC "$FC" >> configure.mk +case $FC in + ifx|ifort) echo 'INTEL=1' >> configure.mk ;; + gfortran|f77) echo 'GNU=1' >> configure.mk ;; +esac + # Check whether ar is deterministic by default if ar h | grep -q '\[D\].*(default)' 2>/dev/null; then printf 'AR_DEFAULT_DETERMINISTIC=1\n' >> configure.mk diff --git a/src/gray_errors.f90 b/src/gray_errors.f90 index 48b69e1..4f6d42e 100644 --- a/src/gray_errors.f90 +++ b/src/gray_errors.f90 @@ -23,57 +23,64 @@ module gray_errors end type ! macros used for defining errors -# define after(x) x%offset + x%subcases +#define after(x) x%offset + x%subcases +#define str character(64) ! All GRAY errors type(error_spec), parameter :: unstable_beam = & error_spec(offset=0, subcases=2, & mod='gray_core', proc='gray_main', & - msg=reshape(['beamtracing may be unstable'], [10], [''])) + msg=reshape([str :: & + 'beamtracing may be unstable'], & + [10], [str :: ''])) - type(error_spec), parameter :: dielectric_tensor = & - error_spec(offset=after(unstable_beam), subcases=2, & - mod='gray_core', proc='gray_main', & - msg=reshape([character(64) :: & - 'ε tensor, overflow in `fsup`', & - 'ε tensor, integration error in `hermitian_2`' & - ], [10], [''])) + type(error_spec), parameter :: dielectric_tensor = & + error_spec(offset=after(unstable_beam), subcases=2, & + mod='gray_core', proc='gray_main', & + msg=reshape([str :: & + 'ε tensor, overflow in `fsup`', & + 'ε tensor, integration error in `hermitian_2`'], & + [10], [str :: ''])) type(error_spec), parameter :: warmdisp_convergence = & error_spec(offset=after(dielectric_tensor), subcases=2, & mod='dispersion', proc='warmdisp', & - msg=reshape([character(64) :: & + msg=reshape([str :: & 'failed to converge, returned fallback value', & - 'failed to converge, returned last value' & - ], [10], [''])) + 'failed to converge, returned last value'], & + [10], [str :: ''])) type(error_spec), parameter :: warmdisp_result = & error_spec(offset=after(warmdisp_convergence), subcases=2, & mod='dispersion', proc='warmdisp', & - msg=reshape([character(64) :: & + msg=reshape([str :: & 'final N⊥² is NaN or ±Infinity', & - 'final N⊥² in 3rd quadrant' & - ], [10], [''])) + 'final N⊥² in 3rd quadrant'], & + [10], [str :: ''])) type(error_spec), parameter :: negative_absorption = & error_spec(offset=after(warmdisp_result), subcases=1, & mod='gray_core', proc='alpha_effj', & - msg=reshape(['negative absorption coeff.'], [10], [''])) + msg=reshape([str :: & + 'negative absorption coeff.'], & + [10], [str :: ''])) type(error_spec), parameter :: fpp_integration = & error_spec(offset=after(negative_absorption), subcases=1, & mod='eccd', proc='eccdeff', & - msg=reshape(['fpp integration error'], [10], [''])) + msg=reshape([str :: & + 'fpp integration error'], & + [10], [str :: ''])) type(error_spec), parameter :: fcur_integration = & error_spec(offset=after(fpp_integration), subcases=3, & mod='eccd', proc='eccdeff', & - msg=reshape([character(64) :: & + msg=reshape([str :: & 'fcur integration error (no trapping)', & 'fcur integration error (1st trapping region)', & - 'fcur integration error (2st trapping region)' & - ], [10], [''])) + 'fcur integration error (2st trapping region)'], & + [10], [str :: ''])) ! Errors occuring during raytracing type(error_spec), parameter :: raytracing_errors(*) = [unstable_beam] diff --git a/src/logger.f90 b/src/logger.f90 index 1831a3a..59f2df1 100644 --- a/src/logger.f90 +++ b/src/logger.f90 @@ -11,6 +11,9 @@ module logger use, intrinsic :: iso_fortran_env, only : error_unit +#ifdef INTEL + use ifport, only : isatty +#endif implicit none diff --git a/src/main.f90 b/src/main.f90 index 96bfc25..08771ca 100644 --- a/src/main.f90 +++ b/src/main.f90 @@ -1,4 +1,8 @@ program main + +#ifdef INTEL + use ifport, only : chdir, getcwd +#endif use const_and_precisions, only : wp_ use logger, only : INFO, ERROR, WARNING, set_logger, log_message use utils, only : dirname @@ -32,7 +36,7 @@ program main ! Store the original working directory integer :: err character(len=256) :: cwd - call getcwd(cwd) + err = getcwd(cwd) ! Parse the command-line options call parse_cli_options(opts) diff --git a/src/utils.f90 b/src/utils.f90 index 1ff988f..88a7779 100644 --- a/src/utils.f90 +++ b/src/utils.f90 @@ -1,5 +1,8 @@ module utils +#ifdef INTEL + use ifport, only : getcwd +#endif use const_and_precisions, only : wp_ implicit none @@ -151,14 +154,14 @@ contains ! local variables character(255) :: cwd - integer :: last_sep + integer :: last_sep, err last_sep = scan(filepath, '/', back=.true.) directory = filepath(1:last_sep) ! append the cwd to relative paths if (isrelative(filepath)) then - call getcwd(cwd) + err = getcwd(cwd) directory = trim(cwd) // '/' // directory end if end function dirname