Ошибка сегментации - неверная ссылка на память
Эй, я пытаюсь заставить мои библиотеки LAPACK работать, и я искал и искал, но я не могу понять, что я делаю неправильно.
Я пытаюсь запустить свой код, и я получаю следующую ошибку
Программа получила сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.
Backtrace for this error:
#0 0x7FFB23D405F7
#1 0x7FFB23D40C3E
#2 0x7FFB23692EAF
#3 0x401ED1 in sgesv_
#4 0x401D0B in MAIN__ at CFDtest.f03:? Segmentation fault (core dumped)
Я вставлю свой основной код здесь, надеюсь, кто-то может помочь мне с этой проблемой.
****************************************************
PROGRAM CFD_TEST
USE MY_LIB
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
DIMENSION ET(0:10), VN(0:10), WT(0:10)
DIMENSION SO(0:10), FU(0:10), DMA(0:10,0:10)
DIMENSION DMA2(0:10,0:10), QN(0:10), WKSPCE(0:10)
INTEGER*8 :: pivot(10), inf
INTEGER*8 :: N
EXTERNAL SGESV
!SET THE PARAMETERS
SIGMA1 = 0.D0
SIGMA2 = 0.D0
TAU = 1.D0
EF = 1.D0
EXP = 2.71828182845904509D0
COST = EXP/(1.D0+EXP*EXP)
DO 1 N=2, 10
!COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX
CALL ZELEGL(N,ET,VN)
CALL WELEGL(N,ET,VN,WT)
CALL DMLEGL(N,10,ET,VN,DMA)
!CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE
!DIFFERENTIAL OPERATOR
DO 2 I=0, N
DO 2 J=0, N
SUM = 0.D0
DO 3 K=0, N
SUM = SUM + DMA(I,K)*DMA(K,J)
3 CONTINUE
OPER = -SUM
IF(I .EQ. J) OPER = -SUM + TAU
DMA2(I,J) = OPER
2 CONTINUE
!CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE
!BOUNDARY CONDITIONS
DO 4 J=0, N
DMA2(0,J) = 0.D0
DMA2(N,J) = 0.D0
4 CONTINUE
DMA2(0,0) = 1.D0
DMA2(N,N) = 1.D0
!CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR
DO 5 I=1, N-1
FU(I) = EF
5 CONTINUE
FU(0) = SIGMA1
FU(N) = SIGMA2
!SOLUTION OF THE LINEAR SYSTEM
N1 = N + 1
CALL SGESV(N,N,DMA2,pivot,FU,N,inf)
DO 6 I = 0, N
FU(I) = SO(I)
6 CONTINUE
PRINT *, pivot
1 CONTINUE
RETURN
END PROGRAM CFD_TEST
*****************************************************
Команды, которые я запускаю для компиляции:
gfortran -c MY_LIB.f03
gfortran -c CFDtest.f03
gfortran MY_LIB.o CFDtest.o -o CFDtest -L / usr / local / lib -llapack -lblas
Я управлял командой
-fbacktrace -g -Wall -Wextra CFDtest
CFDtest: в функции _fini':
(.fini+0x0): multiple definition of
_fini'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:80: сначала определено здесь CFDtest: в функции data_start':
(.data+0x0): multiple definition of
data_start'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.data+0x0): сначала определено здесь CFDtest: In function data_start':
(.data+0x8): multiple definition of
__dso_handle '/usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o:(.data+0x0): сначала определено здесь CFDtest:(.rodata+0x0): множественное определение _IO_stdin_used'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
CFDtest: In function
_start':
(.text+0x0): множественное определение _start'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
CFDtest: In function
_init':
(.init+0x0): множественное определение _init'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:64: first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o:(.tm_clone_table+0x0): multiple definition of
__TMC_END 'CFDtest:(. Data+0x10): сначала определено здесь / usr / bin / ld: ошибка в CFDtest(.eh_frame); таблица.eh_frame_hdr не будет создана.
collect2: error: ld вернул 1 состояние выхода
2 ответа
Насколько я могу судить, может возникнуть ряд проблем:
- Ваши целые числа с
INTEGER*8
может быть слишком долго, может бытьINTEGER*4
или простоINTEGER
было бы лучше - Ты звонишь
SGESV
на двойных аргументах вместоDGESV
- Ваш
LDA
аргумент отсутствует, поэтому ваш код должен выглядетьCALL DGESV(N,N,DMA2,N,pivot,FU,N,inf)
но вам нужно проверить, хотите ли вы этого.
Вы не опубликовали свой код для MY_LIB.f03
поэтому мы не можем скомпилировать CFDtest.f03
именно так, как вы его поставили.
(Кроме того, обычное соглашение об именах таково, что f90
в .f90
файл не должен указывать на целевую языковую версию. Скорее, .f90
обозначает свободный формат, а .f
используется для фиксированного формата. По расширению, ваш .f03
файлы были бы лучше (т.е. более переносимы, если) названы .f90
.)
Я закомментировал USE MY_LIB
линии и пробежал ваш код nagfor -u -c cfd_test.f90
, Выходной сигнал в разбивке:
Extension: cfd_test.f90, line 13: Byte count on numeric data type
detected at *@8
Extension: cfd_test.f90, line 15: Byte count on numeric data type
detected at *@8
Количество байтов не является переносимым. kind
значение для 8-байтового целого числа selected_int_kind(18)
, (Точно так же вы могли бы использовать kind(0.0d0)
доброе значение для ваших данных с двойной точностью.)
Error: cfd_test.f90, line 48: Implicit type for I
detected at 2@I
Error: cfd_test.f90, line 50: Implicit type for J
detected at 2@J
Error: cfd_test.f90, line 54: Implicit type for K
detected at 3@K
Error: cfd_test.f90, line 100: Implicit type for N1
detected at N1@=
У вас есть эти неявно типизированные, что означает, что они являются 4-байтовыми (по умолчанию) целыми числами. Вы, вероятно, должны объявить их явно как 8-байтовые целые числа (используя приведенное выше 8-байтовое целочисленное значение), если это то, что вы намереваетесь.
Questionable: cfd_test.f90, line 116: Variable COST set but never referenced
Questionable: cfd_test.f90, line 116: Variable N1 set but never referenced
Warning: cfd_test.f90, line 116: Unused local variable QN
Warning: cfd_test.f90, line 116: Unused local variable WKSPCE
Вам нужно решить, что вы намерены делать с ними, или же это просто удаляемый хлам.
С неявными целыми числами, объявленными явно, есть дальнейший вывод
Warning: cfd_test.f90, line 116: Variable SO referenced but never set
Это выглядит плохо.
Obsolescent: cfd_test.f90, line 66: 2 is a shared DO termination label
Ваш DO
петли, вероятно, было бы лучше, используя современные END DO
терминаторы (не разделяется!)
Error: cfd_test.f90, line 114: RETURN is only allowed in SUBROUTINEs and FUNCTIONs
Это очевидно легко исправить.
Для вызова LAPACK одним из источников явных интерфейсов для этих подпрограмм является библиотека NAG Fortran (через nag_library
модуль). Поскольку ваши реальные данные не одинарной точности, вы должны использовать dgesv
вместо sgesv
, Добавление USE nag_library, ONLY: dgesv
и переключение на звонок dgesv
вместо sgesv
, а затем перекомпилировать, как указано выше, показывает
Incorrect data type INTEGER(KIND=4) (expected INTEGER) for argument N (no. 1) of DGESV
так что вы действительно должны использовать значения по умолчанию (4-байтовые целые числа) - по крайней мере, для сборки LAPACK в вашей системе, которая почти наверняка будет использовать 4-байтовые целые числа. Таким образом, вы можете забыть все о kind
используя целые числа и просто используйте значение по умолчанию integer
типа для всех. Исправляя это дает
Array supplied for scalar argument LDA (no. 4) of DGESV
так что вам нужно добавить этот аргумент. Может пройти size(DMA2,1)
?
С этим аргументом, добавленным к вызову, код успешно компилируется, но без определений для вашего *LEGL
функции, которые я не мог пройти ни одного тестирования во время выполнения.
Вот моя модифицированная (и довольно распечатанная) версия вашей программы
Program cfd_test
! Use my_lib
! Use nag_library, Only: dgesv
Implicit None
Integer, Parameter :: wp = kind(0.0D0)
Real (Kind=wp) :: ef, oper, sigma1, sigma2, tau
Integer :: i, inf, j, k, n, sum
Real (Kind=wp) :: dma(0:10, 0:10), dma2(0:10, 0:10), et(0:10), fu(0:10), &
so(0:10), vn(0:10), wt(0:10)
Integer :: pivot(10)
External :: dgesv, dmlegl, welegl, zelegl
Intrinsic :: kind, size
! SET THE PARAMETERS
sigma1 = 0._wp
sigma2 = 0._wp
tau = 1._wp
ef = 1._wp
Do n = 2, 10
! COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX
Call zelegl(n, et, vn)
Call welegl(n, et, vn, wt)
Call dmlegl(n, 10, et, vn, dma)
! CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE
! DIFFERENTIAL OPERATOR
Do i = 0, n
Do j = 0, n
sum = 0._wp
Do k = 0, n
sum = sum + dma(i, k)*dma(k, j)
End Do
oper = -sum
If (i==j) oper = -sum + tau
dma2(i, j) = oper
End Do
End Do
! CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE
! BOUNDARY CONDITIONS
Do j = 0, n
dma2(0, j) = 0._wp
dma2(n, j) = 0._wp
End Do
dma2(0, 0) = 1._wp
dma2(n, n) = 1._wp
! CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR
Do i = 1, n - 1
fu(i) = ef
End Do
fu(0) = sigma1
fu(n) = sigma2
! SOLUTION OF THE LINEAR SYSTEM
Call dgesv(n, n, dma2, size(dma2,1), pivot, fu, n, inf)
Do i = 0, n
fu(i) = so(i)
End Do
Print *, pivot
End Do
End Program
В целом ваш опыт разработки будет наиболее приятным, если вы используете настолько хороший проверяющий компилятор, насколько это возможно, и если вы уверены, что попросите его диагностировать как можно больше для вас.