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 

WHERE gives runtime error
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
qt



Joined: 23 Aug 2005
Posts: 46
Location: Berlin, Germany

PostPosted: Mon Oct 30, 2006 9:03 am    Post subject: WHERE gives runtime error Reply with quote

Hi Paul,

here is another error Prof. Lassmann encounters:

The demonstration program Test_where leads to Error 112: Reference to undefined variable, array element or function result (/UNDEF).
It seems that this error is caused by the intrinsic function matmul, which might be the cause that some programs from Numerical Recipes do not run correctly.


Winapp

Program Test_where

Implicit None

Real , Dimension (1:2,1:2) :: u
Real , Dimension (1:2 ) :: b, w, tmp

u = +0.
u (1,1) = -1.
u (2,2) = -1.

b (1 ) = 1.
b (2 ) = 0.

w (1 ) = 1.
w (2 ) = 2.

Write (*,*) 'u = ', u
Write (*,*) 'b = ', b
Write (*,*) 'w = ', w

w = w - 1.

Write (*,*) 'w = ', w

! The following statement gives
! Error 112, Reference to undefined variable, array element
! or function result (/UNDEF)

where (w /= 0.0)
tmp=matmul(b,u)/w
elsewhere
tmp=0.0
end where

Write (*,*) 'tmp = ', tmp (1:2)

End Program Test_where

Back to top
View user's profile Send private message Visit poster's website
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Mon Oct 30, 2006 4:37 pm    Post subject: WHERE gives runtime error Reply with quote

I'd check Prof. Lassmann 's version of ftn95, as my Ver 4.9.1 does not produce the errors you are finding.

However, I do get " tmp = 0.00000 6.611829E-37" , rather than tmp = 0.0 0.0, so I'm not sure what is happening there.

Why not calculate MATMUL before the WHERE ?
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1886

PostPosted: Tue Oct 31, 2006 7:40 am    Post subject: WHERE gives runtime error Reply with quote

[small]John Campbell wrote:[/small]
I'd check Prof. Lassmann 's version of ftn95, as my Ver 4.9.1 does not produce the errors you are finding.

However, I do get " tmp = 0.00000 6.611829E-37" , rather than tmp = 0.0 0.0, so I'm not sure what is happening there.


To reproduce the "undefined" error, compile with the /undef option.

That this is a compiler bug is reinforced by running the program (with the /undef option used) under SDBG. The line with the WHERE statement is where an array element with an undefined value is reported to be accessed. However, inspecting the variables shows that none of the elements of w are undefined, nor are any elements of the variables on the right side of the assignment on the next line (b, u,w).


[small]John Campbell wrote:[/small]
Why not calculate MATMUL before the WHERE ?

That makes the bug go away! Working around compiler bugs that way is feasible only for toy programs.


MECEJ4
Back to top
View user's profile Send private message
DrTip



Joined: 01 Aug 2006
Posts: 74
Location: Manchester

PostPosted: Tue Oct 31, 2006 1:39 pm    Post subject: WHERE gives runtime error Reply with quote

MECEJ4

Although I do agree this *might* be a compiler bug and if it is should be fixed.

However in my humble opinion the previous suggestion of a work around is the non toy solution. In my company we have some programs with 3 hour+ runtimes, which rapidly goes up with when they are chained together in batches. They are mostly legacy FTN77 code compiled to FTN95. In this commercial environment which I guess is a non toy environment you go with what works, and you test every single component for numerical validity otherwise it bites you later.

I guess I am just saying not many commercial users have the time to wait for a new Compiler to be released!

Personally I also thought that the work around was actually more readable with no additional variables required.

I came up with exactly the same work around before John posted when I played with the code.

the reason I say it *might* be a compiler bug is that, does the code actually make sense?

I don't have my FTN95 standard handy but I rarely use the where construct but when I do I see it as a shorthand for a do/if combination. Expanding the where out you must do the matmul() first, ie outside the loop.


tmp = matmul(a,b)

do i=1,2
if (abs(w(i) > 0.0)) then
tmp(i) = tmp(i)/w(i)
else
tmp(i) = 0.0
end if
end do

I might have also gone for somethign like this


where (abs(w) > 0.0)
w = 1/w
end where

tmp = w*(matmul(a,b))


Another possible source of problems is the use of of (w /= 0.0) rather (abs(w) > 0.0) my compiler will give a warning in an if statement about unpredictable results with equalities and reals. (this examples seems to fit the bill to me)











Carl
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Tue Oct 31, 2006 3:57 pm    Post subject: WHERE gives runtime error Reply with quote

