forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Implied DO LOOP and SUM Causes Error

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
viroxa



Joined: 28 Jul 2017
Posts: 78

PostPosted: Tue Aug 08, 2017 9:08 am    Post subject: Implied DO LOOP and SUM Causes Error Reply with quote

Good morning, everyone,

I have several implied DO LOOPs in my program. All of them work, except for those where SUM is used, for example:

Code:
!   Reshape is used, because implied DO LOOP returns 1D-array
    array=reshape([((sum(arrin(jcoun,kcoun,:),jcoun=1,ndima),kcoun=1,ndima)],shape(array))


It compiles without error, but at runtime an access violation occurs.

Whereas this works just fine:
Code:
      DO kcoun=1,ndima
         DO jcoun=1,ndima
            array(jcoun,kcoun)=sum(arrin(jcoun,kcoun,:))
            END DO
        END DO


Any ideas as to why that is would be greatly appreciated!
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Aug 08, 2017 10:08 am    Post subject: Reply with quote

Why would you want to use RESHAPE? Even if you can get it to work, it is much more difficult to read and surely can't be more efficient.

As it is I get a syntax error on compilation. An Emoticons?!
Back to top
View user's profile Send private message AIM Address
viroxa



Joined: 28 Jul 2017
Posts: 78

PostPosted: Tue Aug 08, 2017 10:39 am    Post subject: Reply with quote

I used RESHAPE, because the implied DO LOOP returns an array with rank=1 (vector), and I need rank 2 (matrix).
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Aug 08, 2017 10:43 am    Post subject: Reply with quote

What I mean is that the code that "works just fine" is easier to read and understand and is probably more efficient at runtime.
Back to top
View user's profile Send private message AIM Address
viroxa



Joined: 28 Jul 2017
Posts: 78

PostPosted: Tue Aug 08, 2017 10:47 am    Post subject: Reply with quote

It is? Good to know!
Because I read somewhere, that implied DO LOOPs are more efficient, than "normal" ones, so I tried using them, but it's quite a hassle.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Aug 08, 2017 11:34 am    Post subject: Reply with quote

I recommend that you ignore issues about efficiency particularly whilst you are learning to write in Fortran. Such issues only become of interest when your runtimes become unreasonably long. Concentrate on writing code that is error free, well documented, easy to read and (as far as is reasonable) "object oriented".
Back to top
View user's profile Send private message AIM Address
viroxa



Joined: 28 Jul 2017
Posts: 78

PostPosted: Tue Aug 08, 2017 12:25 pm    Post subject: Reply with quote

Alright, thanks for the advice!
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Tue Aug 08, 2017 4:03 pm    Post subject: Reply with quote

Paul, the compiler (8.1) generates incorrect code when the first argument to RESHAPE is an array constructor rather than an array variable in the following example, which I put together based on viroxa's posts in this thread.
Code:
program xreshape
implicit none
integer, parameter :: nx = 5, ny = 4, nz = 3
real,dimension(nx,ny,nz) :: arrin
real, dimension(nx*ny) :: sm
real, dimension(nx,ny) :: sma, smb
integer :: i,j,k
!
do i=1,nx; do j=1,ny; do k=1,nz; arrin(i,j,k)=100*k+10*j+i
   end do; end do; end do
sm = [((sum(arrin(i,j,:)),i=1,nx),j=1,ny)]
sma=reshape(sm,shape(sma))
write(*,10)(sma(i,:),i=1,nx)
smb=reshape([((sum(arrin(i,j,:)),i=1,nx),j=1,ny)],shape(smb))
write(*,*)
write(*,10)(smb(i,:),i=1,nx)
10 format(1x,4F12.1)
end program

The output has the second half incorrect:
Code:
        633.0       663.0       693.0       723.0
        636.0       666.0       696.0       726.0
        639.0       669.0       699.0       729.0
        642.0       672.0       702.0       732.0
        645.0       675.0       705.0       735.0

        542.0       542.0       542.0       542.0
        542.0       542.0       542.0       542.0
        542.0       542.0       542.0       542.0
        542.0       542.0       542.0       542.0
        542.0       542.0       542.0       542.0

If /check is used, a spurious subscript error message is generated in line 14.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Aug 08, 2017 4:20 pm    Post subject: Reply with quote

Mecej4

Thanks. I will make a note of this.
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Tue Aug 08, 2017 5:31 pm    Post subject: Reply with quote

Here is a shorter example that uses only 2-D and 1-D arrays and exhibits the same compiler bug. The use of RESHAPE is redundant, since the first argument already has the desired shape, but RESHAPE is needed to exhibit the bug.
Code:
program xreshape
implicit none
integer, parameter :: nx = 3, ny = 2
real,dimension(nx,ny) :: arrin
real, dimension(nx) :: sma, smb
integer :: i,j
!
do i=1,nx; do j=1,ny; arrin(i,j)=10*j+i
   end do; end do
sma = [(sum(arrin(i,:)),i=1,nx)]
write(*,10)sma
smb=reshape([(sum(arrin(i,:)),i=1,nx)],shape(smb))
write(*,*)
write(*,10)smb
10 format(1x,3F12.1)
end program
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Aug 08, 2017 5:35 pm    Post subject: Reply with quote

Mecej4

Thanks again.
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Fri Aug 11, 2017 4:06 am    Post subject: Reply with quote

Quote:
Whereas this works just fine:
DO kcoun=1,ndima
DO jcoun=1,ndima
array(jcoun,kcoun)=sum(arrin(jcoun,kcoun,:))
END DO
END DO


You need to learn about contiguous storage for arrays, which works from left to right. If array "arrin' is a large array, the performance would not be described as "fine".
A better arrangement would be :
array(jcoun,kcoun)=sum(arrin(:,jcoun,kcoun))

Large could be when the size of array arrin >> 64k, which would span many memory pages.

It is interesting reading your posts, as you use approaches I would not consider (such as RESHAPE). You will learn from this experience, which can be a good approach.
Back to top
View user's profile Send private message
viroxa



Joined: 28 Jul 2017
Posts: 78

PostPosted: Fri Aug 11, 2017 10:31 am    Post subject: Reply with quote

Thanks for pointing that out.

I arranged the array this way, because the assignment of arrin required it.
nlays could be 1, but could also be 100, depending on user input:

Code:
DO icoun=1,nlays
    DO jcoun=1,ndima
        DO kcoun=1,ndima
            arrin(kcoun,jcoun,icoun)=....
        END DO
    END DO
END DO


Since ndima = 4 and that nested loop calculating the sum is only run once, I didn't bother to rearrange the array. Should I?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group