I'm updating some of my long-standing code to take advantage of the latest OpenMP 4.0 syntax, but I've come unstuck at the first attempt.
I decided to take a very simple, short subroutine that calculates a vector product: one of the vectors, 'normal' is unique, represented by its scalar components 'normal_x', 'normal_y' and 'normal_z', whilst the other vector 'rzero' is typically one of a large number of vectors represented by arrays of 'rzero_x', 'rzero_y' and 'rzero_z' components. Multiplying the normal by 'rzero' gives 'es', and taking the amplitude of 'es' gives us the sine of the angle between 'rzero' and the normal, viz:
elemental subroutine Calculate_Sines(normal_x, normal_y, normal_z, & rzero_x, rzero_y, rzero_z, & es_x, es_y, es_z, sin_theta) !$omp declare simd(Calculate_Sines) uniform(normal_x, normal_y, normal_z) real(kind(1d0)), intent(in) :: normal_x, normal_y, normal_z real(kind(1d0)), intent(in) :: rzero_x, rzero_y, rzero_z real(kind(1d0)), intent(out) :: es_x, es_y, es_z, sin_theta es_x = normal_z * rzero_y - normal_y * rzero_z es_y = normal_x * rzero_z - normal_z * rzero_x es_z = normal_y * rzero_x - normal_x * rzero_y sin_theta = sqrt( es_x**2 + es_y**2 + es_z**2 ) end subroutine Calculate_Sines
If I unit-test this by putting it into a program all on its own, then its works just as I'd expect: if I compile with /Qopt-report:2, then I am told:
15301: FUNCTION WAS VECTORIZED
...just as I'd hope. However, if I now take exactly the same code snippet and past it into the module where I actually want to use it (but as yet without having it actually invoked from anywhere else in the application), then compile with exactly the same relevant switches (/O2 /Qparallel /Qopenm /standard-semantics /Qopt-report:2) then I'm told:
warning #13397: vector function was not vectorized warning #13401: vector function was emulated
The compiler persistently refuses to give me any clues as to what may be preventing it from vectorising the function, even if I bump Qopt-report all the way up to 5.
So, what is going on here?