The probable cause of the error is that the compiler may calculate all values of MATMUL(a,b)/w, rather than only where W > 0.
A point I would also like to make is that in the 10 years that WHERE and FORALL have been available, I am yet to find a practical use for these constructs.
There was a spate of FORALL bugs a few years ago, which was the only time I tried to use FORALL. I gave up and used a DO loop and a few if statements. If the arrays become large, stack size limitations can make the temporary array values a problem for memory management, producing very inefficient solutions. There appears to be negligable performance improvement available, just the reduction in a few lines of DO constructs.
All WHERE appears to provide in this case is an inefficient way of programming that should be avoided.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Wed Nov 01, 2006 12:21 am    Post subject: WHERE gives runtime error Reply with quote

Joerg

I have just got back after a brief holiday and I will check out these items as soon as I can.
There are probably bugs to fix here and I can confirm this after one or two tests.

On the general point, WHERE and FORALL are designed for high performance Fortran (parallel processing) and will almost certainly be slower than alternative constructions under FTN95 which is designed for a single processor PC. There are known bugs in this area and although they need to be fixed (so that teachers can demonstrate their use), they have a relatively low priority. For most practical purposes WHERE and FORALL should be avoided when using FTN95.
Back to top
View user's profile Send private message AIM Address
DrTip



Joined: 01 Aug 2006
Posts: 74
Location: Manchester

PostPosted: Wed Nov 01, 2006 2:24 am    Post subject: WHERE gives runtime error Reply with quote

How true.

However getting rid of a few do loops can be a good thing the matrix = scalar construct is a great invention for initialisation. Very Happy The older code I maintain has massive 3 page subroutines given over to just to setting some multi rank arrays to 0. written in ftn95 these would be a lot more readable as A = 0.0 etc.

I am a big fan of readablity as I am picking up the pieces of people who weren't! With the newer constructs I decide whether the code is more or less readble with them and use them accordingly. Often they are less readable I would suggest the example here is an example of less readable.

Right I am goign to do some work Sad



Carl
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Mon Nov 06, 2006 2:08 am    Post subject: WHERE gives runtime error Reply with quote

Joerg

I have looked at this and although technically the code reveals a bug, I do not think that it is a serious one.

From the point of view of a) efficiency b) clarity and c) writing compiler friendly code, it would be better if matmul was applied before the WHERE statement.

t1 = matmul(b,u)
where (w /= 0.0)
tmp=t1/w
elsewhere
tmp=0.0
end where

When viewed as parallel processing statements this is essentially a two stage process and should be programmed as such.
Back to top
View user's profile Send private message AIM Address
KL
Guest





PostPosted: Fri Nov 17, 2006 8:41 am    Post subject: WHERE gives runtime error Reply with quote

Dear Paul,

I am the author of the "WHERE" problem. However, the program lines stem from the SVD algorithm of Numerical Recipes. When I found that this algorithm did not run, I extracted the error and came to the "WHERE" problem.

In my opinion it is not acceptable to recommend not to use an important Fortran 95 concept such as the WHERE construct. Other programs that use this construct should of course work with FTN95.

This is not the only problem that I found when I ran test problems from Numerical Recipes. I extracted several problems and Mr. Kuthe send these problems to the forum. Including the last 3 problems which I have sent to Mr. Kuthe I found 5 or 6 severe cases. In the case of the WHERE construct I would like to ask you to fix this problem.

Best regards

Klaus Lassmann



K. Lassmann
Back to top
PaulLaidler
Site Admin


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

PostPosted: Fri Nov 17, 2006 12:32 pm    Post subject: WHERE gives runtime error Reply with quote

Klaus

We can certainly have another look at this problem however, the reasons I suggested that the issue was not a serious one are
a) the problem only occurs when using /UNDEF and
b) the matrix multiplication should be placed before the WHERE construct otherwise it is likely that the compiler will calculate the whole vector result for each scan of the construct even though it will only use one element from the vector each time. In other words the calculation will be highly repetitive unless the compiler is clever enough to take the matrix product out of the construct for you. What you need inside the construct is essentially a dot product to return a scalar result rather than a full matrix multiplication that returns a vector but I could not think a way to program this.
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


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

PostPosted: Tue Nov 28, 2006 12:05 pm    Post subject: WHERE gives runtime error Reply with quote

Klaus

We have done some more work on this and this is how things appear to stand at the moment.

If you make a simple call to MATMUL within a WHERE construct then you will get the right answer (with FTN95) but the resulting assembly code is inefficient.

If you include MATMUL within an assignment expression (within a WHERE construct), as in your code, then FTN95 will probably give the wrong answer (as well as producing it in an inefficient way!).

It may take a while to fix this bug because the construction is highly complex. When it is fixed, the problem of inefficiency will not necessarily go away.

It seems natural to me to say that MATMUL returns an array whatever the context and, if the programmer only wants a particular element from the result, then they should provide the corresponding code. Having said this, it may still be possible to make FTN95 work in the way that you expect.
Back to top
View user's profile Send private message AIM Address
KL
Guest





