Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matrix 单位Fortran DGEMM上的Lapack矩阵乘法_Matrix_Fortran_Hpc_Lapack_Blas - Fatal编程技术网

Matrix 单位Fortran DGEMM上的Lapack矩阵乘法

Matrix 单位Fortran DGEMM上的Lapack矩阵乘法,matrix,fortran,hpc,lapack,blas,Matrix,Fortran,Hpc,Lapack,Blas,我遇到了一个问题,通过Lapack将单位矩阵上的非空矩阵相乘得到一个空矩阵。所有矩阵都具有正元素 Dimensions of the matrices: W = M1*N1 D = N1*N1 M = M1*M1 D-M-单位矩阵 我想做的是得到D*W'*M的乘法,其中W'是W的转置 PROGRAM SIRT DOUBLE PRECISION,ALLOCATABLE,DIMENSION(:,:) :: W, D, M, C, MAIN DOUBLE PRECISION,ALLOCATABLE,

我遇到了一个问题,通过Lapack将单位矩阵上的非空矩阵相乘得到一个空矩阵。所有矩阵都具有正元素

Dimensions of the matrices:
W = M1*N1
D = N1*N1
M = M1*M1
D-M-单位矩阵

我想做的是得到D*W'*M的乘法,其中W'是W的转置

PROGRAM SIRT
DOUBLE PRECISION,ALLOCATABLE,DIMENSION(:,:) :: W, D, M, C, MAIN
DOUBLE PRECISION,ALLOCATABLE,DIMENSION(:) :: b, x
DOUBLE PRECISION :: pho
INTEGER, PARAMETER :: M1 = 27000
INTEGER, PARAMETER :: N1 = 1000
INTEGER, PARAMETER :: num_iterations = 200
INTEGER :: i, j, k

allocate(W(1:M1,1:N1))
allocate(D(1:N1,1:N1))
allocate(M(1:M1,1:M1))
allocate(C(1:N1,1:M1))
allocate(MAIN(1:N1,1:M1))
allocate(b(1:M1))
allocate(x(1:N1))

D = 0
M = 0

DO i=1,N1
    D(i,i) = 1
END DO

DO i=1,M1
    M(i,i) = 1
END DO

OPEN(UNIT=11, FILE="Wmpi.txt")
DO i = 1,M1
    READ(11,*) (W(i,j),j=1,N1)
END DO
print *,ANY(W>0)
CLOSE (11, STATUS='KEEP') 

OPEN(UNIT=11, FILE="bmpi.txt")
DO i = 1,M1


READ(11,*) b(i)
END DO
CLOSE (11, STATUS='KEEP') 

CALL DGEMM('N', 'T', N1, N1, N1, 1.0, D, N1, W, N1, 0.0, C, N1)
print *,ANY(C>0)
CALL DGEMM('N', 'N', N1, M1, M1, 1.0, C, N1, M, M1, 0.0, MAIN, N1)
print *,ANY(MAIN>0)
pho = DLANGE('F', N1, M1, C, N1, x)
END PROGRAM SIRT
顺序打印的答案是真的,真的,假的。第一次乘法有效,我得到的不是空矩阵,但在第二次乘法中,所有元素都是0

我知道我不需要对单位矩阵进行矩阵乘法,但我想弄清楚如果我这样做会有什么问题

另一个问题是,我能在没有临时矩阵Main和C的情况下实现内存效率吗

编辑


计算出在第一次乘法后得到的矩阵中所有元素都为空。无法理解为什么任何(C>0)在第二阶段都是正确的。

首先请注意,DGEMM是BLAS库的一部分,而不是LAPACK-后者是更高级别的库

