Skip to content

Commit 8e5e4ce

Browse files
committed
Merge branch '522-floating-point-comparison-to-reflect-nan' into 'development'
ensure that double comparison handles NaN correctly Closes #522 See merge request damask/DAMASK!1097
2 parents e8d95ed + 06fedf5 commit 8e5e4ce

File tree

6 files changed

+112
-63
lines changed

6 files changed

+112
-63
lines changed

cmake/Compiler-GNU.cmake

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,18 @@ endif ()
2929

3030
#------------------------------------------------------------------------------------------------
3131
# Fine tuning compilation options
32+
#------------------------------------------------------------------------------------------------
33+
34+
# position independent code:
3235
set (COMPILE_FLAGS "${COMPILE_FLAGS} -fPIE")
33-
# position independent code
3436

37+
# PETSc macros are long, line length is enforced in pre-receive hook:
3538
set (COMPILE_FLAGS "${COMPILE_FLAGS} -ffree-line-length-none")
36-
# PETSc macros are long, line length is enforced in pre-receive hook
3739

40+
# assume "implicit none" even if not present in source:
3841
set (COMPILE_FLAGS "${COMPILE_FLAGS} -fimplicit-none")
39-
# assume "implicit none" even if not present in source
4042

41-
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wall")
42-
# sets the following Fortran options:
43+
# set the following Fortran options:
4344
# -Waliasing: warn about possible aliasing of dummy arguments. Specifically, it warns if the same actual argument is associated with a dummy argument with "INTENT(IN)" and a dummy argument with "INTENT(OUT)" in a call with an explicit interface.
4445
# -Wampersand: checks if a character expression is continued proberly by an ampersand at the end of the line and at the beginning of the new line
4546
# -Warray-bounds: checks if array reference is out of bounds at compile time. use -fcheck-bounds to also check during runtime
@@ -53,7 +54,7 @@ set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wall")
5354
# -Wtarget-lifetime:
5455
# -Wreal-q-constant: warn about real-literal-constants with 'q' exponent-letter
5556
# -Wunused: a number of unused-xxx warnings
56-
# and sets the general (non-Fortran options) options:
57+
# and set the general (non-Fortran options) options:
5758
# -Waddress
5859
# -Warray-bounds (only with -O2)
5960
# -Wc++11-compat
@@ -78,12 +79,12 @@ set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wall")
7879
# -Wunused-value
7980
# -Wunused-variable
8081
# -Wvolatile-register-var
82+
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wall")
8183

82-
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wextra")
83-
# sets the following Fortran options:
84+
# set the following Fortran options:
8485
# -Wunuses-parameter:
8586
# -Wcompare-reals:
86-
# and sets the general (non-Fortran options) options:
87+
# and set the general (non-Fortran options) options:
8788
# -Wclobbered
8889
# -Wempty-body
8990
# -Wignored-qualifiers
@@ -94,50 +95,60 @@ set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wextra")
9495
# -Wuninitialized
9596
# -Wunused-but-set-parameter (only with -Wunused or -Wall)
9697
# -Wno-globals
98+
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wextra")
9799

100+
# warn if character expressions (strings) are truncated:
98101
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wcharacter-truncation")
99-
# warn if character expressions (strings) are truncated
100102

103+
# produce a warning when numerical constant expressions are encountered, which yield an UNDERFLOW
104+
# during compilation:
101105
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wunderflow")
102-
# produce a warning when numerical constant expressions are encountered, which yield an UNDERFLOW during compilation
103106

104107
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wsuggest-attribute=pure")
105108
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wsuggest-attribute=noreturn")
106109
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wconversion-extra")
107110
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wimplicit-procedure")
108111
set (COMPILE_FLAGS "${COMPILE_FLAGS} -Wunused-parameter")
112+
113+
# print summary of floating point exeptions (invalid,zero,overflow,underflow,inexact,denormal):
109114
set (COMPILE_FLAGS "${COMPILE_FLAGS} -ffpe-summary=all")
110-
# print summary of floating point exeptions (invalid,zero,overflow,underflow,inexact,denormal)
115+
116+
# https://gcc.gnu.org/onlinedocs/gfortran/IEEE-modules.html:
117+
set (COMPILE_FLAGS "${COMPILE_FLAGS} -fno-unsafe-math-optimizations")
118+
set (COMPILE_FLAGS "${COMPILE_FLAGS} -frounding-math")
119+
set (COMPILE_FLAGS "${COMPILE_FLAGS} -fsignaling-nans")
111120

