Does IFC have operators like ANDALSO or ORELSE?

Does IFC have operators like ANDALSO or ORELSE?

mtamiry's picture

Hi

We're trying to convert our old software from CVF to IVF. The problem is that, CVF when dealing with boolean operations, e.g. AND, if the first operand is false, would not evaluate the second operand, and using this we could reduce a lot of coding (instead of typing different IF statements for each case). But IFC seems to evaluate all of the operands, no matter they are needed to be evaluated or not. For instance, the following line (which our source has a lot of instances of it) crashes on intel compiler if IWEL=0 but not in compaq.

IF(...) THEN
ELSE IF(IWEL > 0.AND.WP(IWEL)%IPCODE(IP1) > 0) THEN
...
ELSE IF(IWEL > 0 .AND. WW(IWEL)%MATCH > 0) THEN
...
END IF

Is there any way to make this lines work the same as in CVF?

Thanks

12 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Tim Prince's picture
Quoting - mtamiry Hi

We're trying to convert our old software from CVF to IVF. The problem is that, CVF when dealing with boolean operations, e.g. AND, if the first operand is false, would not evaluate the second operand, and using this we could reduce a lot of coding (instead of typing different IF statements for each case). But IFC seems to evaluate all of the operands, no matter they are needed to be evaluated or not. For instance, the following line (which our source has a lot of instances of it) crashes on intel compiler if IWEL=0 but not in compaq.

IF(...) THEN
ELSE IF(IWEL > 0.AND.WP(IWEL)%IPCODE(IP1) > 0) THEN
...
ELSE IF(IWEL > 0 .AND. WW(IWEL)%MATCH > 0) THEN
...
END IF

Is there any way to make this lines work the same as in CVF?

Examples have been presented where CVF took advantage of Fortran syntax rules and changed the order of evaluation in compound conditionals, which would disprove your assertion that CVF didn't optimize them.
Did you mean
ELSE IF(IWEL > 0)
IF(WP(IWEL)%IPCODE(IP1) > 0) THEN
...
ELSE IF(WW(IWEL)%MATCH > 0) THEN

...
ENDIF
ENDIF
?
You can't expect correct optimizations to forgive mistakes on all compilers, even though they may have on some earlier compiler.

mtamiry's picture
Quoting - tim18 Examples have been presented where CVF took advantage of Fortran syntax rules and changed the order of evaluation in compound conditionals, which would disprove your assertion that CVF didn't optimize them.
Did you mean
ELSE IF(IWEL > 0)
IF(WP(IWEL)%IPCODE(IP1) > 0) THEN
...
ELSE IF(WW(IWEL)%MATCH > 0) THEN

...
ENDIF
ENDIF
?
You can't expect correct optimizations to forgive mistakes on all compilers, even though they may have on some earlier compiler.

No, the block I sent was correct. Actually it was only a single part of a very large condition checking (a lot of ELSE IFs and a single END IF at the end).

If we want to break the conditions, then a lot of codes must be duplicated (or even copied more). The obvoius solution would be to change the code from:

IF( Condition1 ) THEN
Stamements1
.
.
.
ELSE IF (Condition10) THEN
Statements10
ELSE IF(IWEL>0.AND.WP(IWEL)%IPCODE(IP1) > 0) THEN
Statements11
ELSE IF(IWEL>0.AND.WW(IWEL)%MATCH > 0) THEN
Statements12
ELSE IF( Condition 13) THEN
Statements13
.
.
.
ENDIF
-------------------------
to the following:

IF( Condition1 ) THEN
Stamements1
.
.
.
ELSE IF (Condition10) THEN
Statements10
ELSE IF(IWEL>0) THEN
IF (WP(IWEL)%IPCODE(IP1) > 0) THEN
Statements11
ELSE IF(IWEL>0.AND.WW(IWEL)%MATCH > 0) THEN
Statements12
ELSE
#Dear Compiler, please continue to check other conditions from Condition13 !!
END IF
ELSE IF( Condition13) THEN
Statements13
.
.
.
ENDIF

This would be really difficult since we even cannot use GOTO, and for some other cases the conditions are much more complicated that even breaking them would not result in just a couple of nested IF's.

The problem is that the code is really really old and absolutely huge and it's been working on CVF fine, and after we bought IVF 10.1 and made a lot of tiresome efforts to be able to compile it in IVF, in all such situations, it crashes.

My question is that, is it possible to tell IFC not to evaluate further conditions if the first operand of .AND. is .FALSE. or the first operand of .OR. is .TRUE.?

If it is not possible, is there any suggestions how to get rid of these crashes with the least possible code changes?

Thank you..

gvautier's picture

Hello

You where lucky if it works with CVF. I have to find and change all these occurences when porting from Powerstation, to CVF.

A solution can be changing :

ELSE IF(IWEL>0.AND.WW(IWEL)%MATCH > 0) THEN