您给DGEMM打电话时遇到了一些问题

  • 真正的常数有种类,你必须提供正确的种类。在里面 特别是DGEMM期望的是老式Fortran中的名称 双精度。您提供的常量是默认的实数。 这将导致错误,我强烈建议提供 如果您的程序要求精度,则所有实数常量的种类 不是默认的精度
  • 在前三个整数中,前两个始终是 结果矩阵。C是n1xm1,因此对 DGEMM
  • 矩阵的前导维数是第一个时间的99.999% 已分配/声明的维度-它与 在数学上,这纯粹是为了让DGEMM能够计算出矩阵是怎样的 放在记忆里。在第一节中,W是错误的
  • 我还建议,作为对结果的适当检查,使用MATUL内在函数相当容易做到这一点,而不是像你在原著中那样三心二意,并且避免使用单位矩阵进行测试,除非你真的想要单位矩阵,因为高度对称性和大量的零很容易掩盖错误

    把这些放在一起,把不相关的部分切掉,把你的程序修改成稍微现代一点的形式

    Program sirt
    
      Integer, Parameter :: wp = Kind( 1.0d0 )
    
      Real( wp ),Allocatable,Dimension(:,:) :: w, d, m, c, main, main_compare
      Real( wp ),Allocatable,Dimension(:) :: b, x
      ! Change problem size to something manageable on my laptop
    !!$  Integer, Parameter :: m1 = 27000
    !!$  Integer, Parameter :: n1 = 1000
      Integer, Parameter :: m1 = 2700
      Integer, Parameter :: n1 = 100
    !!$  Integer :: i
    
      Allocate(w(1:m1,1:n1))
      Allocate(d(1:n1,1:n1))
      Allocate(m(1:m1,1:m1))
      Allocate(c(1:n1,1:m1))
      Allocate(main(1:n1,1:m1))
      Allocate(main_compare(1:n1,1:m1))
      Allocate(b(1:m1))
      Allocate(x(1:n1))
    
      d = 0.0_wp
      m = 0.0_wp
    
      ! Don't trust unit matrices for tests, too much symmetry, too many zeros - use Random numbers
    !!$  Do i=1,n1
    !!$     d(i,i) = 1.0_wp
    !!$  End Do
      Call Random_number( d )
    !!$
    !!$  Do i=1,m1
    !!$     m(i,i) = 1.0_wp
    !!$  End Do
      Call Random_number( m )
    
      ! Don't have the file - use random numbers
    !!$  open(unit=11, file="wmpi.txt")
    !!$  do i = 1,m1
    !!$     read(11,*) (w(i,j),j=1,n1)
    !!$  end do
    !!$  print *,any(w>0)
    !!$  close (11, status='keep') 
      Call random_Number( w )
    
      ! 1) Real constant have kind, and you must provide the correct kind
      ! 2) Of the first three constant the first two are always the shape
      !    of the result matrix. C is n1xm1, hece the change
      ! 3) The leading dimension of a matrix is 99.999% of the time
      !    the first dimension as allocated/declared  -it has nothing
      !    to do with the maths at all. It was wrong for W in the
      !    first matmul
      ! 4) DGEMM is part of the BLAS library - not LAPACK
    !!$  CALL DGEMM('N', 'T', N1, N1, N1, 1.0, D, N1, W, N1, 0.0, C, N1)
    !!$  CALL DGEMM('N', 'N', N1, M1, M1, 1.0, C, N1, M, M1, 0.0, MAIN, N1)
      Call dgemm('n', 't', n1, m1, n1, 1.0_wp, d, n1, w, m1, 0.0_wp, c, n1)
      Call dgemm('n', 'n', n1, m1, m1, 1.0_wp, c, n1, m, m1, 0.0_wp, main, n1)
    
      ! 5) Don't do half hearted checks on the results when proper checks are easy
      main_compare = Matmul( Matmul( d, Transpose( w ) ), m )
      Write( *, * ) 'Max error ', Maxval( Abs( main - main_compare ) )
    
      ! Check we haven't somehow managed all zeros in both matrices ...
      Write( *, * ) main( 1:3, 1 )
      Write( *, * ) main_compare( 1:3, 1 )
    
    End Program sirt
    ian@eris:~/work/stack$ gfortran-8  -std=f2008 -fcheck=all -Wall -Wextra -pedantic -O matmul.f90 -lblas
    /usr/bin/ld: warning: libgfortran.so.4, needed by //usr/lib/x86_64-linux-gnu/libopenblas.so.0, may conflict with libgfortran.so.5
    ian@eris:~/work/stack$ ./a.out
     Max error    3.6379788070917130E-011
       38576.055405987529        33186.640731082334        33818.909332709263     
       38576.055405987536        33186.640731082334        33818.909332709263     
    ian@eris:~/work/stack$ ./a.out
     Max error    2.9103830456733704E-011
       34303.739077708480        34227.623080598998        34987.143088270866     
       34303.739077708473        34227.623080598998        34987.143088270859     
    ian@eris:~/work/stack$ ./a.out
     Max error    3.2741809263825417E-011
       35968.603030053979        34778.110740682620        32732.657800858586     
       35968.603030053971        34778.110740682612        32732.657800858586     
    ian@eris:~/work/stack$ ./a.out
     Max error    2.9103830456733704E-011
       31575.076511213174        35879.913361891951        35278.030249048912     
       31575.076511213178        35879.913361891951        35278.030249048912   
    

    首先请注意,DGEMM是BLAS库的一部分,而不是LAPACK-后者是更高级别的库

    您给DGEMM打电话时遇到了一些问题

  • 真正的常数有种类,你必须提供正确的种类。在里面 特别是DGEMM期望的是老式Fortran中的名称 双精度。您提供的常量是默认的实数。 这将导致错误,我强烈建议提供 如果您的程序要求精度,则所有实数常量的种类 不是默认的精度
  • 在前三个整数中,前两个始终是 结果矩阵。C是n1xm1,因此对 DGEMM
  • 矩阵的前导维数是第一个时间的99.999% 已分配/声明的维度-它与 在数学上,这纯粹是为了让DGEMM能够计算出矩阵是怎样的 放在记忆里。在第一节中,W是错误的
  • 我还建议,作为对结果的适当检查,使用MATUL内在函数相当容易做到这一点,而不是像你在原著中那样三心二意,并且避免使用单位矩阵进行测试,除非你真的想要单位矩阵,因为高度对称性和大量的零很容易掩盖错误

    把这些放在一起,把不相关的部分切掉,把你的程序修改成稍微现代一点的形式

    Program sirt
    
      Integer, Parameter :: wp = Kind( 1.0d0 )
    
      Real( wp ),Allocatable,Dimension(:,:) :: w, d, m, c, main, main_compare
      Real( wp ),Allocatable,Dimension(:) :: b, x
      ! Change problem size to something manageable on my laptop
    !!$  Integer, Parameter :: m1 = 27000
    !!$  Integer, Parameter :: n1 = 1000
      Integer, Parameter :: m1 = 2700
      Integer, Parameter :: n1 = 100
    !!$  Integer :: i
    
      Allocate(w(1:m1,1:n1))
      Allocate(d(1:n1,1:n1))
      Allocate(m(1:m1,1:m1))
      Allocate(c(1:n1,1:m1))
      Allocate(main(1:n1,1:m1))
      Allocate(main_compare(1:n1,1:m1))
      Allocate(b(1:m1))
      Allocate(x(1:n1))
    
      d = 0.0_wp
      m = 0.0_wp
    
      ! Don't trust unit matrices for tests, too much symmetry, too many zeros - use Random numbers
    !!$  Do i=1,n1
    !!$     d(i,i) = 1.0_wp
    !!$  End Do
      Call Random_number( d )
    !!$
    !!$  Do i=1,m1
    !!$     m(i,i) = 1.0_wp
    !!$  End Do
      Call Random_number( m )
    
      ! Don't have the file - use random numbers
    !!$  open(unit=11, file="wmpi.txt")
    !!$  do i = 1,m1
    !!$     read(11,*) (w(i,j),j=1,n1)
    !!$  end do
    !!$  print *,any(w>0)
    !!$  close (11, status='keep') 
      Call random_Number( w )
    
      ! 1) Real constant have kind, and you must provide the correct kind
      ! 2) Of the first three constant the first two are always the shape
      !    of the result matrix. C is n1xm1, hece the change
      ! 3) The leading dimension of a matrix is 99.999% of the time
      !    the first dimension as allocated/declared  -it has nothing
      !    to do with the maths at all. It was wrong for W in the
      !    first matmul
      ! 4) DGEMM is part of the BLAS library - not LAPACK
    !!$  CALL DGEMM('N', 'T', N1, N1, N1, 1.0, D, N1, W, N1, 0.0, C, N1)
    !!$  CALL DGEMM('N', 'N', N1, M1, M1, 1.0, C, N1, M, M1, 0.0, MAIN, N1)
      Call dgemm('n', 't', n1, m1, n1, 1.0_wp, d, n1, w, m1, 0.0_wp, c, n1)
      Call dgemm('n', 'n', n1, m1, m1, 1.0_wp, c, n1, m, m1, 0.0_wp, main, n1)
    
      ! 5) Don't do half hearted checks on the results when proper checks are easy
      main_compare = Matmul( Matmul( d, Transpose( w ) ), m )
      Write( *, * ) 'Max error ', Maxval( Abs( main - main_compare ) )
    
      ! Check we haven't somehow managed all zeros in both matrices ...
      Write( *, * ) main( 1:3, 1 )
      Write( *, * ) main_compare( 1:3, 1 )
    
    End Program sirt
    ian@eris:~/work/stack$ gfortran-8  -std=f2008 -fcheck=all -Wall -Wextra -pedantic -O matmul.f90 -lblas
    /usr/bin/ld: warning: libgfortran.so.4, needed by //usr/lib/x86_64-linux-gnu/libopenblas.so.0, may conflict with libgfortran.so.5
    ian@eris:~/work/stack$ ./a.out
     Max error    3.6379788070917130E-011
       38576.055405987529        33186.640731082334        33818.909332709263     
       38576.055405987536        33186.640731082334        33818.909332709263     
    ian@eris:~/work/stack$ ./a.out
     Max error    2.9103830456733704E-011
       34303.739077708480        34227.623080598998        34987.143088270866     
       34303.739077708473        34227.623080598998        34987.143088270859     
    ian@eris:~/work/stack$ ./a.out
     Max error    3.2741809263825417E-011
       35968.603030053979        34778.110740682620        32732.657800858586     
       35968.603030053971        34778.110740682612        32732.657800858586     
    ian@eris:~/work/stack$ ./a.out
     Max error    2.9103830456733704E-011
       31575.076511213174        35879.913361891951        35278.030249048912     
       31575.076511213178        35879.913361891951        35278.030249048912   
    

    至少在第一次乘法中,W的前导维数可能是错误的,W是W(1:M1,1:N1)。同样,在第一个例子中,考虑到矩阵的形状,它应该是N1,M1,N1。如果你发布一个完整的程序,我可以测试it@IanBush这是一个完整的程序。我忘了在最后加上“结束程序”。如果你能测试一下,我会很高兴的。此外,我可以提供矩阵文件,但请告诉我,我可以张贴在哪里?非常感谢。至少在第一次乘法中,W的前导维数可能是错误的,W是W(1:M1,1:N1)。同样,在第一个例子中,考虑到矩阵的形状,它应该是N1,M1,N1。如果你发布一个完整的程序,我可以测试it@IanBush这是一个完整的程序。我忘了在最后加上“结束程序”。如果你能测试一下,我会很高兴的。此外,我可以提供矩阵文件,但请告诉我,我可以张贴在哪里?非常感谢。你能澄清一下矩阵的前导维数吗?在官方文档中,它说LDB在输入时是整数,LDB指定了调用(子)程序中声明的B的第一个维度。当TRANSB='N'或'N'时,则LDB必须至少为max(1,k),否则LDB必须至少为max(1,N)。所以在我的例子中,TRANS='T'LDB必须至少是max(1,n)。n指定矩阵op(B)的列数,在我的例子中是N1。有点复杂-实际上这本身是一个很好的问题,所以(在第一次检查重复项之后)你可以在单独的问题中问它,我会在那里回答。一个好的答案对于一个评论来说太长了。添加一个新的问题[链接]()。谢谢!你能澄清一下矩阵的前导维数吗?在官方文档中,它说LDB在输入时是整数,LDB指定了调用(子)程序中声明的B的第一个维度。当TRANSB='N'或'N'时,则LDB必须至少为max(1,k),否则LDB必须至少为max(1,N)。所以在我的例子中,TRANS='T'LDB必须至少是max(1,n)。n指定矩阵op(B)的列数,在我的例子中是N1