Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Problem copying arrays of derived types with allocatable components (IVF 2018)

Arjen_Markus
Honored Contributor I
977 Views

We experience a problem with copying arrays of derived types that contain allocatable components. The problem is illustrated with the program below:

module mymodule
    implicit none

    type mydata
        real, allocatable, dimension(:) :: value
    end type mydata
end module mymodule

program test_copy
    use mymodule
    implicit none

    type(mydata), dimension(5) :: array1
    type(mydata), dimension(2,5) :: array2
    integer :: i


    allocate( array1(1)%value(10) )
    allocate( array1(2)%value(10) )
    allocate( array1(5)%value(10) )

    array2(1,:) = array1
    array2(2,:) = array1

    do i = 1,size(array1)
        write(*,*) i, allocated(array1(i)%value), allocated(array2(1,i)%value), &
                                                  allocated(array2(2,i)%value)
    enddo
end program test_copy

The output is:

           1 T T T
           2 T F F
           3 F T F
           4 F F F
           5 T F F

whereas I expected (as indeed provided by gfortran):

           1 T T T
           2 T T T
           3 F F F
           4 F F F
           5 T T T 

This does not occur with copying one-dimensional arrays in this way.

The compiler version I use is: Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 18.0.5.274 Build 20180823

 

 

0 Kudos
9 Replies
Johannes_Rieke
New Contributor III
977 Views

Hi Arjen,

PSXE 2019 update 1 seem to deliver the correct results (PSXE 2019 initial also). Gfortran is in my opinion doing it correctly. PSXE 2018 update 3 fails, also like update 5.

D:\Folder\alloc_test_PSXE2019>ifort test.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.1.144 Build 20181018
Copyright (C) 1985-2018 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:test.exe
-subsystem:console
test.obj

D:\Folder\alloc_test_PSXE2019>test.exe
           1 T T T
           2 T T T
           3 F F F
           4 F F F
           5 T T T

I remember there were also some issues with intent and allocation status with PSXE2018 (not sure about the updates).

0 Kudos
Arjen_Markus
Honored Contributor I
977 Views

Ah, good to hear that the issue has already been solved.

As I have located it in our source code it was easy enough to create a workaround, but it was a nasty surprise

0 Kudos
FortranFan
Honored Contributor II
977 Views

It looks like a compiler bug in that version of Intel Fortran; it appears fixed in 19.0 update 1 where the output is as expected in agreement with what's shown in the original post with gfortran.

You may want to submit a support request at the Intel Online Service Center (OSC) to discuss your options.

 

0 Kudos
John_Campbell
New Contributor II
977 Views
Could I ask what should be the result for the following addition of using sizeof to the example code. module mymodule implicit none type mydata real, allocatable, dimension(:) :: value end type mydata end module mymodule program test_copy use mymodule implicit none type(mydata), dimension(5) :: array1 type(mydata), dimension(2,5) :: array2 integer :: i write (*,*) 'sizeof array1 =', sizeof(array1) write (*,*) 'sizeof array2 =', sizeof(array2) allocate( array1(1)%value(10) ) allocate( array1(2)%value(10) ) allocate( array1(5)%value(10) ) write (*,*) 'sizeof array1 =', sizeof(array1) write (*,*) 'sizeof array2 =', sizeof(array2) array2(1,:) = array1 array2(2,:) = array1 write (*,*) 'sizeof array1 =', sizeof(array1) write (*,*) 'sizeof array2 =', sizeof(array2) do i = 1,size(array1) write(*,*) i, allocated(array1(i)%value), allocated(array2(1,i)%value), & allocated(array2(2,i)%value) enddo end program test_copy
0 Kudos
Arjen_Markus
Honored Contributor I
977 Views

I tried this with both Intel Fortran and gfortran and got very similar results: sizeof(array2) =  2 * sizeof(array1) and the numbers are constant throughout the program. That is: the allocated array components are not part of the sizeof() result.

0 Kudos
John_Campbell
New Contributor II
977 Views

Arjen Markus wrote:

I tried this with both Intel Fortran and gfortran and got very similar results: sizeof(array2) =  2 * sizeof(array1) and the numbers are constant throughout the program. That is: the allocated array components are not part of the sizeof() result.

That is my finding also. SIZEOF appears to report the size of the derived type array definition (which is interesting if correct), but not it's allocated components. I am not sure if this is a feature of SIZEOF or an error which both ifort and gfortran report ?

I would prefer that SIZEOF reports both the size of the structure and the allocatable components, which in the OP would indicate how many components were allocated.

0 Kudos
Arjen_Markus
Honored Contributor I
977 Views

Well, SIZEOF() is not standard Fortran and it is documented to give just the space occupied by the argument, not including any of its allocatable or pointer components. It is more or less equivalent to the C macro by that name (in lower-case).

Of course, it would have been nice if it had included the allocated bits and pieces ...

0 Kudos
LRaim
New Contributor I
977 Views

How is it possible that SIZEOF takes care of allocated component ?  Starting from a user defined type one can have a chain of allocated elements ? A user should always think what he/she would be able to do in developing a compiler. 

0 Kudos
Steve_Lionel
Honored Contributor III
977 Views

SIZEOF is telling you the size of the thing without chasing down pointers and allocatables. If there are pointers or allocatables, the size includes the size of the descriptors.

0 Kudos
Reply