112121
# Additional options
113122
# -Wimplicit-interface: no interfaces for lapack/MPI routines
114123
# -Wunsafe-loop-optimizations: warn if the loop cannot be optimized due to nontrivial assumptions
115124

116125
#------------------------------------------------------------------------------------------------
117126
# Runtime debugging
118-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -ffpe-trap=invalid,zero,overflow")
127+
#------------------------------------------------------------------------------------------------
128+
119129
# stop execution if floating point exception is detected (NaN is silent)
120130
# Additional options
121131
# -ffpe-trap=precision,denormal,underflow
132+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -ffpe-trap=invalid,zero,overflow")
122133

134+
# Generate symbolic debugging information in the object file:
123135
set (DEBUG_FLAGS "${DEBUG_FLAGS} -g")
124-
# Generate symbolic debugging information in the object file
125136

137+
# Optimize debugging experience:
126138
set (DEBUG_FLAGS "${DEBUG_FLAGS} -Og")
127-
# Optimize debugging experience
128139

140+
# checks for (array-temps,bounds,do,mem,pointer,recursion):
129141
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fbacktrace")
130142
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fdump-core")
131143
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fcheck=all")
132-
# checks for (array-temps,bounds,do,mem,pointer,recursion)
133144

145+
# Inserts a guard variable onto the stack frame for all functions:
134146
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fstack-protector-all")
135-
# Inserts a guard variable onto the stack frame for all functions
136147

148+
# "strange" values to simplify debugging:
137149
set (DEBUG_FLAGS "${DEBUG_FLAGS} -finit-real=snan -finit-integer=-2147483648")
138-
# "strange" values to simplify debugging
139150

140-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fsanitize=undefined")
141151
# detect undefined behavior
142152
# Additional options
143153
# -fsanitize=address,leak,thread
154+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fsanitize=undefined")

cmake/Compiler-IntelLLVM.cmake

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,39 +18,41 @@ endif ()
1818
# -assume std_mod_proc_name (included in -standard-semantics) causes problems if other modules
1919
# (PETSc, HDF5) are not compiled with this option (https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/62172)
2020
set (STANDARD_CHECK "-stand f23 -assume nostd_mod_proc_name")
21+
22+
# Link against shared Intel libraries instead of static ones:
2123
set (LINKER_FLAGS "${LINKER_FLAGS} -shared-intel")
22-
# Link against shared Intel libraries instead of static ones
24+
# enforce use of ifx for MPI wrapper:
2325
set (LINKER_FLAGS "${LINKER_FLAGS} -fc=ifx")
24-
# enforce use of ifx for MPI wrapper
2526

2627
#------------------------------------------------------------------------------------------------
2728
# Fine tuning compilation options
29+
#------------------------------------------------------------------------------------------------
30+
# disable flush underflow to zero, will be set if -O[1,2,3]:
2831
set (COMPILE_FLAGS "${COMPILE_FLAGS} -no-ftz")
29-
# disable flush underflow to zero, will be set if -O[1,2,3]
3032

33+
# disable warnings ...
3134
set (COMPILE_FLAGS "${COMPILE_FLAGS} -diag-disable")
32-
# disables warnings ...
33-
set (COMPILE_FLAGS "${COMPILE_FLAGS} 5268")
3435
# ... the text exceeds right hand column allowed on the line (enforced by pre-receive hook)
35-
set (COMPILE_FLAGS "${COMPILE_FLAGS},7624")
36+
set (COMPILE_FLAGS "${COMPILE_FLAGS} 5268")
3637
# ... about deprecated forall (has nice syntax and most likely a performance advantage)
38+
set (COMPILE_FLAGS "${COMPILE_FLAGS},7624")
3739

