2015-05-13 1 views
0

Я хочу открыть MAT-файл в fortran, и я следовал за example file. Компиляция и связь происходят без каких-либо ошибок или предупреждений.Ошибка сегментации в скрипте для открытия MAT-файла

Это Makefile:

FC = gfortran 
FCFLAGS = -g -fcheck=all -Wall 
INCLUDES = -I/usr/local/matlab2008a/extern/include 
LFLAGS = -L/usr/local/matlab2008a/bin/glnxa64 
LIBS = -lmat -lmx 
LDFLAGS = "-Wl,-rpath,/usr/local/matlab2008a/bin/glnxa64" 

main: main.o param.o dmotifs.o ssa.o 
    $(FC) $(LFLAGS) $(LIBS) $(LDFLAGS) -o main main.o param.o dmotifs.o ssa.o 
param.o: param.f90 
    $(FC) $(FCFLAGS) -c $<  
dmotifs.o: dmotifs.f90 param.o 
    $(FC) $(FCFLAGS) -c $<  
ssa.o: ssa.f90 dmotifs.o 
    $(FC) $(FCFLAGS) -c $< 
main.o: main.f90 param.o dmotifs.o ssa.o 
    $(FC) -c -cpp $(FCFLAGS) $(INCLUDES) $<  
clean: 
    rm -f *.o *.mod *.MOD 

Однако, когда я бегу сценарий я получаю ошибку ошибки сегментации.

Program received signal SIGSEGV: Segmentation fault - invalid memory reference. 

Backtrace for this error: 
#0 0x37B4C19497 
#1 0x37B4C19ADE 
#2 0x37B1E358EF 
#3 0x7F1EA50EA7C1 
#4 0x401A69 in MAIN__ at main.f90:75 
Segmentation fault 

Это основной код:

#include "fintrf.h" 

PROGRAM main  
USE ssa 
IMPLICIT NONE 

CHARACTER(LEN=6) :: argfun 
TYPE(fhandle), DIMENSION(13) :: fmotifs 
TYPE(funnames), DIMENSION(13) :: fnames 
TYPE(PRM) p 
REAL, DIMENSION(4) :: y0 
REAL tf 
REAL, ALLOCATABLE, DIMENSION(:) :: t 
REAL, ALLOCATABLE, DIMENSION(:,:) :: y 
TYPE(OPTIONS) opt 
INTEGER fin 
REAL nM2m 

! MAT-FILE Declarations ! 

INTEGER*8 matOpen, matGetDir !, matGetNextVariable 
INTEGER matGetVariableInfo 
INTEGER mp, dir, adir(100), pa 
INTEGER mxGetM, mxGetN, matClose 
INTEGER ndir, i, clstat 
CHARACTER*32 names(100) !, name 

!===========================! 


nM2m=1.355178815844751e3; 

opt%numsample=2000 
tf=1000000 

call get_command_argument(1,argfun) 

call makemotifs(fnames,fmotifs) 
call getparamdef(p) 

if(all(fnames(:)%fn .NE. argfun)) then 
    write(*,*) "No such motif: ",argfun 
    write(*,*) "Input format-> main <motifname>" 
    stop 
else 


    fin=fchton(argfun) 
    y0=nint(nM2m*analys(p,argfun)) 


    !*** ==> OPEN MAT-file <== ***! 

    mp=matOpen('./PRMS_lxr_29Apr15.mat','r') 

    if (mp .eq. 0) then 
     write(6,*) "Can't open MAT-file" 
     stop 
    end if 

    dir = matgetdir(mp, ndir) 

    if (dir .eq. 0) then 
     write(6,*) "Can't read MAT-file-directory." 
     stop 
    endif 

    call mxCopyPtrToPtrArray(dir, adir, ndir) 

    do 20 i=1,ndir 
     call mxCopyPtrToCharacter(adir(i), names(i), 32) 
20 continue 

    write(6,*) 'Directory of Mat-file:' 

    do 30 i=1,ndir 
     write(6,*) names(i) 
30 continue 

    write(6,*) 'Getting Header info from first array.' 
    pa = matGetVariableInfo(mp, names(1)) 
    write(6,*) 'Retrieved ', names(1) 
    write(6,*) ' With size ', mxGetM(pa), '-by-', mxGetN(pa) 
    call mxDestroyArray(pa) 

    clstat=matClose(mp) 

    call gillespie(fmotifs(fin),y0,p,tf,opt,t,y) 

end if 

Line 75 (как указано в сообщении об ошибке есть): dir = matgetdir(mp, ndir)

Я понятия не имею, как исправить эту проблему. Если я прокомментирую часть открытия MAT-файла, все будет хорошо. MAT-файл содержит плавающий 3D-массив (9x5x10000) и два скаляра.

EDIT

Как мне кажется, что для 64-битных систем, указатели должны быть объявлены как integer*8 вместо integer. Когда я сделал это, я снова получаю ошибку сегментации на этой линии:
            call mxCopyPtrToPtrArray(dir, adir, ndir)

Mathworks документация по этой теме нет почти ничего, и они делают это, кажется, довольно легко рутинная работа. Кто-нибудь, кто на самом деле открыл MAT-файл на fortran? Может кто-нибудь, пожалуйста, поделитесь своими сценариями?

+0

@AlexanderVogt у него есть обратная линия там, строка 75. –

+0

Двойная проверка, что вы правильно вызываете подпрограммы mat *, например, количество аргументов и их типы. Если бы у них был модуль с явными интерфейсами, это было бы лучше. –

+0

На самом деле я отказываюсь от использования MAT-файлов. Использование HDF5 - это бесконечно лучший вариант. Сохранение этой должности для общего интереса. – WYSIWYG

ответ

2

Из длины адресов в сообщении об ошибке это похоже на то, что вы находитесь на 64-битной системе.

Вы указали и сохраняете результаты большинства функций mat * в целочисленном по умолчанию. Вероятно, это всего лишь 32-битный тип. Функции mat * фактически возвращают машинный указатель, который будет 64 бит на 64-битной машине.

Пример кода, с которым вы связывались, вероятно, предполагает 32-битную платформу.

Отрегулируйте свои объявления для функций mat * и переменных, которым присваиваются результаты вызова этих функций соответствующим образом. Возможно, INTEGER(C_INTPTR_T), где C_INTPTR_T - ISO_C_BINDING.

Mathworks предоставляет архаичное средство препроцессора C для указания соответствующего типа (например, возвращаемый тип matOpen - это mwPointer), который препроцессор переходит в соответствующий целочисленный вид. Лично я предпочитаю использовать свои собственные интерфейсы, написанные с использованием функций совместимости C Fortran 2003.

+2

Также может быть полезно указать на комментарий «Заменить целое число на целое число 8 на 64-разрядной платформе DEC Alpha» в [пример] (http://www-rohan.sdsu.edu/doc/matlab/techdoc /matlab_external/ch05ma11.html), потому что кажется, что некоторые переменные/функции должны быть изменены в части декларации. – roygvib

+0

Спасибо. После того, как я заменил 'integer' на' integer * 8' для объявлений указателей, я все еще получаю ошибку сегментации в строке 82: 'call mxCopyPtrToPtrArray (dir, adir, ndir)' – WYSIWYG