python - 使用 ctypes 从 numba 调用 fortran

标签 python fortran ctypes numba

考虑文件 test.f90 中的这个 Fortran 模块

module mymod
  use iso_c_binding, only: c_double
  implicit none
contains
  subroutine addstuff(a,b,c) bind(c,name='addstuff_wrap')
    real(c_double), intent(in) :: a, b
    real(c_double), intent(out) :: c
    c = a + b
  end subroutine
end module

可以使用 gfortran test.f90 -shared -fPIC -o test.so 进行编译。我可以从 python 中调用它

import ctypes as ct
mylib = ct.CDLL('test.so')
addstuff.argtypes = [ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.POINTER(ct.c_double)]
addstuff.restype = None

a = ct.c_double(1.0)
b = ct.c_double(2.0)
c = ct.c_double()

addstuff(ct.byref(a),ct.byref(b),ct.byref(c))
print(c.value)

这将返回正确的答案,3.0。但是,我想从 numba jitted 函数调用它

from numba import njit
@njit
def test(a, b):
    c = ct.c_double()
    addstuff(ct.byref(ct.c_double(a)), \
             ct.byref(ct.c_double(b)), \
             ct.byref(c))
    return c.value
test(1.0, 2.0)

但这行不通。它返回错误

TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Unknown attribute 'c_double' of type Module(<module 'ctypes' from ...)

File "<ipython-input-14-f8fb94981395>", line 3:
def test(a, b):
    c = ct.c_double()
    ^

有人知道解决方法吗?这很烦人,因为 numba does claim它支持 c_double 类型。

最佳答案

解决方案如下:

import ctypes as ct
from numba import njit

mylib = ct.CDLL('test.so')
addstuff.argtypes = [ct.c_void_p, ct.c_void_p, ct.c_void_p]
addstuff.restype = None

@njit
def test(a, b):
    aa = np.array(a,np.float64)
    bb = np.array(b,np.float64)
    c = np.array(0.0,np.float64)
    addstuff(aa.ctypes.data, \
             bb.ctypes.data, \
             c.ctypes.data)
    return c.item()

关于python - 使用 ctypes 从 numba 调用 fortran,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67409406/

相关文章:

c - Makefile FFLAGS 描述

c++ - 使用 ctypes.cdll.LoadLibrary 从 Python 加载库时 ELF header 无效

python - ctypes 中的硬类型转换可能吗?例如 int -> "pointer to struct"

c++ - 如何从 python 程序调用 C++ 对象中定义的函数?

python xlsxwriter 缺少图表

WebDAV 的 Python 客户端库

python - 如何使用 Django 在一个查询中从多个表中进行选择?

python - 在 SuSE 11.1 64 位上安装 yum

FORTRAN 77 除以零行为

fortran - 在 mpi 中使用可分配数组发送派生类型数据时出现 seg 错误