2

I have the following piece of code:

program testdatatype

integer(8), parameter :: Stot= 2 
integer(8), dimension(Stot) :: Nf
integer(8) :: f, s, Qind
integer(8), dimension(:, :), allocatable :: NqG
real(16), dimension(:, :, :), allocatable :: d3xnormfac

type NqGtype
    integer(8), dimension(:, :), allocatable :: NqGvalT
end type NqGtype
type(NqGtype), dimension(Stot) :: NqGT

type d3xnormfactype
    real(16), dimension(:, :, :), allocatable :: d3xnormfacvalT
end type d3xnormfactype
type(d3xnormfactype), dimension(Stot) :: d3xnormfacT

! ----------------------------------------------------

! LOOP 1.1:

do s= 1, Stot, 1

    Nf(s)= 2d0

    write(*, *) 'NfLoop1.1= ', Nf(s)

end do

! LOOP 1.2:

do s= 1, Stot, 1

    write(*, *) 'NfLoop1.2= ', Nf(s)

end do

! ----------------------------------------------------

! LOOP 2.1:

do s= 1, Stot, 1

    allocate(NqG(Nf(s), Stot))

    do f= 1, Nf(s), 1

        NqG(f, s)= 5d0
        NqGT(s)%NqGvalT= NqG

        write(*, *) 'NqGLoop2.1= ', NqG(f, s)
        write(*, *) 'NqGTLoop2.1= ', NqGT(s)%NqGvalT(f, s)

    end do

    deallocate(NqG)

end do

! LOOP 2.2:

do s= 1, Stot, 1    
    do f= 1, Nf(s), 1

        write(*, *) 'NqGTLoop2.2= ', NqGT(s)%NqGvalT(f, s)

    end do
end do

! ----------------------------------------------------

! LOOP 3.1:

do s= 1, Stot, 1                    
    do f= 1, Nf(s), 1   

        allocate(d3xnormfac(Nf(s), Stot, NqGT(s)%NqGvalT(f, s)))

        do Qind= 1, NqGT(s)%NqGvalT(f, s)

            d3xnormfac(f, s, Qind)= 153d12
            d3xnormfacT(s)%d3xnormfacvalT= d3xnormfac

            write(*, *) 'd3xnormfacLoop3.1= ', d3xnormfac(f, s, Qind)
            write(*, *) 'd3xnormfacTLoop3.1= ', d3xnormfacT(s)%d3xnormfacvalT(f, s, Qind)

        end do  

        deallocate(d3xnormfac)

    end do
end do

! LOOP 3.2:

do s= 1, Stot, 1                    
    do f= 1, Nf(s), 1                       
        do Qind= 1, NqGT(s)%NqGvalT(f, s)

            write(*, *) 'd3xnormfacTLoop3.2= ', d3xnormfacT(s)%d3xnormfacvalT(f, s, Qind)

        end do
    end do
end do

! ----------------------------------------------------

end program testdatatype

I am compiling this .f90 file on a mpif90 compiler. As you can see when I run this code it is apparent that the write statement in Loop 1.1 gives the same as than in Loop 1.2, that is, the value of Nf(:) is correct for all s values outside of Loop 1.1. This is the same for Loop 2.1 and Loop 2.2 (this time creating a derived data type). The output for Loop 1 is the following:

 NfLoop1.1=                     2
 NfLoop1.1=                     2
 NfLoop1.2=                     2
 NfLoop1.2=                     2

I am able to call out any correct value of the data type NqGT(s)%NqGT(f, s) for any f and s value (in Loop 2.2) outside of the loop where it was created (Loop 2.1). There is no problem so far. When I run Loop 1 variables with Loop 2 the following output is given:

 NfLoop1.1=                     2
 NfLoop1.1=                     2
 NfLoop1.2=                     2
 NfLoop1.2=                     2
 NqGLoop2.1=                     5
 NqGTLoop2.1=                     5
 NqGLoop2.1=                     5
 NqGTLoop2.1=                     5
 NqGLoop2.1=                     5
 NqGTLoop2.1=                     5
 NqGLoop2.1=                     5
 NqGTLoop2.1=                     5
 NqGTLoop2.2=                     5
 NqGTLoop2.2=                     5
 NqGTLoop2.2=                     5
 NqGTLoop2.2=                     5