40+
# enable warnings ...
3841
set (COMPILE_FLAGS "${COMPILE_FLAGS} -warn")
39-
# enables warnings ...
40-
set (COMPILE_FLAGS "${COMPILE_FLAGS} declarations")
4142
# ... any undeclared names (alternative name: -implicitnone)
42-
set (COMPILE_FLAGS "${COMPILE_FLAGS},general")
43+
set (COMPILE_FLAGS "${COMPILE_FLAGS} declarations")
4344
# ... warning messages and informational messages are issued by the compiler
44-
set (COMPILE_FLAGS "${COMPILE_FLAGS},usage")
45+
set (COMPILE_FLAGS "${COMPILE_FLAGS},general")
4546
# ... questionable programming practices
46-
set (COMPILE_FLAGS "${COMPILE_FLAGS},interfaces")
47+
set (COMPILE_FLAGS "${COMPILE_FLAGS},usage")
4748
# ... checks the interfaces of all SUBROUTINEs called and FUNCTIONs invoked in your compilation against an external set of interface blocks
48-
set (COMPILE_FLAGS "${COMPILE_FLAGS},ignore_loc")
49+
set (COMPILE_FLAGS "${COMPILE_FLAGS},interfaces")
4950
# ... %LOC is stripped from an actual argument
50-
set (COMPILE_FLAGS "${COMPILE_FLAGS},alignments")
51+
set (COMPILE_FLAGS "${COMPILE_FLAGS},ignore_loc")
5152
# ... data that is not naturally aligned
52-
set (COMPILE_FLAGS "${COMPILE_FLAGS},unused")
53+
set (COMPILE_FLAGS "${COMPILE_FLAGS},alignments")
5354
# ... declared variables that are never used
55+
set (COMPILE_FLAGS "${COMPILE_FLAGS},unused")
5456

5557
# Additional options
5658
# -warn: enables warnings, where
@@ -62,55 +64,55 @@ set (COMPILE_FLAGS "${COMPILE_FLAGS},unused")
6264

6365
#------------------------------------------------------------------------------------------------
6466
# Runtime debugging
65-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -g")
67+
#------------------------------------------------------------------------------------------------
6668
# Generate symbolic debugging information in the object file
69+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -g")
6770

68-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -traceback")
6971
# Generate extra information in the object file to provide source file traceback information when a severe error occurs at run time
72+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -traceback")
7073

71-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -gen-interfaces")
7274
# Generate an interface block for each routine. http://software.intel.com/en-us/blogs/2012/01/05/doctor-fortran-gets-explicit-again/
75+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -gen-interfaces")
7376

74-
# set (DEBUG_FLAGS "${DEBUG_FLAGS} -fp-stack-check") not available on ifx 2025.0.4
7577
# Generate extra code after every function call to ensure that the floating-point (FP) stack is in the expected state
78+
# set (DEBUG_FLAGS "${DEBUG_FLAGS} -fp-stack-check") not available on ifx 2025.0.4
7679

77-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fp-model strict")
7880
# Trap uninitalized variables
81+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fp-model strict")
7982

83+
# Check at runtime ...
8084
set (DEBUG_FLAGS "${DEBUG_FLAGS} -check" )
81-
# Checks at runtime ...
82-
set (DEBUG_FLAGS "${DEBUG_FLAGS} bounds")
8385
# ... if an array index is too small (<1) or too large!
84-
set (DEBUG_FLAGS "${DEBUG_FLAGS},format")
86+
set (DEBUG_FLAGS "${DEBUG_FLAGS} bounds")
8587
# ... for the data type of an item being formatted for output.
86-
set (DEBUG_FLAGS "${DEBUG_FLAGS},output_conversion")
88+
set (DEBUG_FLAGS "${DEBUG_FLAGS},format")
8789
# ... for the fit of data items within a designated format descriptor field.
88-
set (DEBUG_FLAGS "${DEBUG_FLAGS},pointers")
90+
set (DEBUG_FLAGS "${DEBUG_FLAGS},output_conversion")
8991
# ... for certain disassociated or uninitialized pointers or unallocated allocatable objects.
90-
set (DEBUG_FLAGS "${DEBUG_FLAGS},nouninit") # https://fortran-lang.discourse.group/t/issue-with-stdlib-and-intel-oneapi-fortran-compiler-ifx-2024-0/7049/4
92+
set (DEBUG_FLAGS "${DEBUG_FLAGS},pointers")
9193
# ... for uninitialized variables.
92-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fpe-all=0 -ftz")
94+
set (DEBUG_FLAGS "${DEBUG_FLAGS},nouninit") # https://fortran-lang.discourse.group/t/issue-with-stdlib-and-intel-oneapi-fortran-compiler-ifx-2024-0/7049/4
9395
# ... capture all floating-point exceptions, need to overwrite -no-ftz
96+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -fpe-all=0 -ftz")
9497

