Table of Contents

上一个主题

数组迭代器API

下一个主题

通用函数API

UFUNC API

常量

UFUNC_ERR_{HANDLER}

{{HANDLER}} 可以是 IGNOREWARNRAISECALL

UFUNC_{THING}_{ERR}

{{THING}} 可以是 MASKSHIFTFPE{{ERR}} 可以是 DIVIDEBYZEROOVERFLOWUNDERFLOWINVALID .

PyUFunc_{VALUE}

{{VALUE}} 可以是 One (1) Zero (0),或 None (- 1)

宏指令

NPY_LOOP_BEGIN_THREADS

在通用函数代码中使用,仅在loop->obj不为真时释放python gil( i.e. 这不是对象数组循环)。需要使用 NPY_BEGIN_THREADS_DEF 在变量声明区域中。

NPY_LOOP_END_THREADS

在通用函数代码中用于在释放python gil时重新获取它(因为loop->obj不是真的)。

UFUNC_CHECK_ERROR(loop)

一种宏,用于内部检查错误,如果找到则转到“失败”。此宏在当前代码块中需要一个失败标签。这个 loop 变量必须至少有成员(obj、errormask和errorobj)。如果 loop ->obj不是零,那么 PyErr_Occurred ()被调用(意味着必须持有GIL)。如果 loop ->obj为零,那么如果 loop ->错误掩码不是零, PyUFunc_checkfperr 用参数调用 loop >错误掩码和 loop -埃尔罗杰。如果对IEEE浮点寄存器的检查结果为真,则代码重定向到必须定义的失败标签。

UFUNC_CHECK_STATUS(ret)

已弃用:请改用npy_math.h中的npy_clear_floatstatus。

扩展到依赖于平台的代码的宏。这个 ret 变量可以是任何整数。这个 UFUNC_FPE_{{ERR}} 位设置为 ret 根据浮点处理器的相应错误标志的状态。

功能

PyObject* PyUFunc_FromFuncAndData(PyUFuncGenericFunction* func, void** data, char* types, int ntypes, int nin, int nout, int identity, char* name, char* doc, int unused)

从所需变量创建新的广播通用函数。每个ufunc都围绕一个元素一个元素操作的概念构建。每个UFUNC对象都包含指向1-D循环的指针,这些循环实现了每个支持类型的基本功能。

注解

这个 funcdata类型namedoc 参数未被复制 PyUFunc_FromFuncAndData . 调用方必须确保这些数组使用的内存不会被释放,只要ufunc对象是活动的。