to

ELSE IF(IWEL>0.AND.WW(max(1,IWEL))%MATCH > 0) THEN

The problem is to detect all occurences.

mtamiry's picture
Quoting - gvautier Hello

You where lucky if it works with CVF. I have to find and change all these occurences when porting from Powerstation, to CVF.

A solution can be changing :

ELSE IF(IWEL>0.AND.WW(IWEL)%MATCH > 0) THEN

to

ELSE IF(IWEL>0.AND.WW(max(1,IWEL))%MATCH > 0) THEN

The problem is to detect all occurences.

Hi

Maybe it can be named luck, but you can check CVF! In no case it crashes!!

But, it was a wise workaround if there is no other choice!
Actually it can save us quite a lot of effort. But SURE! as you mentioned it is really difficult to spot all occurences!!

Thank you

Steve Lionel (Intel)'s picture

CVF did not perform "short circuit evaluation". I saw many customer programs that demonstrated that. The order of evaluation of logical operations in CVF is whatever the optimizer thought best. I even wrote an article in 1999 on the topic.

Steve
Tim Prince's picture
Quoting - Steve Lionel (Intel) CVF did not perform "short circuit evaluation". I saw many customer programs that demonstrated that. The order of evaluation of logical operations in CVF is whatever the optimizer thought best. I even wrote an article in 1999 on the topic.

f2c was the most recent compiler I've seen which did support short circuit evaluation. Neither CVF nor g77 claimed compatibility with it; both tried to improve optimization in accordance with Fortran standards, going back to f66.

jimdempseyatthecove's picture

How about

IF( Condition1 ) THEN
Stamements1
.
.
.
ELSE IF (Condition10) THEN
Statements10
ELSE IF(IWEL>0.) THEN
  IF(WP(IWEL)%IPCODE(IP1) > 0) THEN
    Statements11
  ELSE IF(WW(IWEL)%MATCH > 0) THEN
     Statements12
  ENDIF
ELSE IF( Condition 13) THEN
Statements13
.
.
.
ENDIF

Jim Dempsey

www.quickthreadprogramming.com
IanH's picture
Best Reply

Perhaps:

PROGRAM put_condition_into_internal_proc
  IMPLICIT NONE
  ! ...rest of your program...
  IF (condition_1) THEN
    ! do_stuff...
  ELSE IF (condition_2) THEN
    ! do_stuff...
  ELSE IF (eval_condition_with_index_3()) THEN
    ! do_stuff...
  ELSE IF (eval_condition_with_index_4()) THEN
    ! do_stuff...
  ELSE IF (condition_3) THEN
    ! do_stuff...
  ELSE
    ! do_stuff...
  END IF
  ! ...rest of your program...  
CONTAINS
  FUNCTION eval_condition_with_index_3() RESULT
    LOGICAL r
    IF (index > 0) THEN
      IF (condition_with_index_3) THEN
        r = .TRUE.
        RETURN
      END IF
    END IF
    r = .FALSE.
  END FUNCTION eval_condition_with_index_3

  FUNCTION eval_condition_with_index_4() RESULT
    LOGICAL r
    IF (index > 0) THEN
      IF (condition_with_index_4) THEN
        r = .TRUE.
        RETURN
      END IF
    END IF
    r = .FALSE.
  END FUNCTION eval_condition_with_index_4
END PROGRAM put_condition_into_internal_proc

The various "condition_" bits being A < B or C(index) < B etc...

schulzey's picture

Has there been any change with Intel supporting "and-also" and "or-else" in the Intel Fortran v14.0 compiler?

It's a real pain to change my code so that something like the following doesn't crash when A=0:

if (A.gt.0.and.ARRAY(A).gt.10.0.and.B.eq.0) THEN
   Do something...
else
   Do something else... 
endif

The best way I can see to change the above code is something like the following:

Choice=0
if (A.gt.0) then
   if (ARRAY(A).gt.10.0.and.B.eq.0) Choice=1
endif
if (Choice.gt.0) then
   Do something...
else
   Do something else...
endif

Not very nice.

IanH's picture

No.  Operands for expressions may be evaluated in any order.  Buggy code is still buggy.

Your `Choice` variable might as well be logical.

jimdempseyatthecove's picture

The Fortran language does not assure left to rigth evaluation (others have stated this)

Consider using the preprocessor (untested example):

#define if_l2r(a, opab, b, opabc, c) 
if(a opab b) then 
l2r_ret = (.true. opabc c) 
else 
l2r_ret = .false. 
endif 
if(l2r_ret)

*** insert back slashes on #define continuation lines (forum editor chopped them off)

Use:

if_l2r(X, .ne., 0.0, .and., ((Y/X) .gt. 12.34)) then
... enter here for left to right condition without divide by zero possibility

Jim Dempsey

www.quickthreadprogramming.com

Login to leave a comment.