Furthermore, when running Loop 1 variables into Loop 2 derived data types, which in turn are used with Loop 3, the following output is given:

 NfLoop1.1=                     2
 NfLoop1.1=                     2
 NfLoop1.2=                     2
 NfLoop1.2=                     2
 NqGLoop2.1=                     5
 NqGTLoop2.1=                     5
 NqGLoop2.1=                     5
 NqGTLoop2.1=                     5
 NqGLoop2.1=                     5
 NqGTLoop2.1=                     5
 NqGLoop2.1=                     5
 NqGTLoop2.1=                     5
 NqGTLoop2.2=                     5
 NqGTLoop2.2=                     5
 NqGTLoop2.2=                     5
 NqGTLoop2.2=                     5
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=   -1.83360386755485123703987599430319601E-2466
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
 d3xnormfacTLoop3.2=    153000000000000.000000000000000000000

However, when I am trying to do the same for Loop 3.1 I can no longer get all of the correct values of the derived data type d3xnormfacT(s)%d3xnormfacvalT(f, s, Qind), that is, the data type printed in Loop 3.2 does not equal the values printed of the same data type in Loop 3.1 (some values are correct but other values are not). How can I fix this? I must be missing something (pointers and/or allocation with the derived data types?)

Rob A.
  • 21
  • 4
  • Please post the output you get from running the code, and what compilation command you are using. – Ross Jan 29 '18 at 20:28
  • For me, `NqGT(1)%NqGvalT` isn't allocated so the code errors even for loop 2.1 – Ross Jan 29 '18 at 20:29
  • The code requires a Fortran 2003 compiler. It appears to work for me. Which compiler and what compiler options are you using? – IanH Jan 29 '18 at 21:02
  • Welcome, be sure to take the [tour] and read [ask]. Try to always give the basic information such as the compiler you are using, its version, compiler flags used and the output including all error messages. – Vladimir F Героям слава Jan 29 '18 at 21:08
  • I have edited the text to include the output. At the command line I have < mpif90 -O3 testdatatype.f90 -o testfile > After this I call the executable as < ./testfile > Any Ideas why these numbers do not translate after being allocated in derived data types from three loops? – Rob A. Jan 29 '18 at 22:09
  • I'm writing up a complete answer, but do you know about automatic allocation, and do you intend to use it here? See: https://stackoverflow.com/questions/42140832/automatic-array-allocation-upon-assignment-in-fortran – Ross Jan 29 '18 at 22:26
  • I noticed that this problem is particular for when d3xnormfac and d3xnormfacT type is real(16). It works well when it is real(8). How can I get around this? – Rob A. Jan 29 '18 at 22:52
  • Do you intend to use automatic allocation? The problem is not specific to real(16) but may manifest easier when memory chunks are larger. – Ross Jan 29 '18 at 22:55
  • @RobA. My answer is posted. But you really must understand the implications of using automatic allocation if you do not already. – Ross Jan 29 '18 at 23:08

2 Answers2

3

Within loop 3.1 you are setting only a specific index of d3xnormfac but then assigning the entire d3xnormfac array to d3xnormfacT(s)%d3xnormfacvalT. Because d3xnormfac is deallocated and then allocated several times, the previously-assigned values are not guaranteed to still be set.

Because of your specific loop order, the values in d3xnormfac(:,1,:) are uninitialized. Depending on whether the compiler reallocates d3xnormfac to the same place and whether the memory is sanitized, the values may end up being correct. For my Intel (with -assume realloc-lhs to allow for automatic allocation), most of the values are correct. For my gfortran, most of the values are incorrect, as you see. The behavior likely depends on the type of real, too, which explains your observation.

A good way to see this is to initialize every value following allocation. Modifying your code to add this in loop 3.1:

        allocate(d3xnormfac(Nf(s), Stot, NqGT(s)%NqGvalT(f, s)))
        d3xnormfac = -1234     ! -- Added this line

        do Qind= 1, NqGT(s)%NqGvalT(f, s)

