6

i get the following warning at runtime:

...
forrtl: warning (402): fort: (1): In call to I/O Write routine, an array temporary was created for argument #2

forrtl: warning (402): fort: (1): In call to I/O Write routine, an array temporary was created for argument #3

forrtl: warning (402): fort: (1): In call to GERADHEIT_LINIAL, an array temporary was created for argument #2

forrtl: warning (402): fort: (1): In call to GERADHEIT_LINIAL, an array temporary was created for argument #3
...   

for every call of the subroutine / write statement.

The call of the subroutine:

integer :: l,kreise
character(*)::setname
real(8),diemnsion(:,:,:),allocatable::stripe
integer,dimension(:)s(j)

...code and allocation of arrays...
 do j=n(1)
   call geradheit_linial (s(j),stripe(j,1:s(j),1),
&                       stripe(j,1:s(j),2),setname)
 end do

...

subroutine geradheit_linial (ndaten,x,r,setname)
  implicit none
  integer,intent(in) :: ndaten
  real(8),dimension(ndaten),intent(in)  :: x,r
  character(*),intent(in) :: setname   

and the write statement:

    write(91,*)'Gerade: ',gerade(maxloc(reslt(1:i)),minsumloc,1),
&               gerade(maxloc(reslt(1:i)),minsumloc,2)

The array stripe is allocated with the maximum value expected for each dimension, so most of the time only a subset is passed through the call.

As far as i understand, it isn't really a problem in terms of accuracy but may slow down the program, hence a lot of writing to the RAM is done. So how much does it slow down my computation (stripe may have a dimension of about stripe(100,300,3) and could get bigger sometime later)? And how can i avoid such extra arrays?.

vaultah
  • 44,105
  • 12
  • 114
  • 143
why.n0t
  • 432
  • 7
  • 21
  • I notice that when I use a deffered size, e.g. real(8),dimension(:),intent(in) :: x,r , I don't see this warning.. – Charles Feb 10 '15 at 16:28

1 Answers1

7

I think that you are getting this warning because the subroutines are being passed non-contiguous array sections and the compiler has decided that the subroutine should get a contiguous temporary array containing the necessary values. I expect that the subroutine code is written in terms of an array and implicitly assumes, as we always do when programming in Fortran, that it is contiguous.

If I read your code correctly the compiler understands this statement

stripe(j,1:s(j),1)

to mean (as it were)

stripe(j,1,1)
stripe(j,2,1)
stripe(j,3,1)
...

Since, as I expect that you are aware, Fortran arrays are stored with the first index value changing most rapidly, your array section strides through memory.

You could suppress the warning with the compiler option noarg_temp_created. Note that this does only suppress the warning (which might save a smidgeon of the program's run time I suppose), it does not affect what the compiler does, the temporary arrays will still be created.

You could write code to create temporary arrays containing the section to be passed to the subroutine. I don't see much advantage in doing this; I'd expect the compiler to issue code that outperforms any code you write for such a straightforward operation.

Or you could reshape / permute your original array once, before starting to call the subroutine, and give it the right shape and arrangement for slicing into contiguous blocks. And then unpermute / unreshape at the end of all the calls.

The only conclusive way to answer your question about the relative performance of your current code and any alternative formulations is to code them up and get out your stopwatch.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
  • 1
    Maybe it is implicit in your answer, but two further points... If the array dummy argument in the procedure is assumed shape, then typically the compiler can generate code that accepts "regular" stride, non-contiguous arrays, as I think is happening here. The write statement report is probably (based on available code) because MAXLOC without DIM returns an array result - hence the subscript is a vector subscript which is likely to result in a temporary; add the DIM=1 specifier and the subscript would be scalar. – IanH Aug 13 '13 at 09:59
  • @IanH: yes, that's right, those points were implied by my answer, thanks for making them explicit :-) – High Performance Mark Aug 13 '13 at 10:06
  • Hi, i updated how the subroutine handels with its arguments. I know that the printing of th warning doesn't affect the speed much but i wont shut it up. I will change the layout of the array perhaps sometime later, but for now it seems good enough. (and thanks for the 'smidgeon of the program's run time', i like the sound of it ^^). – why.n0t Aug 13 '13 at 10:56
  • Wouldn't the reshaping and rereshaping of the arry consume at least as much speed as the array generation of the compiler since it will move the same amount of, or even more, data? Allthoug i don't know how the reshaping/permutating works... – why.n0t Aug 13 '13 at 11:01
  • @IanH the DIM=1 specifier got rid of the write warning, and cut computation time of by about 2sec. So a redesign of the array seems worthwhile... – why.n0t Aug 13 '13 at 11:18
  • Yes, I'd expect the reshaping to take time, but I don't know how much. If you are concerned or interested test and measure. – High Performance Mark Aug 13 '13 at 11:53
  • I changed the layout of some other arrays (they produced the same warning, but where simpler to alter), which reduced the walltime about 1sec. - 2sec. Which is a significant amount for me. An other bonus is, that now some loops are faster because the array is aligned to the Fortran storing method. Lesson learnd: Design arrays with care. – why.n0t Aug 14 '13 at 07:59