Fortran 可以将二维数组除以一维数组

Fortran possible to dot divide 2d array by 1d array

为了最大限度地提高速度,我尝试对以下内容进行矢量化(以使编译器能够按其认为好的方式进行矢量化):

integer  :: i,j
real :: a(4),b(4,5),c(4,5)
!... setting values to a and b...

do i=1,5
  do j=1,4
    c(j,i)=b(j,i)/a(i)
  end do
end do

我试过以下方法

c=b/a

但这不起作用:

error #6366: The shapes of the array expressions do not conform.

我的想法是,既然你可以做到 a/i,(数组/标量),我希望可以做到(二维数组/数组)。首先,b 和 c 的维度是 (5,4),我认为这就是问题所在,它需要符合第一行中排名较小的变量,但情况似乎并非如此。截至目前,我想知道是否有可能???还是我必须坚持使用 do 循环? (当然我可以对内部循环进行矢量化感到满意)

很高兴对此有任何评论或想法。 (我在 windows 上使用 ifort 16)

如果您还没有得到答案,看似 非向量化代码如下所示:

!Non-vectorized
do i=1,5
  do j=1,4
    c(j,i) = b(j,i) / a(j)
  enddo
enddo

看似矢量化版本如下:

!Vectorized
do i=1,5
  c(:,i) = b(:,i) / a(:)
enddo

但是 intel 编译器将它们都矢量化。要确定某个循环是否已向量化,请使用标志 -qopt-report-phase=vec。这会生成有关已编译程序的矢量化报告,并且是了解某个循环是否已矢量化的一种巧妙方法。

以上代码生成的向量化报告如图:

.... Beginning stuff...
LOOP BEGIN at vect_div.f90(11,5)
remark #15542: loop was not vectorized: inner loop was already vectorized

 LOOP BEGIN at vect_div.f90(12,5)
    remark #15300: LOOP WAS VECTORIZED
 LOOP END
LOOP END

LOOP BEGIN at vect_div.f90(18,5)
remark #15542: loop was not vectorized: inner loop was already vectorized

 LOOP BEGIN at vect_div.f90(19,7)
    remark #15300: LOOP WAS VECTORIZED
 LOOP END
LOOP END

这里,(11,5)、(12,5) 等是我的 .f90 文本文件中存在 do 关键字的行号和列号。您可能会注意到,外部循环未矢量化,而内部循环是。它们都是矢量化的,也没有任何明显的区别。

通过更改 ifort 标志中的 'n' 值可以生成更详细的报告 -qopt-report=[n]