PostPosted: Thu Nov 30, 2006 3:03 am    Post subject: WHERE gives runtime error Reply with quote

Dear Paul,

I am not sure whether you have received my more detailed message
on the WHERE problem. Here it is again, forget it if you had received it
already.

Dear Paul,

thank you very much for your answer. I have placed the matrix multiplication before
the where construct and it works. With the same modification, the SVD algorithm
from Numerical Recipes also runs. So we could consider the problem as being solved.

Nevertheless, I would like to ask you or your coworker to have another look to the
problem:

According to the Fortran 95 standard, the intrinsic function MATMUL is elemental.
(Of course all following arguments do not hold if this condition is not fulfilled).
If in the expression matmul (b, u) b has the shape m and u has shape m,n,
then the result has shape n. Element j has the value sum (b*u(:,j)) and it should
be possible
to devide this element j by w(j). So the algorithm of Numerical Recipes seems to
be correct. It is also efficient since it avoids the calculation
of element j when w(j) is zero. I guess that this is the reason why this algorithm
has been chosen in Numerical Recipes.

I have tested this problem with the little program "WHERE" below. Part 1 is the
FORTRAN 77 algorithm, that acts as a reference. Part 2 is
the modified and unmodified algorithm of Numerical
Recipes and part 3 is a simulation of the elemental treatment which should be
automatically included in Fortran 95.

It is interesting to note that the original algorithm from Numerical
Recipes seems to work correctly for n>m. So I guess that there is only a
minor error for n<=m.

It is also interesting to note that the modified algorithm leads to the
error "Access Violation" if m>n (This error has been reported already to the
forum and your answer to J. Kuthe was that this bug has been fixed).

To summarise: I am quite sure that the algorithm of
Numerical Recipes is correct and efficient (they normally think in
large system of equations) and that there might be a minor error in FTN95.

I have worked with FTN77 /95 since many years and I do hope that such a
discussion helps to increase the quality of FTN95.

Below
is the program. I am using FTN95 Version 4.7 and I have investigated
the problem with

Del *.lis
Del *.exe
Ftn95 Where.f95 /Checkmate /Link >> comp.lis
sdbg where.exe

!----------------------------------------------------------------------------------------
Winapp
Program Where

! ------------------------------------------------------------------

Implicit none

! ------------------------------------------------------------------

Integer , Parameter :: m = 5
Integer , Parameter :: n = 3

Real , Dimension (m,n) :: u
Real , Dimension (m ) :: b
Real , Dimension (n ) :: w
Real , Dimension (n ) :: tmp1, tmp2, tmp3
Real :: s
Integer :: i, j

u = 1.
b = 1.
w = 0.

w (1) = 1.

! ------------------------------------------------------------------
! FORTRAN 77 style

Do j = 1,n
s = 0.
if ( w (j) .ne. 0.) Then
do i = 1,m
s = s + u (i,j) * b (i)
end do
s = s / w (j)
end if
tmp1 (j) = s
End Do

Write (*,*) 'tmp1 = ', tmp1

! ------------------------------------------------------------------
! Modified and unmodified Fortran 95 style (see Numerical Recipes svbksb)

tmp2 = matmul (b,u)

where (w /= 0.0)
! Original statement from Numerical Recipes
! tmp2 = matmul (b,u)/w
tmp2 = tmp2/w
else where
tmp2=0.0
end where

! Write (*,*) 'tmp2 = ', tmp2 gives "Access Violation"
Write (*,*) 'tmp2 = ', tmp2 (1:n)

! ------------------------------------------------------------------
! "
Back to top
KL
Guest





PostPosted: Mon Dec 04, 2006 1:58 pm    Post subject: Where problem Reply with quote

Dear Paul,

as I can see from the forum, my message was incomplete. I try it again:

thank you very much for your answer. I have placed the matrix multiplication before
the where construct and it works. With the same modification, the SVD algorithm
from Numerical Recipes also runs. So we could consider the problem as being solved.

Nevertheless, I would like to ask you or your coworker to have another look to the
problem:

According to the Fortran 95 standard, the intrinsic function MATMUL is elemental.
(Of course all following arguments do not hold if this condition is not fulfilled).
If in the expression matmul (b, u) b has the shape m and u has shape m,n,
then the result has shape n. Element j has the value sum (b*u(:,j)) and it should
be possible
to devide this element j by w(j). So the algorithm of Numerical Recipes seems to
be correct. It is also efficient since it avoids the calculation
of element j when w(j) is zero. I guess that this is the reason why this algorithm
has been chosen in Numerical Recipes.

