Ошибка сегментации Fortran90 с использованием OpenMP и внешней библиотеки

Я искал помощь в решении этой проблемы, пробовал различные решения и т. Д., Но, похоже, не могу отследить проблему. Я пытаюсь распараллелить цикл do, который содержит вызов подпрограммы оптимизации в библиотеке NLopt (для NLOpt см.: http://ab-initio.mit.edu/wiki/index.php/NLopt). Вот игрушечный пример того, что я пытаюсь сделать (реальная проблема значительно сложнее с дополнительными вызовами подпрограмм, которые обновляют параметры в calfun):

program tester

implicit none

! Include optimization package
include 'nlopt.f'

integer :: i,t,obs,J,MAXI=1000
real(kind=8) :: TOL = 0.0000001

! Optimization variables
real(kind=8), allocatable :: lb(:), ub(:), args(:,:)
integer(kind=8), allocatable :: opt(:)
integer, allocatable :: ires(:),val(:)

print*, 'How many times would you like to evaluate the optimization problem?'
read*, obs
print*, 'What is the size of the input vector?'
read*, J

allocate(lb(J))
allocate(ub(J))
allocate(args(J,obs))
allocate(opt(obs))
allocate(ires(obs))
allocate(val(obs))

do i=1,J
    lb(i) = -5
    ub(i) = 5
end do

!$OMP PARALLEL DO SHARED(lb,ub,args,opt,ires,val) PRIVATE(t,i,J,TOL,MAXI) 

do t=1,obs

    ! Call optimization routine
    call nlo_create(opt(t),NLOPT_LN_BOBYQA,J)
    ! Set Bounds
    call nlo_set_lower_bounds(ires(t), opt(t), lb(1:J))
    call nlo_set_upper_bounds(ires(t), opt(t), ub(1:J))
    call nlo_set_max_objective(ires(t), opt(t), calfun, 0)
    ! Set initial values
    do i=1,J
        args(i,t) = 0
    end do
    ! Set tolerance and stopping criteria
    call nlo_set_xtol_abs1(ires(t), opt(t), TOL)
    call nlo_set_maxeval(ires(t), opt(t), MAXI)
    ! Call optimizer
    call nlo_optimize( ires(t), opt(t), args(1:J,t), val(t) )
    call nlo_destroy( opt(t) )
end do
!$OMP END PARALLEL DO

! Write argmax to working directory
open(unit=2, file="out.txt") 
write(2,*) args
close(2)

contains

! Function to be optimized
subroutine calfun(val, dims, args, grad, need_grad, f_data)

integer :: dims, need_grad
real(kind=8) :: val, args(dims), grad(dims)
real(kind=8) :: f_data
real(kind=8) :: sq_in =0
real(kind=8) :: lin_in = 1

! Example function has the form -2*(Sum(x(i)^2)) + Prod x(i)
if (need_grad == 0) then
    do i=1,dims
        sq_in = -2*args(i)**2 + sq_in
        lin_in = args(i)*lin_in
    end do
    val = sq_in + lin_in
end if

end subroutine calfun
end program tester

Я занимался устранением неполадок после этого документа:

https://software.intel.com/en-us/articles/determining-root-cause-of-sigsegv-or-sigbus-errors

Я также попытался сбросить размер стека после этого поста:

Почему в этом коде openmp происходит ошибка сегментации?

Выше компилируется и работает правильно, используя gfortran следующее:

$ gfortran -I/usr/local/include/ tester.f90 /usr/local/lib/libnlopt.a 
$ ./a.out

Он также компилируется, когда я добавляю флаг OpenMP:

$ gfortran -fopenmp -I/usr/local/include/ tester.f90 /usr/local/lib/libnlopt.a 

Тем не менее, я получаю ошибку сегментации даже после настройки (работает на Mac OSX)

$ ulimit -s 65532

Компиляция с обратной трассировкой выявляет только ошибки табуляции и неиспользуемые фиктивные аргументы из пакета NLOpt. Я в растерянности относительно того, как действовать, и мне действительно нужно распараллелить эту операцию. Нужно ли мне входить в процедуру NLOpt вручную и устанавливать что-то, используя threadprivate? Я не могу найти хорошую документацию по этому вопросу. Цените любые идеи...

(PS: Это мой первый пост в Stackexchange. Я был заядлым читателем на протяжении многих лет. Полегче на меня! Спасибо!)

0 ответов

Другие вопросы по тегам