98+
# Initialize logical to false, integer to -huge, float+complex to signaling NaN
9599
set (DEBUG_FLAGS "${DEBUG_FLAGS} -init=arrays,zero,minus_huge,snan")
96-
# ... initialize logical to false, integer to -huge, float+complex to signaling NaN
97100

98101
# disable due to compiler bug https://community.intel.com/t5/Intel-Fortran-Compiler/false-positive-stand-f18-and-IEEE-SELECTED-REAL-KIND/m-p/1227336
99-
#set (DEBUG_FLAGS "${DEBUG_FLAGS} -warn")
100102
# enables warnings ...
101-
#set (DEBUG_FLAGS "${DEBUG_FLAGS} errors")
103+
#set (DEBUG_FLAGS "${DEBUG_FLAGS} -warn")
102104
# ... warnings are changed to errors
103-
#set (DEBUG_FLAGS "${DEBUG_FLAGS},stderrors")
105+
#set (DEBUG_FLAGS "${DEBUG_FLAGS} errors")
104106
# ... warnings about Fortran standard violations are changed to errors
107+
#set (DEBUG_FLAGS "${DEBUG_FLAGS},stderrors")
105108

106-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -debug-parameters all")
107109
# generate debug information for parameters
110+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -debug-parameters all")
108111

109-
set (DEBUG_FLAGS "${DEBUG_FLAGS} -debug all")
110112
# generate complete debugging information
111-
112113
# Additional options
113114
# -heap-arrays: Should not be done for OpenMP, but set "ulimit -s unlimited" on shell. Probably it helps also to unlimit other limits
114115
# -check: Checks at runtime, where
115116
# arg_temp_created: will cause a lot of warnings because we create a bunch of temporary arrays (performance?)
116117
# stack:
118+
set (DEBUG_FLAGS "${DEBUG_FLAGS} -debug all")

python/tests/test_Rotation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,7 @@ def test_misorientation_360deg(self):
11281128

11291129
def test_misorientation_zero(self,set_of_quaternions,assert_allclose):
11301130
r = Rotation.from_quaternion(set_of_quaternions)
1131-
assert_allclose(r.misorientation_angle(r),0.,atol=1.e-8,rtol=0.)
1131+
assert_allclose(r.misorientation_angle(r),0.,atol=1.e-7,rtol=0.)
11321132
assert_allclose(r.misorientation(r).as_axis_angle(pair=True)[1],0.,atol=1.e-8,rtol=0.)
11331133