参数:
  • func -- 必须为长度数组 n型 包含 PyUFuncGenericFunction 项目。这些项是指向实际实现基础(逐元素)函数的函数的指针。 N 带有以下签名的时间:…C:函数::void loopfunc(char ** args, npy_intp* dimensions, npy_intp* steps, void* data) args An array of pointers to the actual data for the input and output arrays. The input arguments are given first followed by the output arguments. dimensions A pointer to the size of the dimension over which this function is looping. steps A pointer to the number of bytes to jump to get to the next element in this dimension for each of the input and output arguments. data Arbitrary data (extra arguments, function names, etc. ) that can be stored with the ufunc and will be passed in when it is called. This is an example of a func specialized for addition of doubles returning doubles. .. code-block:: c static void double_add(char ** 阿格斯 dimensions, npy_intp * 台阶,空 [extra) {{ npy_intp i; npy_intp is1 = steps[0], is2 = steps[1]; npy_intp os = steps[2], n = dimensions[0]; char ] I1= ARGS [0] , [i2 = args[1], ] OP= ARGS [2] ;对于(i=0;i<n;i++){ *(双) = OP) (双) (i1)+ (双) )i2);i1+=is1;i2+=is2;op+=os;
  • data -- 应该是 NULL 或指向大小数组的指针 n型 . 此数组可能包含要传递给func数组中相应循环函数的任意额外数据。
  • types -- 长度 (nin + nout) * ntypes 数组 char 编码 numpy.dtype.num (仅内置)在 func 数组接受。例如,将ufunc与三个 ntypesnin 一个 nout ,其中第一个函数接受 numpy.int32 第二个呢 numpy.int64 ,两者都返回 numpy.bool_types 将是 (char[]) {{5, 5, 0, 7, 7, 0}} 自从 NPY_INT32 是5, NPY_INT64 是7, NPY_BOOL 是0。也可以使用位宽度名称(例如 NPY_INT32NPY_COMPLEX128 如果需要的话。 铸造规则 将在运行时用于查找第一个 func 可通过提供的输入/输出进行调用。
  • ntypes -- UFUNC实现了多少种不同的数据类型特定函数。
  • nin -- 此操作的输入数。
  • nout -- 输出的数量
  • identity -- 要么 PyUFunc_OnePyUFunc_ZeroPyUFunc_MinusOnePyUFunc_None . 这指定将空数组传递给ufunc的reduce方法时应返回的内容。特殊价值 PyUFunc_IdentityValue 只能用于 PyUFunc_FromFuncAndDataAndSignatureAndIdentity 方法,以允许将任意python对象用作标识。
  • name -- ufunc的名称作为 NULL 终止的字符串。如果指定“add”或“multiple”的名称,则在未指定任何数据类型时,可以为整数类型的缩减启用特殊的行为。如果输入类型是小于 numpy.int_ 数据类型,它将在内部向上转换为 numpy.int_ (或) numpy.uint )数据类型。
  • doc -- 允许传入要与ufunc一起存储的文档字符串。文档字符串不应包含函数名或调用签名,因为在访问 __doc__ ufunc的属性。
  • unused -- 为了C-API的向后兼容性而未使用和存在。
PyObject* PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction* func, void** data, char* types, int ntypes, int nin, int nout, int identity, char* name, char* doc, int unused, char *signature)

此函数与上面的pyufunc_fromfuncddata非常相似,但有一个额外的 签名 参数,定义 generalized universal functions . 类似于UFunc是如何围绕一个元素一个元素的操作构建的,gufuncs是围绕一个元素一个元素一个元素的操作构建的。 signature 定义要操作的子数组。

参数:
  • signature -- 新Gufunc的签名。将其设置为空相当于调用pyufunc_fromfuncddata。复制字符串,以便释放传入的缓冲区。
PyObject* PyUFunc_FromFuncAndDataAndSignatureAndIdentity(
PyUFuncGenericFunction *func, void **data, char *types, int ntypes, int nin, int nout, int identity, char *name, char *doc, int unused, char *signature,
PyObject *identity_value)

此函数与 PyUFunc_FromFuncAndDataAndSignature 上面,但有一个额外的 identity_value 参数,当 identity 传递为 PyUFunc_IdentityValue .

参数:
  • identity_value -- 新Gufunc的身份。必须作为 NULL 除非 identity 论证是 PyUFunc_IdentityValue . 将其设置为空相当于调用pyufunc_FromFuncndDataAndSignature。
int PyUFunc_RegisterLoopForType(PyUFuncObject* ufunc, int usertype, PyUFuncGenericFunction function, int* arg_types, void* data)

此函数允许用户使用已创建的ufunc注册一维循环,以便在使用任何输入参数作为用户定义的数据类型调用ufunc时使用。这是为了让UFUNC与内置数据类型一起工作。数据类型必须已在numpy系统中注册。循环作为 功能 . 此循环可以接受任意数据,这些数据应作为 data . 循环所需的数据类型作为 arg_types 它必须是指向内存的指针,大小至少与ufunc->nargs相同。

int PyUFunc_RegisterLoopForDescr(PyUFuncObject* ufunc, PyArray_Descr* userdtype, PyUFuncGenericFunction function, PyArray_Descr** arg_dtypes, void* data)

