错误 forrtl:严重 (174):SIGSEGV,矩阵乘法发生分段错误
error forrtl: severe (174): SIGSEGV, segmentation fault occurred matrix multiplication
我试图实现一个简单的矩阵乘法,但我一直收到错误
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
test_performance. 00000000004708F1 Unknown Unknown Unknown
test_performance. 000000000046F047 Unknown Unknown Unknown
test_performance. 000000000043F544 Unknown Unknown Unknown
test_performance. 000000000043F356 Unknown Unknown Unknown
test_performance. 0000000000423DFF Unknown Unknown Unknown
test_performance. 000000000040384D Unknown Unknown Unknown
libpthread.so.0 00002AD8B44769F0 Unknown Unknown Unknown
test_performance. 00000000004034A8 Unknown Unknown Unknown
test_performance. 0000000000402ECE Unknown Unknown Unknown
libc.so.6 00002AD8B46A6BE5 Unknown Unknown Unknown
test_performance. 0000000000402DD9 Unknown Unknown Unknown
这是我的代码:
PROGRAM test_performance
IMPLICIT NONE
INTEGER :: DIM_M, DIM_L, DIM_N, index1, index2,index3,index4
INTEGER, DIMENSION(4,4) :: A,B,C
DIM_L=4
DIM_M=4
DIM_N=4
DO index1=1,DIM_M
DO index2=1,DIM_L
print *, 'here I am!'
A(index1,index2)=index1+index2
END DO
END DO
DO index3=1,DIM_L
DO index4=1,DIM_N
B(index3,index4)=index3+index4
END DO
END DO
print *,'A= ',A
print *,'B= ',B
CALL MATRIXMULTIPLICATION
PRINT *, 'C=', C
END PROGRAM test_performance
SUBROUTINE MATRIXMULTIPLICATION(A,B,C, DIM_M, DIM_L, DIM_N)
INTEGER, INTENT(IN) :: DIM_M, DIM_L, DIM_N
INTEGER, INTENT(IN) :: A(4,4), B(4,4)
INTEGER, INTENT(OUT) :: C(4,4)
INTEGER :: ii=1,jj=1, kk=1
DO ii=1, DIM_M
DO jj=1, DIM_N
DO kk=1, DIM_L
C(ii,jj)=C(ii,jj)+A(ii,ll)*B(ll,jj)
END DO
END DO
END DO
END SUBROUTINE MATRIXMULTIPLICATION
我不知道为什么会出现此错误,因为维度和所有索引应该没问题。我试图通过使用所有可能的东西来查找错误,但我不知道错误可能是什么。
声明
CALL MATRIXMULTIPLICATION
不包括调用例程时所需的参数。一个糟糕的解决方案是简单地用
替换该语句
CALL MATRIXMULTIPLICATION(A,B,C, DIM_M, DIM_L, DIM_N)
但是,更好的解决方案是使子例程的接口显式。有多种方法可以做到这一点,一种方法是将其放入 module
和 use
模块中。对于单个子例程,这可能有点矫枉过正,但随着您的程序变得越来越大和越来越复杂,绝对是可行的方法。
一个简单直接且满足您当前目的的解决方案是移动行
END PROGRAM test_performance
跟随路线
END SUBROUTINE MATRIXMULTIPLICATION
并且,在原来 end program
行的位置插入行
contains
如果您一开始就按照这些思路编写程序,编译器就会发现您的严重错误并指出给您。就目前而言,子例程是程序的 外部 并且编译器无法在编译时匹配其虚拟参数和实际参数;正如所写的那样,参数匹配是程序员的责任,你已经相当困惑了。
进一步的改进是让您的子例程处理任何大小的数组,而不是通过参数列表传递数组维度。 Fortran 数组携带它们的大小和形状信息,在极少数情况下,例程需要明确知道它们可以进行查询。
更简单的方法是使用 matmul
内在函数,并花时间编写代码中其他可能更具挑战性和更有趣的部分。
我试图实现一个简单的矩阵乘法,但我一直收到错误
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
test_performance. 00000000004708F1 Unknown Unknown Unknown
test_performance. 000000000046F047 Unknown Unknown Unknown
test_performance. 000000000043F544 Unknown Unknown Unknown
test_performance. 000000000043F356 Unknown Unknown Unknown
test_performance. 0000000000423DFF Unknown Unknown Unknown
test_performance. 000000000040384D Unknown Unknown Unknown
libpthread.so.0 00002AD8B44769F0 Unknown Unknown Unknown
test_performance. 00000000004034A8 Unknown Unknown Unknown
test_performance. 0000000000402ECE Unknown Unknown Unknown
libc.so.6 00002AD8B46A6BE5 Unknown Unknown Unknown
test_performance. 0000000000402DD9 Unknown Unknown Unknown
这是我的代码:
PROGRAM test_performance
IMPLICIT NONE
INTEGER :: DIM_M, DIM_L, DIM_N, index1, index2,index3,index4
INTEGER, DIMENSION(4,4) :: A,B,C
DIM_L=4
DIM_M=4
DIM_N=4
DO index1=1,DIM_M
DO index2=1,DIM_L
print *, 'here I am!'
A(index1,index2)=index1+index2
END DO
END DO
DO index3=1,DIM_L
DO index4=1,DIM_N
B(index3,index4)=index3+index4
END DO
END DO
print *,'A= ',A
print *,'B= ',B
CALL MATRIXMULTIPLICATION
PRINT *, 'C=', C
END PROGRAM test_performance
SUBROUTINE MATRIXMULTIPLICATION(A,B,C, DIM_M, DIM_L, DIM_N)
INTEGER, INTENT(IN) :: DIM_M, DIM_L, DIM_N
INTEGER, INTENT(IN) :: A(4,4), B(4,4)
INTEGER, INTENT(OUT) :: C(4,4)
INTEGER :: ii=1,jj=1, kk=1
DO ii=1, DIM_M
DO jj=1, DIM_N
DO kk=1, DIM_L
C(ii,jj)=C(ii,jj)+A(ii,ll)*B(ll,jj)
END DO
END DO
END DO
END SUBROUTINE MATRIXMULTIPLICATION
我不知道为什么会出现此错误,因为维度和所有索引应该没问题。我试图通过使用所有可能的东西来查找错误,但我不知道错误可能是什么。
声明
CALL MATRIXMULTIPLICATION
不包括调用例程时所需的参数。一个糟糕的解决方案是简单地用
替换该语句CALL MATRIXMULTIPLICATION(A,B,C, DIM_M, DIM_L, DIM_N)
但是,更好的解决方案是使子例程的接口显式。有多种方法可以做到这一点,一种方法是将其放入 module
和 use
模块中。对于单个子例程,这可能有点矫枉过正,但随着您的程序变得越来越大和越来越复杂,绝对是可行的方法。
一个简单直接且满足您当前目的的解决方案是移动行
END PROGRAM test_performance
跟随路线
END SUBROUTINE MATRIXMULTIPLICATION
并且,在原来 end program
行的位置插入行
contains
如果您一开始就按照这些思路编写程序,编译器就会发现您的严重错误并指出给您。就目前而言,子例程是程序的 外部 并且编译器无法在编译时匹配其虚拟参数和实际参数;正如所写的那样,参数匹配是程序员的责任,你已经相当困惑了。
进一步的改进是让您的子例程处理任何大小的数组,而不是通过参数列表传递数组维度。 Fortran 数组携带它们的大小和形状信息,在极少数情况下,例程需要明确知道它们可以进行查询。
更简单的方法是使用 matmul
内在函数,并花时间编写代码中其他可能更具挑战性和更有趣的部分。