Reionization and NAG compiler

Use of Healpix, camb, CLASS, cosmomc, compilers, etc.
Post Reply
Vinicius Miranda
Posts: 9
Joined: August 20 2014
Affiliation: Upenn
Contact:

Reionization and NAG compiler

Post by Vinicius Miranda » November 28 2016

Dear Prof Lewis,

I tried to compile run the latest CAMB with NAG compiler and I got the following runtime error

Code: Select all

Runtime Error: reionization.f90, line 193: Reference to dangling pointer THISREION
Target was RETURNed from procedure REIONIZATION:REIONIZATION_GETOPTDEPTH
Program terminated by fatal error
I was able to compile the code without problems with the following flags (and using make default)

Code: Select all

F90C = nagfor
FFLAGS = -v -openmp -fpp -g -O0 -DNAGF95 -f2008 -C=all -info 
SFFLAGS =
F90CRLINK = 
MODOUT = 
SMODOUT = 
I understand CAMB is supposed to work only with IFORT/GFORTRAN but I wonder if this is a compiler error or some non-standard execution code

Best
Vinicius

Antony Lewis
Posts: 1364
Joined: September 23 2004
Affiliation: University of Sussex
Contact:

Re: Reionization and NAG compiler

Post by Antony Lewis » November 28 2016

I haven't tried the NAG compiler for years, and not sure what this is. You could try to compile with optimization rather than debug options - that may just be a run-time check error.

Vinicius Miranda
Posts: 9
Joined: August 20 2014
Affiliation: Upenn
Contact:

Reionization and NAG compiler

Post by Vinicius Miranda » November 28 2016

Thank you - this was indeed a runtime check.

Best
Vinicius

Vinicius Miranda
Posts: 9
Joined: August 20 2014
Affiliation: Upenn
Contact:

Reionization and NAG compiler

Post by Vinicius Miranda » November 29 2016

Dear Prof Lewis,

NAG Team took a look at this problem (they have very good support), and they wrote to me. According to them:
The CAMB Reionization module is essentially doing

Code: Select all

Module m
 Integer, Pointer, Private :: m_p
Contains
 Subroutine s1(p)
   Integer, Target :: p
   m_p => p
   Call s2(p)
 End Subroutine
 Subroutine s2(i)
   Integer :: i
   Call s3(i)
   Print *, m_p
 End Subroutine
 Subroutine s3(p)
   Integer, Target :: p
   m_p => p
 End Subroutine
End Module
Program foo
 Use m
 Integer :: i
 Call s1(i)
End Program
The fact that i in s2 does not have the Target attribute is what changes
the semantics of the code and makes m_p dangle after returning from s3.
The Fortran standard states

"If the dummy argument has the TARGET attribute and the effective
argument does not have the TARGET attribute or is an array section with
a vector subscript, any pointers associated with the dummy argument
become undefined when execution of the procedure completes."

I attach a patch to fix this. Note though that my code does not free the
cp%reion and cp%reionhist allocated in CAMBParams_Set.

I observe that the code still fails at runtime when checking for
undefined variables is active (-C=undefined) at the point that a deep
copy of a partly uninitialized derived type is attempted:

Runtime Error: camb.f90, line 125: Reference to undefined variable PARAMS
Program terminated by fatal error
camb.f90, line 125: Error occurred in CAMB:CAMB_GETRESULTS
inidriver.F90, line 321: Called by DRIVER

I suppose a solution to this, if some of the components of PARAMS being
set or not is conditional on the problem's state, might be to split the
data into smaller pieces (i.e. using smaller type definitions) to
reflect that. Or maybe to write a custom assignment routine to skip
components that are known to be uninitialized in certain contexts.

The code also fails when call checking is enabled (-C=calls)

Runtime Error: subroutines.f90, line 370: Invalid procedure reference -
Actual argument for dummy argument EV is derived-type instead of
REAL(real32)
Program terminated by fatal error
subroutines.f90, line 370: Error occurred in DVERK
recfast.f90, line 669: Called by RECOMBINATION:RECOMBINATION_INIT
modules.f90, line 2664: Called by THERMODATA:INITHERMO
cmbmain.f90, line 768: Called by CAMBMAIN:INITVARS
cmbmain.f90, line 157: Called by CAMBMAIN:CMBMAIN
camb.f90, line 137: Called by CAMB:CAMB_GETRESULTS
inidriver.F90, line 321: Called by DRIVER

I can see from the code that this is in some sense 'anticipated'.
Nevertheless, it is illegal Fortran. The suggestion in the code to use
Class (*) instead seems reasonable. Alternatively, what we do in such
cases in the NAG Library is just to 'cast' the data into an opaque c_ptr
type (using the facilities from the Fortran 2003 iso_c_binding module) -
a bit like a void * in C.
I can send you the patch if you want.
Best
Vinicius

Antony Lewis
Posts: 1364
Joined: September 23 2004
Affiliation: University of Sussex
Contact:

Re: Reionization and NAG compiler

Post by Antony Lewis » November 30 2016

Thanks - if you could make a pull request with the patch that would be great (http://github.com/cmbant/camb).

Post Reply