Fortran中高阶张量对称的BLAS

Fortran中高阶张量对称的BLAS,fortran,blas,Fortran,Blas,如果我有张量收缩 A[A,b]*b[b,c,d]=c[A,c,d] 哪个具有属性B[B,c,d]=B[B,d,c]和c[a,c,d]=c[a,d,c],如何设置BLAS以利用这种对称性 此处假定爱因斯坦求和符号,即重复指数平均求和 sgemm 似乎是关于矩阵的对称性,而不是秩3张量 我可以尝试将张量B展平/重塑为低维数组,但至少在Fortran中,展平/重塑张量似乎也需要时间。 矩阵运算C{acd}=A{ab}。B_{bcd}可以编程编写为matrix*vector操作的双循环(为了清晰起见,使

如果我有张量收缩
A[A,b]*b[b,c,d]=c[A,c,d]
哪个具有属性
B[B,c,d]=B[B,d,c]
c[a,c,d]=c[a,d,c]
,如何设置BLAS以利用这种对称性

此处假定爱因斯坦求和符号,即重复指数平均求和

sgemm
似乎是关于矩阵的对称性,而不是秩3张量

我可以尝试将张量
B
展平/重塑为低维数组,但至少在Fortran中,展平/重塑张量似乎也需要时间。
矩阵运算C{acd}=A{ab}。B_{bcd}可以编程编写为
matrix*vector
操作的双循环(为了清晰起见,使用matmul;根据需要替换为BLAS):

由于“
C[a,d,C]=C[a,C,d]
”,因此可以将
matmul
的方形循环替换为
matmul
的三角形循环和仅复制的三角形循环,如下所示:

n = size(B,3) ! = size(B,2)
do d=1,n
  do c=1,d
    C(:,c,d) = matmul(A(:,:), B(:,c,d))
  enddo
  
  do c=d+1,n
    C(:,c,d) = C(:,d,c)
  enddo
enddo

这利用了对称性来减少BLAS操作的数量,提高了性能,但必须进行大量的
matrix*vector
乘法,而不是一次大的
matrix*matrix
乘法,这将恶化性能。这种方法会整体提高还是降低性能?找出这个问题的最好方法可能是试试看。

矩阵运算C{acd}=A{ab}。B_{bcd}可以编程编写为
matrix*vector
操作的双循环(为了清晰起见,使用matmul;根据需要替换为BLAS):

由于“
C[a,d,C]=C[a,C,d]
”,因此可以将
matmul
的方形循环替换为
matmul
的三角形循环和仅复制的三角形循环,如下所示:

n = size(B,3) ! = size(B,2)
do d=1,n
  do c=1,d
    C(:,c,d) = matmul(A(:,:), B(:,c,d))
  enddo
  
  do c=d+1,n
    C(:,c,d) = C(:,d,c)
  enddo
enddo

这利用了对称性来减少BLAS操作的数量,提高了性能,但必须进行大量的
matrix*vector
乘法,而不是一次大的
matrix*matrix
乘法,这将恶化性能。这种方法会整体提高还是降低性能?找出这个问题的最好方法可能是试试看。

为什么需要利用对称性?DSYMM的性能通常与DGEMM相差不大,所以为什么不直接使用DGEMM,就像在第二个链接答案中一样?我认为如果存在对称性,我可以节省2倍的计算时间。如果BLAS不是这种情况,那么很好。尽管其中一个输入矩阵中有对称性,但输出()中不一定有对称性,因此您仍然需要生成相同数量的结果。因此,操作的数量是相同的。因此,对于零阶,时间是相同的。对称例程的主要用途是避免访问矩阵的一半,可能出于其他原因使用该一半。我认为在本例中,对称性得到了保留
C[a,d,C]=a[a,b]*b[b,d,C]=a[a,b]*b[b,C,d]=C[a,C,d]
,采用爱因斯坦求和符号。如果我使用嵌套循环,我可以对a=1,na使用
;对于b=1,nb;对于c=1,nc;对于d=1,nd
或对于a=1,na;对于b=1,nb;对于c=1,nc;对于d=1,nc然后在索引
C
d
中复制数组
C
的下一半。为什么需要利用对称性?DSYMM的性能通常与DGEMM相差不大,所以为什么不直接使用DGEMM,就像在第二个链接答案中一样?我认为如果存在对称性,我可以节省2倍的计算时间。如果BLAS不是这种情况,那么很好。尽管其中一个输入矩阵中有对称性,但输出()中不一定有对称性,因此您仍然需要生成相同数量的结果。因此,操作的数量是相同的。因此,对于零阶,时间是相同的。对称例程的主要用途是避免访问矩阵的一半,可能出于其他原因使用该一半。我认为在本例中,对称性得到了保留
C[a,d,C]=a[a,b]*b[b,d,C]=a[a,b]*b[b,C,d]=C[a,C,d]
,采用爱因斯坦求和符号。如果我使用嵌套循环,我可以对a=1,na使用
;对于b=1,nb;对于c=1,nc;对于d=1,nd
或对于a=1,na;对于b=1,nb;对于c=1,nc;对于d=1,nc然后在索引
C
d
中复制数组
C
的下一半。再次感谢您的回答。在使用DGEMM时,是否有办法指定数组
B
中使用的索引范围?按
K
in的大小?我应该从
B
的第一个索引开始计算吗?如果乘法是
B(c,:,d)
,有没有办法在DGEMM中指定?我尝试引入更小的维度数组,例如,
B_-small(:)=B(:,c,d)
c_-small(:)=c(:,c,d)
,操纵新数组需要相当多的时间time@AlphaF20你能把这个问题作为一个新问题提出来吗!我会的!我不知道我是否已经清楚地表达了我的问题。再次感谢你的回答。在使用DGEMM时,是否有办法指定数组
B
中使用的索引范围?按
K
in的大小?我应该从
B
的第一个索引开始计算吗?如果乘法是
B(c,:,d)
,有没有办法在DGEMM中指定?我尝试引入更小的维度数组,例如,
B_-small(:)=B(:,c,d)
c_-small(:)=c(:,c,d)
,操纵新数组需要相当多的时间time@AlphaF20你能把这个问题作为一个新问题提出来吗!我会的!我不知道我是否已经清楚地表达了我的问题