mgilson
mgilson

Reputation: 310049

How can I efficiently transpose array and assign to an array with a different type

Consider the following:

program main
integer, parameter :: n=10, m=20
integer ints(n,m)
real floats(m,n)

!... initialize ints
! ...

floats=transpose(ints)
!... do stuff with floats

end

looking at the documentation for gfortran, it seems that transpose(ints) will return an integer array which will then be cast to reals. In this operation, the compiler (gfortran) creates a temporary array for the transposed array which seems like a waste (compile with gfortran -O3 -Warray-temporaries -o test test.f90). Also note that if you change the real array "floats" into an integer array, the warning goes away.

Is there a way to do this (for arbitrary types) without generating a temporary array? (I also tried floats(:,:)=transpose(ints) because I read somewhere that it mattered ... ). Does it behave this way with other compilers?

Upvotes: 1

Views: 5755

Answers (2)

bdforbes
bdforbes

Reputation: 1556

do i = 1, n
do j = 1, m
    floats(j,i) = real(ints(i,j))
enddo
enddo

You could make your own transpose interface for handling different data types, although it would have to be a subroutine and not a function.

interface transpose_
    module procedure transpose_ints_to_reals
end interface

subroutine transpose_ints_to_reals(ints_in, reals_out)
...
end subroutine

call transpose_(ints,floats)

Upvotes: 1

High Performance Mark
High Performance Mark

Reputation: 78344

You could try

floats = transpose(real(ints))

but I wouldn't be very surprised if gfortran (or any other compiler) generated a temporary array to implement this. I'd be more surprised if it didn't.

You might also try

forall (J=1:N, K=1:M) floats(K, J) = real(ints(J, K))

Again, I wouldn't be surprised if a compiler created a temporary array to implement this.

Upvotes: 2

Related Questions