Quantcast
Channel: Intel® Software - Intel® Fortran Compiler for Linux* and macOS*
Viewing all articles
Browse latest Browse all 2746

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

$
0
0

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.


Viewing all articles
Browse latest Browse all 2746


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>