此函数的行为类似于上面的pyufunc_registerloopfortype,但它允许用户使用pyarray_descr对象而不是d type type num值注册一维循环。这允许为结构化数组数据类型和自定义数据类型(而不是标量数据类型)注册一维循环。

int PyUFunc_ReplaceLoopBySignature(PyUFuncObject* ufunc, PyUFuncGenericFunction newfunc, int* signature, PyUFuncGenericFunction* oldfunc)

替换与给定值匹配的一维循环 签名 在已经创建的 乌洛克 使用新的一维循环newfunc。返回旧的一维循环函数 奥尔德芬克 . 成功时返回0,失败时返回-1。此函数仅适用于内置类型(使用 PyUFunc_RegisterLoopForType 对于用户定义的类型)。签名是一个数据类型数字数组,指示输入,后跟一维循环假定的输出。

int PyUFunc_GenericFunction(PyUFuncObject* self, PyObject* args, PyObject* kwds, PyArrayObject** mps)

通用的ufunc调用。ufunc作为 self ,ufunc的参数为 argskwds . 这个 mps 参数是一个数组 PyArrayObject 指针,其值被丢弃,并在返回success时接收转换的输入参数和ufunc输出。用户负责管理此数组,并接收中每个数组的新引用。 mps . 中的数组总数 mps 是由 self -nn+ self -NUOT。

成功时返回0,错误时返回1。

int PyUFunc_checkfperr(int errmask, PyObject* errobj)

一个简单的接口到IEEE错误标志检查支持。这个 错误掩码 参数是的掩码 UFUNC_MASK_{{ERR}} 位掩码指示要检查的错误(以及如何检查错误)。这个 埃罗布吉 必须是一个包含两个元素的python元组:一个包含将在任何错误通信中使用的名称的字符串,以及一个可调用的python对象(回调函数)或 Py_None . 只有在以下情况下才使用可调用对象: UFUNC_ERR_CALL 设置为所需的错误检查方法。这个程序管理gil,即使在释放gil之后也可以安全地调用。如果确定IEEE兼容硬件中存在错误,则返回-1,否则返回0。

void PyUFunc_clearfperr()

清除IEEE错误标志。

void PyUFunc_GetPyValues(char* name, int* bufsize, int* errmask, PyObject** errobj)

从线程本地存储区域获取用于ufunc处理的python值,除非设置了默认值,在这种情况下,将忽略名称查找。名称作为字符串放在 *errobj . 第二个元素是在错误回调时调用的查找函数。将要使用的查找缓冲区大小的值传递给 蟾蜍尺码 ,并将错误掩码的值放入 错误掩码 .

通用函数

每个ufunc的核心是一组特定于类型的函数,这些函数定义了每个支持类型的基本功能。这些函数必须计算基础函数 N\geq1 时代。在计算过程中可能会用到额外的数据。此功能允许将一些常规函数用作这些基本循环函数。通用函数具有将变量指向正确位置并设置函数调用所需的所有代码。常规函数假定要调用的实际函数作为额外数据传入,并使用正确的值调用它。所有这些函数都适用于直接放置在pyufunobject结构的函数成员中存储的函数数组中。

