2013-11-14 1 views
7

Я не могу заставить f2py ссылаться на параметр из модуля в отдельной подпрограмме, где он используется для определения размера входного массива. То есть параметра Я это defeind в модуле:F2PY - параметр модуля доступа из подпрограммы

! File: testmod.f90 
MODULE testmod 
INTEGER, PARAMETER :: dimsize = 20 
END MODULE testmod 

и параметр dimsize должен ссылаться в подпрограмме (не содержится в модуле) в другом файле, который будет точкой входа для моего питона модуля:

! File testsub.f90 
SUBROUTINE testsub(arg) 
USE testmod 
REAL, INTENT(IN) :: arg(dimsize) 
END SUBROUTINE testsub 

компилировать так:

f2py -m testmod -h testmod.pyf testsub.f90 
pgf90 -g -Mbounds -Mchkptr -c -fPIC testmod.f90 -o testmod.o 
pgf90 -g -Mbounds -Mchkptr -c -fPIC testsub.f90 -o testsub.o 
f2py -c testmod.pyf testmod.o testsub.o 

но получаю эту ошибку:

testmodmodule.c: In function 'f2py_rout_testmod_testsub': 
testmodmodule.c:180: error: 'dimsize' undeclared (first use in this function) 

Я попытался модифицировать testsub.g90 включить следующую директиву, как предложено Ní другие должности:

SUBROUTINE testsub(arg) 
USE testmod 
!f2py integer, parameter :: dimsize 
REAL, INTENT(IN) :: arg(dimsize) 
END SUBROUTINE testsub 

, но безрезультатно. Мне нужно оставить подпрограмму отдельно от модуля.

Как я могу получить f2py, чтобы правильно разрешить переменную dimsize?

ТИА

+0

У меня такая же проблема с 'ifort' в Windows 7 с использованием f2py версии 2. Проблема возникает в вызове _first_ f2py, где я вижу ошибку: ' In:: testmoddd: testsub.f90: testub get_useparameters: нет информации о модуле testmod, используемой testub В:: testmoddd: testsub.f90: testsub getarrlen: переменная «dimsize» undefined' – bdforbes

+0

@bdforbes: hmmm .... Я начинаю думать, что это просто серьезный недостаток f2py при использовании Fortran90. Я должен был придерживаться F77! – ccbunney

ответ

1

Хотя я не проверял, я думаю вы почти иметь его с исходным кодом. Мы делаем что-то подобное для некоторых наших кодов, но с gfortran.

Вам не нужно указывать f2py файл testmod.f90. Вы должны просто скомпилировать его в объектный файл так же, как если бы это были нормальные Fortran:

pgf90 -g -Mbounds -Mchkptr -c -fPIC testmod.f90 -o testmod.o 

Тогда вы должны быть в состоянии скомпилировать testsub.f90 в питона Многоразовый модуль с:

f2py --fcompiler=pgf90 --f90flags="-g -Mbounds -Mchkptr" -c testsub.f90 -m testsub testmod.o 

Это должно построить testub.so или эквивалент, позволяя вам import testsub, а затем testsub.testsub(my_arg) в python.

+0

Спасибо за ответ, но, к сожалению, я получаю ту же ошибку ... – ccbunney

+0

Хммм, вы пробовали с другим компилятором? Я только когда-либо использовал gfortran с f2py ... – cm2

+1

Я попробовал еще раз с --fcompiler = gfortran, но я получаю те же ошибки. По сути, компилятор c создает ошибки, а не компилятор fortran. Я думаю, что f2py просто не поддерживает модули F90 ... – ccbunney

2

Прошло много времени с тех пор, как этот вопрос получил какое-либо действие, но я решил проблему, поэтому я решил опубликовать ее для всех, у кого есть эта проблема. Проблема в том, что, хотя код Fortran совершенно корректен, оболочка C, сгенерированная F2PY, не знает, что такое dimsize, когда он проверяет правильность размера массива (в оболочке C он инкапсулирован в некоторую структуру модуля).

Просто измените этот код:

SUBROUTINE testsub(arg) 
USE testmod 
!f2py integer, parameter :: dimsize 
REAL, INTENT(IN) :: arg(dimsize) 
END SUBROUTINE testsub 

к этому:

SUBROUTINE testsub(arg) 
USE testmod 
!f2py integer, intent(aux) :: dimsize 
REAL, INTENT(IN) :: arg(dimsize) 
END SUBROUTINE testsub 

Это будет "Определить вспомогательные переменные C в F2PY генерируемой функции обертки". Как говорит Scipy docs, это «полезно сохранять значения параметров, чтобы к ним можно было получить доступ при инициализации выражения других переменных».

Я не тестировал это с помощью вашего кода, но я тестировал его с аналогичной ситуацией, с которой я столкнулся.

+0

приятно! У меня также была эта проблема при объявлении массива в подпрограмме, размер которой использовал параметр, определенный в * том же * модуле, и это исправило это. –