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

Does IFC have operators like ANDALSO or ORELSE?

mtamiry
初学者
1,863 次查看
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 项奖励
1 解答
IanH
名誉分销商 III
1,863 次查看
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 项奖励
11 回复数
TimP
名誉分销商 III
1,863 次查看
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 项奖励
mtamiry
初学者
1,863 次查看
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 项奖励
GVautier
新分销商 III
1,863 次查看
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 项奖励
mtamiry
初学者
1,863 次查看
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 项奖励
Steven_L_Intel1
1,863 次查看
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 项奖励
TimP
名誉分销商 III
1,863 次查看
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 项奖励
jimdempseyatthecove
名誉分销商 III
1,863 次查看

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 项奖励
IanH
名誉分销商 III
1,864 次查看
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 项奖励
schulzey
新分销商 I
1,863 次查看

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 项奖励
IanH
名誉分销商 III
1,863 次查看

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

Your `Choice` variable might as well be logical.

0 项奖励
jimdempseyatthecove
名誉分销商 III
1,863 次查看

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 项奖励
回复