void PyUFunc_f_f_As_d_d(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_d_d(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_f_f(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_g_g(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_F_F_As_D_D(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_F_F(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_D_D(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_G_G(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_e_e(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_e_e_As_f_f(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_e_e_As_d_d(char** args, npy_intp* dimensions, npy_intp* steps, void* func)

UFUNC的类型特定的核心一维函数,通过调用一个接受一个输入参数并返回一个输出的函数来获得每个计算。此函数已传入 func . 字母对应于支持的数据类型的dtypechar( e 一半, f -浮动, d -双, g -长双倍, F -cFLASH, D -Couple, G -克隆双)。争论 func 必须支持相同的签名。_as_x_x变量假定Ndarray是一种数据类型,但将值强制转换为使用具有不同数据类型的基础函数。因此, PyUFunc_f_f_As_d_d 使用数据类型的ndarrays NPY_FLOAT 但调用一个接受double并返回double的C函数。

void PyUFunc_ff_f_As_dd_d(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_ff_f(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_dd_d(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_gg_g(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_FF_F_As_DD_D(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_DD_D(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_FF_F(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_GG_G(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_ee_e(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_ee_e_As_ff_f(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_ee_e_As_dd_d(char** args, npy_intp* dimensions, npy_intp* steps, void* func)

UFUNC的类型特定的核心一维函数,其中每个计算通过调用一个接受两个输入参数并返回一个输出的函数来获得。要调用的基础函数作为 func . 字母对应于通用函数支持的特定数据类型的DTypechar。争论 func 必须支持相应的签名。这个 _As_XX_X 变量假定一个数据类型的ndarrays,但在循环的每个迭代中强制转换值,以使用采用不同数据类型的基础函数。

void PyUFunc_O_O(char** args, npy_intp* dimensions, npy_intp* steps, void* func)
void PyUFunc_OO_O(char** args, npy_intp* dimensions, npy_intp* steps, void* func)

一个输入、一个输出和两个输入、一个输出核心的一维函数 NPY_OBJECT 数据类型。这些函数处理引用计数问题,并在出错时提前返回。要调用的实际函数是 func 它必须接受有签名的电话 (PyObject*) (PyObject*) 对于 PyUFunc_O_O(PyObject*)(PyObject *, PyObject *) 对于 PyUFunc_OO_O .

void PyUFunc_O_O_method(char** args, npy_intp* dimensions, npy_intp* steps, void* func)

这个通用的一维核心函数假定 func 是表示输入对象的方法的字符串。对于循环的每次迭代,都会从数组及其 func 调用方法,将结果返回到输出数组。

void PyUFunc_OO_O_method(char** args, npy_intp* dimensions, npy_intp* steps, void* func)

这个通用的一维核心函数假定 func 表示接受一个参数的输入对象的方法的字符串。中的第一个论点 args 是其函数被调用的方法,是中的第二个参数 args 是传递给函数的参数。函数的输出存储在 args .

void PyUFunc_On_Om(char** args, npy_intp* dimensions, npy_intp* steps, void* func)

这是umath.frompyfunc(函数,nin,nout)创建的动态ufunc使用的一维核心函数。在这种情况下 func 是指向 PyUFunc_PyFuncData 具有定义的结构

PyUFunc_PyFuncData
typedef struct {
    int nin;
    int nout;
    PyObject *callable;
} PyUFunc_PyFuncData;

在循环的每个迭代中, nin 输入对象从它们的对象数组中提取出来并放入参数元组python中。 可赎回的 使用输入参数调用,并将nout输出放入其对象数组中。

导入API

PY_UFUNC_UNIQUE_SYMBOL
NO_IMPORT_UFUNC
void import_ufunc(void)

这些是用于从扩展模块访问ufunc c-api的常量和函数,与访问数组c-api的方式完全相同。这个 import_ufunc 必须始终调用()函数(在扩展模块的初始化子例程中)。如果扩展模块在一个文件中,那么这就是所需的全部内容。如果扩展模块使用多个文件,则其他两个常量非常有用。在这种情况下,定义 PY_UFUNC_UNIQUE_SYMBOL 对于代码和源文件中不包含模块初始化功能但仍需要访问ufunc api的唯一内容,请定义 PY_UFUNC_UNIQUE_SYMBOL 与以前使用的名称相同,并且还定义 NO_IMPORT_UFUNC .

C-API实际上是一个函数指针数组。此数组由import-ufunc创建(并由全局变量指向)。全局变量要么静态定义,要么允许其他文件查看,具体取决于 PY_UFUNC_UNIQUE_SYMBOLNO_IMPORT_UFUNC .