yields the following result:

mach5% ifort -assume realloc_lhs -check all -warn all -traceback -g main.f90 && ./a.out 
 NfIN=                      2
 NfIN=                      2
 NfOUT=                      2
 NfOUT=                      2
 NqGIN=                     15
 NqGTIN=                     15
 NqGIN=                     15
 NqGTIN=                     15
 NqGIN=                     15
 NqGTIN=                     15
 NqGIN=                     15
 NqGTIN=                     15
 NqGTOUT=                     15
 NqGTOUT=                     15
 NqGTOUT=                     15
 NqGTOUT=                     15
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacIN=    153000000000000.000000000000000000      
 d3xnormfacTIN=    153000000000000.000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=   -1234.00000000000000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000      
 d3xnormfacTOUT=    153000000000000.000000000000000000

You can see the portions which are still set to -1234.

After Clarification

I see now that this question comes from a misunderstanding of how allocatable arrays belong to derived types. d3xnormfacT(s)%d3xnormfacvalT is its own allocatable array. It is rank 3 and (until allocated) is unallocated. It is (typically) allocated with a regular allocate statement, such as:

allocate(d3xnormfacT(s)%d3xnormfacvalT((Nf(s), Stot, NqGT(s)%NqGvalT(f, s)))

You are not doing this. You are bypassing the traditional allocation by (unintentionally) using an advanced feature of fortran: automatic left-hand-side (lhs) allocation. When an array is assigned a value which matches its shape, the array is allocated or reallocated to match. More information is here: Automatic array allocation upon assignment in Fortran

Your statement:

        d3xnormfacT(s)%d3xnormfacvalT= d3xnormfac

is actually doing 2 things at once. First, d3xnormfacT(s)%d3xnormfacvalT is being allocated to match the sizes of d3xnormfac, because d3xnormfacT(s)%d3xnormfacvalT matches the shape (3-dimensional) of d3xnormfac. Second, the newly-allocated d3xnormfacT(s)%d3xnormfacvalT is being assigned the same values that d3xnormfac has. (Nobody is pointing to anything else.)

You should change your code to not use this automatic lhs allocation. This automatic lhs allocation is permitted by the 2003 standard but some compilers (Intel until 2017) deliberately do not support it by default. I personally think it's dangerous and unintuitive, so I typically avoid it. This feature can be a 'gotcha' for developers who are unaware of it. The gfortran (which I guess you are using, you only specify mpif90 which is just a wrapper) flag to prevent this from occuring is -fno-realloc-lhs.

Once you have changed your code, you will better understand the rest of my answer, which is the real reason why you see the problem you did.

Edit: As @eriktous points out, the same issue is present in your loop 2 but the loop order means no uninitialized values are ever put in output. I don't really understand why s indexes both the derived datatype and the outermost dimension of your array. Perhaps it's because this is just a toy case. If you're scaling this code up, be sure to fix both problems.

Ross
  • 2,130
  • 14
  • 25
  • The same issue is present in loop 2.1, by the way. – eriktous Jan 29 '18 at 23:14
  • Good point. It doesn't *manifest* as any initialized values in the output, though, because `NqGvalT` is only a 2D array. – Ross Jan 29 '18 at 23:18
  • @eriktous Edited to that effect – Ross Jan 29 '18 at 23:22
  • What exactly do you mean by lhs allocation to allocate NqGT(s)%NqGvalT and d3xnormfacT(s)%d3xnormfacvalT ? I am allocating the arrays in the loop with this statement: allocate(d3xnormfac(Nf(s), Stot, NqGT(s)%NqGvalT(f, s))) How exactly should I write this part or the declaration of the data type beforehand? – Rob A. Jan 30 '18 at 01:34
  • Right... this is exactly why I asked on the original question, but you didn't answer then. `d3xnormfacT(s)% d3xnormfacvalT` and `d3xnormfac` are *completely* different things. They occupy different spaces in memory and are not allocated together. I will update the answer to give a better overview for a beginner. – Ross Jan 30 '18 at 01:54
  • @RobA. Updated. Please read it and let me know if anything is unclear. – Ross Jan 30 '18 at 02:08
  • @Ross What would you recommend would be the best way to keep the array values (either of the original array or of its derived data type) outside of the three loops and access the values of the arrays by index (e.g. letting s= 1, f= 2, Qind= 3)? Thanks again! – Rob A. Jan 30 '18 at 03:50
  • @RobA. Sorry, I don't know what you mean. Do you have trouble with either a) the problem that makes some values of `d3xnormfacT(s)%d3xnormfacvalT` become uninitialized or b) the lhs automatic allocation? It seems like you're just asking what the best way to access elements of an array. – Ross Jan 30 '18 at 04:05
  • @Ross I respect your view on allocation on assignment, but I'm starting to think it's becoming a bit of a red herring in the context of this question. As I see it, the actual issue is referencing undefined variables. After the explicit allocation of NqG all four of its elements are undefined. On the first go through Loop 2.1, only one of the four elements of NqG is then set to a specific value, while the assignment statement `NqGT(s)%NqGvalT= NqG` next accesses all four elements. Right there the code becomes non-conforming and anything can happen. – eriktous Jan 30 '18 at 11:23
  • @eriktous Yep, the source of the observed problem exactly as you say, and that explanation is still the first part of the answer. But, based on the comment by Rob I think he would learn the most about his complete problem if he also understood that allocatable arrays defined as a component of derived data types must be allocated. – Ross Jan 30 '18 at 14:20
  • @francescalus good point, I hadn't realized they had changed. I've updated my answer to that effect. – Ross Jan 30 '18 at 14:20
  • @Ross a) The main problem is that the rank 3 arrays inside the 3 loops have allocatable dimensions that depend on the outer loop indices. When the arrays are deallocated after each inner loop, I am looking for a way to keep all array values after the loops have completed such that I can access them outside the loops later. There is no way to (directly) retain the values of the arrays after they have been deallocated at the end of an inner loop (the arrays are deallocated and resized in each iteration), regardless if the arrays are data types or not. – Rob A. Jan 30 '18 at 19:09
  • I guess you need to make it more clear what you are *trying* to do. The question you have asked (why is this value not what I expect) has been answered. Now it seems you have a different problem. Sounds to me like an XY issue: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Ross Jan 30 '18 at 19:37
  • I posted a solution that shows why the lhs automatic allocation works. Thanks for the help! – Rob A. Jan 30 '18 at 19:42
