2
votes

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?)

2
Please post the output you get from running the code, and what compilation command you are using. - Ross
For me, NqGT(1)%NqGvalT isn't allocated so the code errors even for loop 2.1 - Ross
The code requires a Fortran 2003 compiler. It appears to work for me. Which compiler and what compiler options are you using? - IanH
Welcome, be sure to take the tour and read How to 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
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.

2 Answers

3
votes

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.

0
votes

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.