10

I get the fortran runtime warning "An array temporary was created" when running my code (compiled with gfortran) and I would like to know if there is a better way to solve this warning.

My original code is something like this:

allocate(flx_est(lsign,3))
allocate(flx_err(lsign,3))
do i=1,lsign
call combflx_calc(flx_est(i,:),flx_err(i,:))
enddo

Inside the subroutine I define the variables like this:

subroutine combflx_calc(flx_est,flx_err)
use,intrinsic              :: ISO_Fortran_env, only: real64
implicit none
real(real64),intent(inout) :: flx_est(3),flx_err(3)

flux_est and flx_err vectors may change inside the subroutine depending on several conditions and I need to update their values accordingly.

Fortran does not seem to like this structure. I can solve it defining temporary variables:

tmp_flx_est=flx_est(i,:)
tmp_flx_err=flx_err(i,:)
call combflx_calc(tmp_flx_est,tmp_flx_err)
flx_est(i,:)=tmp_flx_est
flx_err(i,:)=tmp_flx_err

But it seems to me quite a silly way to fix it.

As you may see I'm not an expert with Fortran, so any help is more than welcome.

6
  • 2
    In what way is your "fix" fixing anything? The temporary is still there, you are just making it manually. Commented Mar 4, 2015 at 16:43
  • Not fixing, masking is better. I didn't see the potential harm of my initial approach so I just wanted to get rid of the warning Commented Mar 4, 2015 at 16:57
  • I disagree that masking is better than fixing. If you wanted to mask you could simply not compile with runtime checking enabled. Commented Mar 4, 2015 at 16:59
  • Most of often it is better to disable useless warning, than obfuscate the code, but it is your project. Commented Mar 4, 2015 at 16:59
  • I was requested to use the compilation flag for detecting warnings because I should not have any. I thought the warning was not dangerous, just minor compilation issue. But I now understand better the issue so I will try to really solve it. Thanks Commented Mar 4, 2015 at 17:05

2 Answers 2

16

One way is to pass an assumed shape array

real(real64),intent(inout) :: flx_est(:),flx_err(:)

the other is to exchange the dimensions of your array, so that you can pass a contiguous section of the 2D array.

call combflx_calc(flx_est(:,i),flx_err(:,i))

The problem is that the explicit size dummy arguments of your procedure (var(n)) require contiguous arrays. The assumed shape arrays can have some stride.

Sign up to request clarification or add additional context in comments.

6 Comments

Indeed when I use assumed-shape arguments I get "Error: Explicit interface required for 'combflx_calc' at (1): assumed-shape argument". But exchanging dimensions implies quite a huge and tedious work though. Thanks for your ideas!
It means what it says. You must have explicit interface. All procedures should be placed in a module.
I did: interface subroutine combflx_calc(flx_est,flx_err) use,intrinsic :: ISO_Fortran_env, only: real64 real(real64),intent(inout) :: flx_est(:),flx_err(:) end subroutine combflx_calc end interface It seems to work without warnings, do you think that's correct?
Interface blocks are also possible, but modern Fortran really prefers modules.
|
14

Your array temporary is being created because you are passing a strided array to your subroutine. Fortran arrays are column major so the leftmost index varies fastest in an array, or better said, the leftmost index is contiguous in memory and each variable to the right is strided over those to the left.

When you call

call combflx_calc(flx_est(i,:),flx_err(i,:))

These slices are arrays of your 3-vector strided by the length of lsign. The subroutine expects variables of a single dimension contiguous in memory, which the variable you pass into it is not. Thus, a temporary must be made for the subroutine to operate on and then copied back into your array slice.

Your "fix" does not change this, it just not longer warns about a temporary because you are using an explicitly created variable rather than the runtime doing it for you.

Vladimir's answer gives you options to avoid the temporary, so I will not duplicate them here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.