2016-10-16 2 views
0

У меня есть подпрограмма, которая вычисляет большой массив и записывает его в файл. Я пытаюсь преобразовать это в функцию, которая возвращает этот массив. Тем не менее, я получаю очень странную ошибку, которая, похоже, связана с тем, что я возвращаю массив. Когда я пытаюсь вернуть float (как тест), он работает отлично.Компиляция функции f90, которая возвращает массив, используя f2py

Вот MWE, которую я называю из питона с mwe('dir', 'postpfile', 150, 90.):

FUNCTION mwe(dir, postpfile, nz, z_scale) 
IMPLICIT NONE 

INTEGER   :: nz 
REAL(KIND=8) :: z_scale 
CHARACTER(len=100)  :: postpfile 
CHARACTER(len=100)   :: dir 
REAL(kind=8) :: mwe 

print*,'dir ', dir 
print*,'postpfile ', postpfile 
print*,'nz ', nz 
print*,'Lz ', z_scale 

mwe = 4.5d0 
END FUNCTION mwe 

Это хорошо работает и печатает, как и ожидалось:

dir dir                         
postpfile postpfile                       
nz   150 
Lz 90.000000000000000  

Однако, если определить функцию как массив:

FUNCTION mwe(dir, postpfile, nz, z_scale) 
IMPLICIT NONE 

INTEGER   :: nz 
REAL(KIND=8) :: z_scale 
CHARACTER(len=100)  :: postpfile 
CHARACTER(len=100)   :: dir 
REAL(KIND=8),DIMENSION (2,23) :: mwe 

print*,'dir ', dir 
print*,'postpfile ', postpfile 
print*,'nz ', nz 
print*,'Lz ', z_scale 

mwe = 4.5d0 
END FUNCTION mwe 

Затем он печатает это:

dir postpfile                       
postpfile ��:����������k�� 2����[email protected](����H���;�!��v 
nz   0 
Segmentation fault (core dumped) 

Я запускаю f2py версию 2, NumPy 1.11.1 и Python 3.5.1.

EDIT

Я компиляция с f2py -c -m fmwe fmwe.f90 и вызовом функции с mwe('dir', 'postpfile', 150, 90.).

+0

@ JonatanÖström Вот новый вопрос. Таким образом, вы можете проверить мой MWE. – TomCho

+1

эти фрагменты кода одинаковы. –

+0

@ ŁukaszRogalski мой плохой. Просто исправил это. – TomCho

ответ

1

Я думаю, что проблема возникает откуда-то из-за отсутствия явного интерфейса. (не уверен, что кто-то еще может указать, в чем проблема более точно.)

Хотя я не уверен в своих объяснениях, у меня есть 2 рабочих случая. Изменение функции в подпрограмме или , помещая вашу функцию внутри модуля (который генерирует явный интерфейс сам по себе) решает проблему, о которой вы упомянули.

Ниже сценария еще можно назвать как my_sub('dir', 'postpfile', 150, 90.) из python.

subroutine my_sub(mwe, dir, postpfile, nz, z_scale) 
implicit none 

integer,intent(in)    :: nz 
real(KIND=8),intent(in)  :: z_scale 
chracter(len=100),intent(in) :: postpfile 
character(len=100), intent(in) :: dir 
real(KIND=8), intent(out)  :: mwe(2,23) 

print*,'dir ', dir 
print*,'postpfile ', postpfile 
print*,'nz ', nz 
print*,'Lz ', z_scale 

mwe = 4.5d0 
end subroutine my_sub 

Если вы используете функцию внутри модуля, вам нужно сделать вызов с python немного по-другому; test('dir', 'postpfile', 150, 90.).

module test 

contains 
function mwe(dir, postpfile, nz, z_scale) 
implicit none 

integer   :: nz 
real(KIND=8)  :: z_scale 
chracter   :: postpfile 
character(len=100) :: dir 
real(KIND=8)  :: mwe(2,23) 

print*,'dir ', dir 
print*,'postpfile ', postpfile 
print*,'nz ', nz 
print*,'Lz ', z_scale 

mwe = 4.5d0 
end function mwe 

end module test 

Я не пробовал, но это вероятно, будет работать с надлежащей Fortran interface включая вашу функцию. (При условии, наличие явного интерфейса является ключом)

Я надеюсь, что кто-то завершит/исправить мой ответ.