5.1.@cfunc # 创建C/C++回调函数;还公开了ctypes指向该回调的回调对象
5.1.@cfunc # 创建C/C++回调函数;还公开了ctypes指向该回调的回调对象
--------------------------------------------------------------------------------------------------------------
#实例1.1:
from numba import cfunc
@cfunc("float64(float64, float64)")
def add(x, y):
return x + y
print(add.ctypes(4.0, 5.0)) # prints "9.0"
--------------------------------------------------------------------------------------------------------------
#实例1.2:
import numpy as np
from numba import cfunc
def fun(t): # 纯Python函数
return np.exp(-t) / t**2
nb_fun = cfunc("float64(float64)")(fun)# 将其编译为C回调
# 将nb_fun对象的ctypes回调传递给scipy.integrate.quad并检查结果是否与纯Python函数相同
import scipy.integrate as si
def run_fun(func):
return si.quad(func, 1, np.inf) # 接受常规Python回调或包装在ctypes回调对象中的C回调
run_fun(fun) # (0.14849550677592208, 3.8736750296130505e-10)
run_fun(nb_fun.ctypes) # (0.14849550677592208, 3.8736750296130505e-10)
--------------------------------------------------------------------------------------------------------------
5.2.指针和阵列存储器处理
# 实例2.1:实现回调:void(double *input, double *output, int m, int n)调用传递C数组
from numba import cfunc, types, carray
c_sig = types.void(types.CPointer(types.double),types.CPointer(types.double),types.intc, types.intc)
@cfunc(c_sig)
def my_callback(in_, out_, m, n):
in_array = carray(in_, (m, n))
out_array = carray(out_, (m, n))
for i in range(m):
for j in range(n):
out_array[i, j] = 2 * in_array[i, j]
--------------------------------------------------------------------------------------------------------------
# 实例2.2:处理C结构
# numba可将cffi类型转换为numba Record类型 numba.cffi_support.map_type:
from numba import cffi_support
from cffi import FFI
src = """
/* Define the C struct */
typedef struct my_struct {
int i1;
float f2;
double d3;
float af4[7]; // arrays are supported
} my_struct;
/* Define a callback function */
typedef double (*my_func)(my_struct*, size_t);
"""
ffi = FFI()
ffi.cdef(src)
# Get the function signature from *my_func*
sig = cffi_support.map_type(ffi.typeof('my_func'),
use_record_dtype=True)#True是必需否则返回指向C结构的指针作为void指针
# Make the cfunc
from numba import cfunc, carray
@cfunc(sig)
def foo(ptr, n):
base = carray(ptr, n) # view pointer as an array of my_struct
tmp = 0
for i in range(n):
tmp += base[i].i1 * base[i].f2 / base[i].d3
tmp += base[i].af4.sum() # nested arrays are like normal numpy array
return tmp
--------------------------------------------------------------------------------------------------------------
# 实例2.3: # 用nb.types.Record.make_c_struct可手动创建遵循C-结构的布局
my_struct = types.Record.make_c_struct([
# Provides a sequence of 2-tuples i.e. (name:str, type:Type)
('i1', types.int32),
('f2', types.float32),
('d3', types.float64),
('af4', types.NestedArray(dtype=types.float32, shape=(7,))),
])
--------------------------------------------------------------------------------------------------------------
来源:CSDN
作者:tcy23456
链接:https://blog.csdn.net/tcy23456/article/details/103963064