Community
cancel
Showing results for
Did you mean:
Highlighted
Beginner
29 Views

## Is there a chance to vectorize the "if-else" condition using omp simd function vectorization?

I am working with these codes (as I post below 2 codes: the original and with omp simd function vectorization). This is the original code, that I want to vectorize:

```    PROGRAM TEST
IMPLICIT NONE
REAL(KIND=8), DIMENSION(2000):: A,B,C
REAL(KIND=8)::TIME1,TIME2
INTEGER::I,K

!Initial condition
!\$OMP SIMD           !This part of course could be vectorized
DO I=1, 2000        !even without !\$OMP SIMD statement
A(I)=2.0+I/100
B(I)=1.0+I/200
C(I)=0.2+I/500
END DO
!\$OMP END SIMD

CALL CPU_TIME(TIME1)

DO K=1, 1000000
!\$OMP SIMD              !This part which I want to vectorize
DO I=1, 2000           !but of course it was not, since
IF(A(I)>0.0) THEN   !if-else statement exists
C(I)=A(I)+B(I)
ELSE
C(I)=2.0*I
END IF
END DO
!\$OMP END SIMD
END DO

CALL CPU_TIME(TIME2)

PRINT *, 'C(2000)           = ', C(2000)
PRINT *, 'Elapsed real time = ', TIME2-TIME1, 'second(s)'
END PROGRAM TEST```

I know when the "if-else" statement exists, the compiler couldn't do the auto-vectorization, and in my case it also didn't work even I've put !\$OMP DO SIMD, which is clear. And also to my knowledge only the intrinsic function could be vectorized automatically by the compiler. A few days ago, I just read a presentation which there is a chance to vectorize a function using "OMP SIMD FUNCTION VECTORIZATION". So I try changing the original code as below:

```    PROGRAM TEST
IMPLICIT NONE
REAL(KIND=8), DIMENSION(2000):: A,B,C
REAL(KIND=8)::TIME1,TIME2
REAL(KIND=8), EXTERNAL::VEC
INTEGER::I,K

!Initial condition
!\$OMP SIMD
DO I=1, 2000
A(I)=2.0+I/100
B(I)=1.0+I/200
C(I)=0.2+I/500
END DO
!\$OMP END SIMD

CALL CPU_TIME(TIME1)

DO K=1, 1000000
!\$OMP SIMD
DO I=1, 2000
C(I)=VEC(A(I),B(I),I)
END DO
!\$OMP END SIMD
END DO

CALL CPU_TIME(TIME2)

PRINT *, 'C(2000)           = ', C(2000)
PRINT *, 'Elapsed real time = ', TIME2-TIME1, 'second(s)'
END PROGRAM TEST

FUNCTION VEC(IN1,IN2,IN3) RESULT(OUT1)
IMPLICIT NONE
REAL(KIND=8)::IN1,IN2,OUT1
INTEGER::IN3

!IN1 = A(I)
!IN2 = B(I)
!IN3 = I

!\$OMP DECLARE SIMD(VEC)
IF(IN1>0.0) THEN
OUT1=IN1+IN2
ELSE
OUT1=2.0*IN3
END IF
END FUNCTION VEC```

but the vectorization still didn't work. Do you have any idea, how could I vectorize with this !\$OMP SIMD? Or it also couldn't be vectorized (it's just a same case with the failure of auto vectorization by the compiler when non-intrinsic function exists)? Any helps will be appreciated. Thanks in advance.

Tags (1)
Highlighted
Black Belt
29 Views

You didn't update this consistently when you edited it from the version you asked on stackoverflow. Did my comments appear there?

However, it's hard to guess how you could miss.  I don't have a Linux box here, but:

ifort -Qopt-report4 -align:array32byte -Qopenmp-simd bobby.f90

LOOP BEGIN at C:\users\tim\tim\tim\src\net\bobby.f90(20,13)
remark #15388: vectorization support: reference C(I) has aligned access
[ C:\users\tim\tim\tim\src\net\bobby.f90(22,19) ]
remark #15388: vectorization support: reference A(I) has aligned access
[ C:\users\tim\tim\tim\src\net\bobby.f90(22,24) ]
remark #15388: vectorization support: reference B(I) has aligned access
[ C:\users\tim\tim\tim\src\net\bobby.f90(22,29) ]
remark #15305: vectorization support: vector length 4
remark #15309: vectorization support: normalized vectorization overhead 0.
053
remark #15417: vectorization support: number of FP up converts: single pre
cision to double precision 1   [ C:\users\tim\tim\tim\src\net\bobby.f90(22,19) ]
remark #15301: OpenMP SIMD LOOP WAS VECTORIZED