I have tested this problem with the little program "WHERE" below. Part 1 is the
FORTRAN 77 algorithm, that acts as a reference. Part 2 is
the modified and unmodified algorithm of Numerical
Recipes and part 3 is a simulation of the elemental treatment which should be
automatically included in Fortran 95.

It is interesting to note that the original algorithm from Numerical
Recipes seems to work correctly for n>m. So I guess that there is only a
minor error for n<=m.

It is also interesting to note that the modified algorithm leads to the
error "Access Violation" if m>n (This error has been reported already to the
forum and your answer to J. Kuthe was that this bug has been fixed).

To summarise: I am quite sure that the algorithm of
Numerical Recipes is correct and efficient (they normally think in
large system of equations) and that there might be a minor error in FTN95.

I have worked with FTN77 /95 since many years and I do hope that such a
discussion helps to increase the quality of FTN95.

Below
is the program. I am using FTN95 Version 4.7 and I have investigated
the problem with

Del *.lis
Del *.exe
Ftn95 Where.f95 /Checkmate /Link >> comp.lis
sdbg where.exe

!----------------------------------------------------------------------------------------
Winapp
Program Where

! ------------------------------------------------------------------

Implicit none

! ------------------------------------------------------------------

Integer , Parameter :: m = 5
Integer , Parameter :: n = 3

Real , Dimension (m,n) :: u
Real , Dimension (m ) :: b
Real , Dimension (n ) :: w
Real , Dimension (n ) :: tmp1, tmp2, tmp3
Real :: s
Integer :: i, j

u = 1.
b = 1.
w = 0.

w (1) = 1.

! ------------------------------------------------------------------
! FORTRAN 77 style

Do j = 1,n
s = 0.
if ( w (j) .ne. 0.) Then
do i = 1,m
s = s + u (i,j) * b (i)
end do
s = s / w (j)
end if
tmp1 (j) = s
End Do

Write (*,*) 'tmp1 = ', tmp1

! ------------------------------------------------------------------
! Modified and unmodified Fortran 95 style (see Numerical Recipes svbksb)

tmp2 = matmul (b,u)

where (w /= 0.0)
! Original statement from Numerical Recipes
! tmp2 = matmul (b,u)/w
tmp2 = tmp2/w
else where
tmp2=0.0
end where

! Write (*,*) 'tmp2 = ', tmp2 gives "Access Violation"
Write (*,*) 'tmp2 = ', tmp2 (1:n)

! ------------------------------------------------------------------
! "Simulation of Elemental Style"


Do j = 1,n

If ( w (j) .ne. 0. ) then
Back to top
KL
Guest





PostPosted: Mon Dec 04, 2006 2:01 pm    Post subject: Where Problem Reply with quote

Del *.lis
Del *.exe
Ftn95 Where.f95 /Checkmate /Link >> comp.lis
sdbg where.exe

!----------------------------------------------------------------------------------------
Winapp
Program Where

! ------------------------------------------------------------------

Implicit none

! ------------------------------------------------------------------

Integer , Parameter :: m = 5
Integer , Parameter :: n = 3

Real , Dimension (m,n) :: u
Real , Dimension (m ) :: b
Real , Dimension (n ) :: w
Real , Dimension (n ) :: tmp1, tmp2, tmp3
Real :: s
Integer :: i, j

u = 1.
b = 1.
w = 0.

w (1) = 1.

! ------------------------------------------------------------------
! FORTRAN 77 style

Do j = 1,n
s = 0.
if ( w (j) .ne. 0.) Then
do i = 1,m
s = s + u (i,j) * b (i)
end do
s = s / w (j)
end if
tmp1 (j) = s
End Do

Write (*,*) 'tmp1 = ', tmp1

! ------------------------------------------------------------------
! Modified and unmodified Fortran 95 style (see Numerical Recipes svbksb)

tmp2 = matmul (b,u)

where (w /= 0.0)
! Original statement from Numerical Recipes
! tmp2 = matmul (b,u)/w
tmp2 = tmp2/w
else where
tmp2=0.0
end where

! Write (*,*) 'tmp2 = ', tmp2 gives "Access Violation"
Write (*,*) 'tmp2 = ', tmp2 (1:n)

! ------------------------------------------------------------------
! "Simulation of Elemental Style"


Do j = 1,n

If ( w (j) .ne. 0. ) then
tmp3 (j) = sum ( b * u (:,j) ) / w (j)
Else
tmp3 (j) = 0.
End If

End Do

Write (*,*) 'tmp3 = ', tmp3 ! gives "Access Violation"
Write (*,*) 'tmp3 = ', tmp3 (1:n)

End Program Where
Back to top
PaulLaidler
Site Admin


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

PostPosted: Mon Dec 11, 2006 8:39 am    Post subject: Reply with quote

Thank you. This problem is already in the pipeline.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
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