0

Adding the line d3xnormfac= 1234 after allocation as @Ross alluded to seems to ensure initialization. When Loop 2 is changed to the following:

! LOOP 2.1:

do s= 1, Stot, 1
    allocate(NqGT(1)%NqGvalT(Nf(s), Stot))
    allocate(NqG(Nf(s), Stot))

    do f= 1, Nf(s), 1
        NqG(f, s)= 5d0
        write(*, *) 'NqGLoop2.1= ', NqG(f, s)

        NqGT(1)%NqGvalT= NqG(:, :)      
        write(*, *) 'NqGTLoop2.1= ', NqGT(1)%NqGvalT(f, s)

    end do

    deallocate(NqG)
    deallocate(NqGT(1)%NqGvalT)
end do

! LOOP 2.2:

write(*, *) 'NqGTLoop2.2= ', NqGT(1)%NqGvalT(:, :)

with direct allocation of the derived data type array, the following error occurs from deallocating the array:

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x103880e46
#1  0x10388060c
#2  0x7fff59ff8f59
#3  0x1039095d5
#4  0x10390975e
#5  0x10390d0dd
#6  0x10367fbef
#7  0x10367fc9e
Segmentation fault: 11 

As a result, lhs automatic allocation of the derived data types is the reason why this error is not given initially. When only allocating d3xnormfac and leaving d3xnormfacT(s)%d3xnormfacvalT to be automatically allocated, the proper array values may be accessed after the 3 loops without error, as the derived data type arrays are not deallocated in an inner loop. As long as the derived data type arrays have constant dimensions, I suspect it shouldn't be a problem later. As for the complete initialization for the array values, the solution by @Ross seems to work. If used with caution, the lhs automatic allocation can work in this case.

Rob A.
  • 21
  • 4