11341134
@pytest.mark.parametrize('shapes',[[None,None],

src/materialpoint.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ module materialpoint
5050
subroutine materialpoint_initAll()
5151

5252
call parallelization_init()
53-
call CLI_init() ! grid and mesh commandline interface
54-
call OS_init()
55-
call signal_init()
5653
call prec_init()
54+
call OS_init()
5755
call misc_init()
5856
call IO_init()
57+
call CLI_init() ! grid and mesh commandline interface
58+
call signal_init()
5959
#if defined(MESH) && (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR<18)
6060
call FEM_quadrature_init()
6161
#elif defined(GRID)

src/parallelization.f90

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,6 @@ subroutine parallelization_init()
8181
call PetscInitializeNoArguments(err_PETSc)
8282
CHKERRQ(err_PETSc)
8383

84-
#if defined(DEBUG)
85-
call PetscSetFPTrap(PETSC_FP_TRAP_ON,err_PETSc)
86-
#else
87-
call PetscSetFPTrap(PETSC_FP_TRAP_OFF,err_PETSc)
88-
#endif
89-
CHKERRQ(err_PETSc)
90-
9184
call PetscOptionsClear(PETSC_NULL_OPTIONS,err_PETSc)
9285
CHKERRQ(err_PETSc)
9386

src/prec.f90

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ module prec
5151
!--------------------------------------------------------------------------------------------------
5252
subroutine prec_init()
5353

54+
#ifdef PETSC
55+
PetscErrorCode :: err_PETSc
56+
#endif
57+
58+
5459
print'(/,1x,a)', '<<<+- prec init -+>>>'
5560

5661
print'(/,a,i0)', ' integer size / bit: ',bit_size(0)
@@ -61,6 +66,15 @@ subroutine prec_init()
6166
print'( a,e9.3)', ' epsilon value: ',PREAL_EPSILON
6267
print'( a,i0)', ' decimal precision: ',precision(0.0_pREAL)
6368

69+
#ifdef PETSC
70+
#ifdef DEBUG
71+
call PetscSetFPTrap(PETSC_FP_TRAP_ON,err_PETSc)
72+
#else
73+
call PetscSetFPTrap(PETSC_FP_TRAP_OFF,err_PETSc)
74+
#endif
75+
CHKERRQ(err_PETSc)
76+
#endif
77+
6478
call prec_selfTest()
6579

6680
end subroutine prec_init
@@ -252,12 +266,16 @@ subroutine prec_selfTest()
252266
real(pREAL), dimension(1) :: f
253267
integer(pI64), dimension(1) :: i
254268
real(pREAL), dimension(2) :: r
269+
#ifndef DEBUG
270+
real(pREAL) :: NaN
271+
#endif
255272
#ifdef PETSC
256273
PetscScalar :: dummy_scalar
257274

258275

259276
if (pREAL /= kind(dummy_scalar)) error stop 'PETSc and DAMASK scalar datatypes do not match'
260277
#endif
278+
261279
realloc_lhs_test = [1,2]
262280
if (any(realloc_lhs_test/=[1,2])) error stop 'LHS allocation'
263281

@@ -267,6 +285,31 @@ subroutine prec_selfTest()
267285
if (dEq(r(1),r(2)) .and. dNeq(r(1),r(2))) error stop 'dNeq'
268286
if (.not. all(dEq0(r-(r+PREAL_MIN)))) error stop 'dEq0'
269287

288+
! even silent NaN causes issues with PETSc's SetFPTrap
289+
#ifndef DEBUG
290+
NaN = IEEE_value(1.0_pREAL, IEEE_QUIET_NAN)
291+
292+
if (dEq(NaN,NaN)) error stop 'dEq/(NaN,NaN)'
293+
if (dEq(NaN,r(1))) error stop 'dEq/(NaN,float)'
294+
if (dEq(r(1),NaN)) error stop 'dEq/(float,NaN)'
295+
if (dEq0(NaN)) error stop 'dEq0/(NaN)'
296+
297+
if (.not. dNeq(NaN,NaN)) error stop 'dNeq/(NaN,NaN)'
298+
if (.not. dNeq(NaN,r(1))) error stop 'dNeq/(NaN,float)'
299+
if (.not. dNeq(r(1),NaN)) error stop 'dNeq/(float,NaN)'
300+
if (.not. dNeq0(NaN)) error stop 'dNeq0/(NaN)'
301+
302+
if (dEq(NaN,NaN,huge(1._pREAL))) error stop 'dEq/(NaN,NaN,tol)'
303+
if (dEq(NaN,r(1),huge(1._pREAL))) error stop 'dEq/(NaN,float,tol)'
304+
if (dEq(r(1),NaN,huge(1._pREAL))) error stop 'dEq/(float,NaN,tol)'
305+
if (dEq0(NaN,huge(1._pREAL))) error stop 'dEq0/(NaN,tol)'
306+
307+
if (.not. dNeq(NaN,NaN,huge(1._pREAL))) error stop 'dNeq/(NaN,NaN,tol)'
308+
if (.not. dNeq(NaN,r(1),huge(1._pREAL))) error stop 'dNeq/(NaN,float,tol)'
309+
if (.not. dNeq(r(1),NaN,huge(1._pREAL))) error stop 'dNeq/(float,NaN,tol)'
310+
if (.not. dNeq0(NaN,huge(1._pREAL))) error stop 'dNeq0/(NaN,tol)'
311+
#endif
312+
270313
! https://www.binaryconvert.com
271314
! https://www.rapidtables.com/convert/number/binary-to-decimal.html
272315
f = real(prec_bytesToC_FLOAT(int([-65,+11,-102,+75],C_SIGNED_CHAR)),pREAL)

0 commit comments

Comments
 (0)