LSchueler
LSchueler

Reputation: 1514

Segmentation Fault from Fortran shared object

I have a fortran subroutine in the file gfunc.f90. I want to call this subroutine from my main program in test.f90.

If I keep both files in the same directory and compile them with

gfortran gfunc.f90 test.f90 -o test

It works fine.

But I want the subroutine to be in a library. Thus, I create a subfolder called gfunc/ and put gfunc.f90 there. In that folder, I compile the module with

gfortran -fdefault-real-8 -fPIC -c gfunc.f90

and

gfortran -fdefault-real-8 -shared -o gfunc.so gfunc.o

I now compile the main program with

gfortran test.f90 gfunc/gfunc.so

But now I get a segmentation fault as soon as a variable in the subroutine is accessed.

How do I have to compile and link the library correctly?

Here, you find a minimal working example in order to reproduce the problem:

gfunc.f90:

module gfunc_module
implicit none
contains
subroutine gfunc(x, n, m, a, b, c)
    double precision, intent(in) :: x
    integer, intent(in) :: n, m
    double precision, dimension(n), intent(in) :: a
    double precision, dimension(m), intent(in) :: b
    double precision, dimension(n, m), intent(out) :: c
    integer :: i, j
    do j=1,m
        do i=1,n
             c(i,j) = exp(-x * (a(i)**2 + b(j)**2))
        end do
    end do
end subroutine
end module

test.f90:

program main

use gfunc_module

implicit none

integer, parameter :: dp = kind(1.0d0)

real(dp) :: x = 1.
integer, parameter :: n = 4
integer, parameter :: m = 4
real(dp), dimension(n) :: a = [-1., -0.33333333, .033333333, 1.]
real(dp), dimension(m) :: b = [-1., -0.33333333, .033333333, 1.]
real(dp), dimension(n, m) :: c

call gfunc(x, n, m, a, b, c)

write(*,*) c

end program main

Upvotes: 2

Views: 273

Answers (1)

brady
brady

Reputation: 2257

You should add fdefault-real-8 to your compilation of test.f90:

gfortran -fdefault-real-8 test.f90 gfunc/gfunc.so

From the documentation for gfortran -fdefault-real-8 is making DOUBLE PRECISION variables 16 bytes wide, so without it on test.f90 the double precision variables are only 8 bytes wide:

-fdefault-real-8

Set the default real type to an 8 byte wide type. Do nothing if this is already the default. This option also affects the kind of non-double real constants like 1.0, and does promote the default width of "DOUBLE PRECISION" to 16 bytes if possible, unless "-fdefault-double-8" is given, too.

Upvotes: 4

Related Questions