Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28703 Discussions

Does IFC have operators like ANDALSO or ORELSE?

mtamiry
Beginner
1,244 Views
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
0 Kudos
1 Solution
IanH
Honored Contributor III
1,244 Views
Perhaps:

[cpp]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

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

View solution in original post

0 Kudos
11 Replies
TimP
Honored Contributor III
1,244 Views
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.

0 Kudos
mtamiry
Beginner
1,244 Views
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..

0 Kudos
GVautier
New Contributor II
1,244 Views
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.

0 Kudos
mtamiry
Beginner
1,244 Views
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
0 Kudos
Steven_L_Intel1
Employee
1,244 Views
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.
0 Kudos
TimP
Honored Contributor III
1,244 Views
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.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,244 Views

How about

[cpp]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
[/cpp]

Jim Dempsey

0 Kudos
IanH
Honored Contributor III
1,245 Views
Perhaps:

[cpp]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

[/cpp]
The various "condition_" bits being A < B or C(index) < B etc...
0 Kudos
schulzey
New Contributor I
1,244 Views

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.

0 Kudos
IanH
Honored Contributor III
1,244 Views

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

Your `Choice` variable might as well be logical.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,244 Views

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

Consider using the preprocessor (untested example):

[fortran]
#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)
[/fortran]

*** 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

0 Kudos
Reply