F2py转换字符(*)分段错误
F2py converting character(*) segmentation fault
我正在尝试使用带有 Python 3.5 的 Fortran90 数值模型使用 f2py。
f2py -c module.f90 -m mod --fcompiler=gfortran
该模型是一个包含变量、函数和子例程的 Fortran 模块。我在这里发布了一个代码示例,它具有数值模型的所有功能
module modul
implicit none
integer :: inte
real :: re
integer, dimension(3) :: array
CHARACTER(*), PARAMETER :: chara = "helloWorld"
contains
integer function fun()
fun = array(1) + array(2) + array(3)
end function
subroutine subrout(a,b)
real, intent(out) :: b
integer, intent(out) :: a
a = inte + fun()
b = re
write(*,*) chara
end subroutine subrout
end module modul
使用 f2py 的代码转换工作正常,但是,当我在 Python 中导入模块时,我收到一个分段错误
>>> import mod
Segmentation fault (core dumped)
我意识到问题出在字符数组的未指定维度上
CHARACTER(*), PARAMETER :: chara = "helloWorld"
因为,如果我删除那行代码或我为数组分配一个固定维度(如 CHARACTER(20) ),模块在 Python.
中正常工作
1.有没有办法让它在不修改 Fortran 代码的情况下工作
(模型又长又复杂,如果可能的话,我不想
处理它)?
字符数组用于在代码中定义字符串(如错误消息)并处理文件中的 input/output。解决问题的一种方法(如果问题 1 没有答案)可以为所有字符串定义一个固定的最大维度(即 INTEGER,PARAMETER :: lenChar = 100),然后使用
CHARACTER(lenChar), PARAMETER :: chara
代替之前的声明。在这种情况下,模块已成功导入 Python 但是当我尝试修改数组内容时,它需要输入 lenChar long (同样的问题出现在其他类型的数组中,如 INTEGER 或 REAL,并且不依赖于参数属性)
mod.modul.chara = "hello"
0-th dimension must be fixed to 100 but got 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: error return without exception set
这是模型需要处理的操作,因为 "chara" 可能是数据的路径,需要在 运行 时初始化。
2。如果问题(1)没有答案而我需要以这种方式进行,我如何为数组分配一个比数组长度短的输入?
System information:
OS: Ubuntu 16.04
Python 3.5.2
f2py Version: 2
numpy Version: 1.12.1
GNU Fortran (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
您似乎混淆了可变长度字符串(无论可能是什么,类似于 Fortran 2003 中的内容)、字符串常量和采用您传递的长度的虚拟参数。可能你想要:
subroutine sub(ch)
character(*), intent(in) :: ch
print *, ch
end
这与您的示例完全不同。这里的参数 ch
将接受您传递到那里的任何长度的字符串。
问题出在假定的长度字符常量中。这足以触发错误
module m
CHARACTER(*), PARAMETER :: chara = "helloWorld"
end module m
这不是字符数组,它是假定长度的标量字符串。
完全等同于
module m
CHARACTER(10), PARAMETER :: chara = "helloWorld"
end module m
唯一的区别是,如果您懒于手动计算长度(或者您不时更改它),编译器会在前一种情况下自动获取长度。
后一个版本在 f2py 中可以正常工作:
f2py -c -m f2pychar f2pychar.f90
ipython
In [1]: import f2pychar
In [2]: print f2pychar.modul.chara
['h' 'e' 'l' 'l' 'o' 'W' 'o' 'r' 'l' 'd']
F2py 应该能看懂,但好像看不懂。这是 f2py 中的一个严重错误。只需手动输入长度,如上面的后一个示例所示。没有区别,代码是等价的。
给你的号码 (2)。它不是数组(在 Fortran 中)。数组规则不适用于此处。但更重要的是,它是一个常量,你不能给它赋值,所以我不太明白你的意思。如果你有一个字符变量,你可以毫无问题地分配一个更短的字符串:
character(10) :: ch = "abcd"
回答问题 2:
fortran 中的字符串在 f2py 中被视为字符数组。因此,在您的情况下 mod.modul.chara
是 100
个字符的数组(取决于 fortran 中指定的长度)。要将 'hello'
之类的内容输入句柄,您可以执行以下操作:
for i,j in enumerate('hello'):
mod.modul.chara[i]=j
这应该可以让您传递字符串。
我正在尝试使用带有 Python 3.5 的 Fortran90 数值模型使用 f2py。
f2py -c module.f90 -m mod --fcompiler=gfortran
该模型是一个包含变量、函数和子例程的 Fortran 模块。我在这里发布了一个代码示例,它具有数值模型的所有功能
module modul
implicit none
integer :: inte
real :: re
integer, dimension(3) :: array
CHARACTER(*), PARAMETER :: chara = "helloWorld"
contains
integer function fun()
fun = array(1) + array(2) + array(3)
end function
subroutine subrout(a,b)
real, intent(out) :: b
integer, intent(out) :: a
a = inte + fun()
b = re
write(*,*) chara
end subroutine subrout
end module modul
使用 f2py 的代码转换工作正常,但是,当我在 Python 中导入模块时,我收到一个分段错误
>>> import mod
Segmentation fault (core dumped)
我意识到问题出在字符数组的未指定维度上
CHARACTER(*), PARAMETER :: chara = "helloWorld"
因为,如果我删除那行代码或我为数组分配一个固定维度(如 CHARACTER(20) ),模块在 Python.
中正常工作1.有没有办法让它在不修改 Fortran 代码的情况下工作 (模型又长又复杂,如果可能的话,我不想 处理它)?
字符数组用于在代码中定义字符串(如错误消息)并处理文件中的 input/output。解决问题的一种方法(如果问题 1 没有答案)可以为所有字符串定义一个固定的最大维度(即 INTEGER,PARAMETER :: lenChar = 100),然后使用
CHARACTER(lenChar), PARAMETER :: chara
代替之前的声明。在这种情况下,模块已成功导入 Python 但是当我尝试修改数组内容时,它需要输入 lenChar long (同样的问题出现在其他类型的数组中,如 INTEGER 或 REAL,并且不依赖于参数属性)
mod.modul.chara = "hello"
0-th dimension must be fixed to 100 but got 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: error return without exception set
这是模型需要处理的操作,因为 "chara" 可能是数据的路径,需要在 运行 时初始化。
2。如果问题(1)没有答案而我需要以这种方式进行,我如何为数组分配一个比数组长度短的输入?
System information:
OS: Ubuntu 16.04
Python 3.5.2
f2py Version: 2
numpy Version: 1.12.1
GNU Fortran (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
您似乎混淆了可变长度字符串(无论可能是什么,类似于 Fortran 2003 中的内容)、字符串常量和采用您传递的长度的虚拟参数。可能你想要:
subroutine sub(ch)
character(*), intent(in) :: ch
print *, ch
end
这与您的示例完全不同。这里的参数 ch
将接受您传递到那里的任何长度的字符串。
问题出在假定的长度字符常量中。这足以触发错误
module m
CHARACTER(*), PARAMETER :: chara = "helloWorld"
end module m
这不是字符数组,它是假定长度的标量字符串。
完全等同于
module m
CHARACTER(10), PARAMETER :: chara = "helloWorld"
end module m
唯一的区别是,如果您懒于手动计算长度(或者您不时更改它),编译器会在前一种情况下自动获取长度。
后一个版本在 f2py 中可以正常工作:
f2py -c -m f2pychar f2pychar.f90
ipython
In [1]: import f2pychar
In [2]: print f2pychar.modul.chara
['h' 'e' 'l' 'l' 'o' 'W' 'o' 'r' 'l' 'd']
F2py 应该能看懂,但好像看不懂。这是 f2py 中的一个严重错误。只需手动输入长度,如上面的后一个示例所示。没有区别,代码是等价的。
给你的号码 (2)。它不是数组(在 Fortran 中)。数组规则不适用于此处。但更重要的是,它是一个常量,你不能给它赋值,所以我不太明白你的意思。如果你有一个字符变量,你可以毫无问题地分配一个更短的字符串:
character(10) :: ch = "abcd"
回答问题 2:
fortran 中的字符串在 f2py 中被视为字符数组。因此,在您的情况下 mod.modul.chara
是 100
个字符的数组(取决于 fortran 中指定的长度)。要将 'hello'
之类的内容输入句柄,您可以执行以下操作:
for i,j in enumerate('hello'):
mod.modul.chara[i]=j
这应该可以让您传递字符串。