Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

why is my copy subroutine not called for arrays?

117 views
Skip to first unread message

Martin Keiter

unread,
Feb 20, 2020, 6:51:40 PM2/20/20
to
Hi,

as I am new to newer fortran, I apologize for maybe making obvious
mistakes. I ran into a a bug in my program, which I could trace down to
the copy subroutine not working for an array, but only for individual
copies. I stripped all overhead and a code to reproduce is this:


module fail
implicit NONE
private
public :: ele
type ele
integer :: int
contains
procedure, pass(this) :: Copy_ele
generic, public :: assignment(=) => Copy_ele
end type ele
contains
subroutine copy_ele(this, from)
class (ele), intent(inout) :: this
class (ele), intent(in) :: from
print *, 'in copy_ele'
this%int = from%int
end subroutine copy_ele
end module fail

program test
use fail
implicit NONE
type(ele), pointer, dimension(:) :: e1, e2
integer, parameter :: n = 10
integer i

allocate(e1(n), e2(n))
do i = 1, n
e1(i)%int = i
end do
print *, 'copy array'
e2 = e1
print *, 'copy individuals'
do i = 1, n
e2(i) = e1(i)
enddo
deallocate(e1, e2)
end program test


which outputs (with ifort 19 and gfortran)

copy array
copy individuals
in copy_ele
in copy_ele
in copy_ele
in copy_ele
in copy_ele
in copy_ele
in copy_ele
in copy_ele
in copy_ele
in copy_ele

so, when copying the whole array, my copy subroutine is not called at
all.
In my 'real' program, 'int' is of some other derived type, which has
a pointer as its element, and the result is, that the pointer (its address)
is copied instead of invoking the copy subroutine of the derived type
and copying the data.
I do not understand this behaviour. It was very unexpected for me and I
spent quite some hours to detect the source of the error.
What am I understanding incorrectly?

Thanks,

Martin


FortranFan

unread,
Feb 20, 2020, 7:18:06 PM2/20/20
to
On Thursday, February 20, 2020 at 6:51:40 PM UTC-5, Martin Keiter wrote:

> Hi,
>
> as I am new to newer fortran, I apologize for maybe making obvious
> mistakes. ..
> I do not understand this behaviour. It was very unexpected for me and I
> spent quite some hours to detect the source of the error.
> What am I understanding incorrectly?
> ..


@Martin Keiter,

Look up ELEMENTAL attribute of subprograms in Fortran. While at it, look up IMPURE also which you will need if you attempt IO (e.g., PRINT statements) for debugging purposes.

David Billinghurst

unread,
Feb 20, 2020, 8:26:33 PM2/20/20
to
Exactly. Changing the subroutine declaration to:

impure elemental subroutine copy_ele(this, from)

gives (with gfortran 7.4.0)

$ ./test2
copy array
in copy_ele
[ 8 lines deleted ]
in copy_ele
copy individuals
in copy_ele
[ 8 lines deleted ]
in copy_ele

FortranFan

unread,
Feb 20, 2020, 11:00:34 PM2/20/20
to
On Thursday, February 20, 2020 at 6:51:40 PM UTC-5, Martin Keiter wrote:

> .. I ran into a a bug in my program, which I could trace down to
> the copy subroutine not working for an array, but only for individual
> copies. ..
>
> which outputs (with ifort 19 and gfortran)
> ..


To OP and other interested readers using Intel Fortran and/or gfortran,

You may know another thread recently on this forum touched upon the same topic involving type-bound procedure for a defined assignment and the ELEMENTAL attribute: https://groups.google.com/d/msg/comp.lang.fortran/q6CPgOdmlss/OJFwkUNbGAAJ

And as I stated therein, there are a couple of scenarios where one or both the compilers of Intel Fortran and gfortran show unexpected behavior relative to the Fortran standard, at least per my read of it.

1) A derived type containing a component which is a derived type extended from another type that has the defined assignment.

--- begin case 1 ---
module b_m
type :: b_t
integer :: i = 0
logical :: defined_assignment = .false.
contains
procedure, pass(lhs) :: assign_b_t
generic :: assignment(=) => assign_b_t
end type
contains
elemental subroutine assign_b_t( lhs, rhs )
! Argument list
class(b_t), intent(inout) :: lhs
class(b_t), intent(in) :: rhs
lhs%i = rhs%i
lhs%defined_assignment = .true.
end subroutine
end module

program case1

use b_m, only : b_t

type, extends(b_t) :: e_t
end type

type :: f_t
type(e_t) :: e
end type

type(f_t) :: foo(2), bar(2)

bar = foo
print *, "bar(1)%e%defined_assignment = ", bar(1)%e%defined_assignment, "; expected value is T."
if ( .not. bar(1)%e%defined_assignment ) error stop "Program did not work as expected."
stop "SUCCESS"

end program case1
--- begin case 1 ---

Upon execution of program compiled using gfortran, the run-time behavior is:
bar(1)%e%defined_assignment = F ; expected value is T.
ERROR STOP Program did not work as expected.

Error termination. Backtrace:

Could not print backtrace: libbacktrace could not find executable to open
#0 0xffffffff
#1 0xffffffff
#2 0xffffffff
#3 0xffffffff
#4 0xffffffff
#5 0xffffffff
#6 0xffffffff
#7 0xffffffff
#8 0xffffffff
#9 0xffffffff

And similar output is generated using Intel Fortran as well.

2) But now, Intel Fortran has an issue processing an even simpler scenario involving a derived type containing a component which is a derived type with a defined assignment:

--- begin case 2 ---
module b_m
type :: b_t
integer :: i = 0
logical :: defined_assignment = .false.
contains
procedure, pass(lhs) :: assign_b_t
generic :: assignment(=) => assign_b_t
end type
contains
elemental subroutine assign_b_t( lhs, rhs )
! Argument list
class(b_t), intent(inout) :: lhs
class(b_t), intent(in) :: rhs
lhs%i = rhs%i
lhs%defined_assignment = .true.
end subroutine
end module

program case2

use b_m, only : b_t

type :: c_t
type(b_t) :: b
end type

type(c_t) :: foo(2), bar(2)

bar = foo
print *, "bar(1)%b%defined_assignment = ", bar(1)%b%defined_assignment, "; expected value is T."
if ( .not. bar(1)%b%defined_assignment ) error stop "Program did not work as expected."
stop "SUCCESS"

end program case2
--- end case 2 ---

gfortran works as I expect in this case but with Intel Fortran the program output unexpectedly is as follows:

bar(1)%b%defined_assignment = F ; expected value is T.
Program did not work as expected.

Martin Keiter

unread,
Feb 21, 2020, 10:58:19 AM2/21/20
to
OK, kind of obvius probably. Thanks!

I got this book
https://www.oxfordscholarship.com/view/10.1093/oso/9780198811893.001.0001/oso-9780198811893
from the library now. Is it good, or would you recommend another one?

baf

unread,
Feb 22, 2020, 2:24:26 AM2/22/20
to
That is an exceptional reference book.
0 new messages