UFunc API
Константы
-
UFUNC_ERR_{HANDLER} -
{HANDLER}может быть IGNORE, WARN, RAISE или CALL
-
UFUNC_{THING}_{ERR} -
{THING}может быть MASK, SHIFT или FPE, а{ERR}может быть DIVIDEBYZERO, OVERFLOW, UNDERFLOW и INVALID.
-
PyUFunc_{VALUE} -
-
PyUFunc_One
-
PyUFunc_Zero
-
PyUFunc_MinusOne
-
PyUFunc_ReorderableNone
-
PyUFunc_None
-
PyUFunc_IdentityValue
-
Макросы
-
NPY_LOOP_BEGIN_THREADS -
Используется в коде универсальной функции для освобождения блокировки Python GIL только в том случае, если loop->obj не истинно (т.е. это не цикл для массива OBJECT). Требуется использование
NPY_BEGIN_THREADS_DEFв области объявления переменной.
-
NPY_LOOP_END_THREADS -
Используется в коде универсальной функции для повторного получения блокировки Python GIL, если она была освобождена (потому что loop->obj не истинно).
Функции
-
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-мерные циклы, реализующие основную функциональность для каждого поддерживаемого типа.
Примечание
Аргументы func, data, types, name и doc не копируются функцией
PyUFunc_FromFuncAndData. Вызывающая сторона должна гарантировать, что память, используемая этими массивами, не освобождается до тех пор, пока объект ufunc жив.- Параметры
-
-
func –
Должен быть массивом длины ntypes, содержащим
PyUFuncGenericFunctionэлементы. Эти элементы являются указателями на функции, которые фактически реализуют базовую (элементную поэлементную) функциюраз с указанным сигнатурой:
-
void loopfunc( -
char** args, npy_intp const *dimensions, npy_intp const *steps, void* data) -
args
Массив указателей на фактические данные для входных и выходных массивов. Входные аргументы указываются первыми, а затем выходные аргументы.
dimensions
Указатель на размер измерения, по которому эта функция итерируется.
steps
Указатель на количество байтов, которые необходимо пропустить, чтобы перейти к следующему элементу в данном измерении для каждого входного и выходного аргументов.
data
Произвольные данные (дополнительные аргументы, имена функций и т. д.), которые могут храниться с функцией ufunc и будут передаваться при её вызове.
Это пример функции, специализирующейся на сложении чисел с плавающей точкой двойной точности, возвращающей числа с плавающей точкой двойной точности.
static void double_add(char **args, npy_intp const *dimensions, npy_intp const *steps, void *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]; for (i = 0; i < n; i++) { *((double *)op) = *((double *)i1) + *((double *)i2); i1 += is1; i2 += is2; op += os; } }
-
-
data – Должен быть
NULLили указателем на массив размером ntypes. Этот массив может содержать произвольные дополнительные данные, которые будут передаваться соответствующей функции цикла в массиве func. -
types –
Массив длины
(nin + nout) * ntypesизcharкодирующихnumpy.dtype.num(только встроенные), которые соответствующая функция в массивеfuncпринимает. Например, для сравнительной функции ufunc с тремяntypes, двумяninи одной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_INT32,NPY_COMPLEX128).Правила преобразования будут использоваться во время выполнения для поиска первой вызываемой функции
funcпо предоставленным входным/выходным данным. - ntypes – Количество различных функций, специфичных для типов данных, реализованных в ufunc.
- nin – Количество входных данных для данной операции.
- nout – Количество выходных данных
-
identity – Либо
PyUFunc_One,PyUFunc_Zero,PyUFunc_MinusOneилиPyUFunc_None. Это определяет, что должно быть возвращено, когда пустой массив передаётся в метод reduce функции ufunc. Специальное значениеPyUFunc_IdentityValueможет быть использовано только с методомPyUFunc_FromFuncAndDataAndSignatureAndIdentity, чтобы разрешить использование произвольного объекта Python в качестве идентичности. -
name – Имя функции ufunc в виде строки, завершённой
NULL. Указание имени «add» или «multiply» позволяет обеспечить специальное поведение для сокращений целочисленных типов, когда не указан тип данных. Если входной тип является целочисленным (или булевым) типом данных размером меньше размера типа данных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_FromFuncAndData выше, но имеет дополнительный аргумент signature для определения обобщённых универсальных функций. Аналогично тому, как функции ufunc строятся вокруг элементарного поэлементного действия, функции gufunc строятся вокруг действий подмассива-подмассива, и сигнатура определяет подмассивы, над которыми выполняются операции.
- Параметры
-
- signature – Сигнатура для новой функции gufunc. Установка значения NULL эквивалентна вызову PyUFunc_FromFuncAndData. Создаётся копия строки, поэтому переданный буфер можно освободить.
-
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 для определения произвольной идентичности для ufunc, когдаidentityпередаётся какPyUFunc_IdentityValue.- Параметры
-
-
identity_value – Идентичность для новой функции gufunc. Должен быть передан как
NULL, если аргументidentityне равенPyUFunc_IdentityValue. Установка значения NULL эквивалентна вызову PyUFunc_FromFuncAndDataAndSignature.
-
identity_value – Идентичность для новой функции gufunc. Должен быть передан как
-
int PyUFunc_RegisterLoopForType(PyUFuncObject* ufunc, int usertype, PyUFuncGenericFunction function, int* arg_types, void* data) -
Эта функция позволяет пользователю зарегистрировать 1-мерный цикл с уже созданной функцией ufunc, который будет использоваться всякий раз, когда функция ufunc вызывается с любым из её входных аргументов в качестве пользовательского типа данных. Это необходимо для работы функций ufunc со встроенными типами данных. Тип данных должен быть предварительно зарегистрирован в системе NumPy. Цикл передаётся как function. Этот цикл может принимать произвольные данные, которые должны быть переданы как data. Типы данных, необходимые для цикла, передаются в виде arg_types, которые должны быть указателем на память размером не менее ufunc->nargs.
-
int PyUFunc_RegisterLoopForDescr(PyUFuncObject* ufunc, PyArray_Descr* userdtype, PyUFuncGenericFunction function, PyArray_Descr** arg_dtypes, void* data) -
Эта функция работает аналогично PyUFunc_RegisterLoopForType выше, за исключением того, что она позволяет пользователю зарегистрировать 1-мерный цикл, используя объекты PyArray_Descr вместо значений num типа данных. Это позволяет зарегистрировать 1-мерный цикл для типов данных массивов со структурированными данными и пользовательских типов данных вместо скалярных типов данных.
-
int PyUFunc_ReplaceLoopBySignature(PyUFuncObject* ufunc, PyUFuncGenericFunction newfunc, int* signature, PyUFuncGenericFunction* oldfunc) -
Заменяет 1-мерный цикл, соответствующий заданной signature в уже созданной ufunc, новым 1-мерным циклом newfunc. Возвращает старую 1-мерную функцию цикла в oldfunc. Возвращает 0 при успехе и -1 при ошибке. Эта функция работает только со встроенными типами (используйте
PyUFunc_RegisterLoopForTypeдля пользовательских типов). Сигнатура — это массив чисел типов данных, указывающих входные данные, за которыми следуют выходные данные, предполагаемые 1-мерным циклом.
-
int PyUFunc_GenericFunction(PyUFuncObject* self, PyObject* args, PyObject* kwds, PyArrayObject** mps) -
Устарело начиная с версии NumPy: 1.19
Если NumPy не обнаружит проблему, эта функция запланирована для быстрого удаления без замены.
Вместо этой функции следует использовать
PyObject_Call(ufunc, args, kwds). Предыдущая функция отличается от этой тем, что она игнорирует поддержку входных данных, которые не являются массивами или подклассами массивов. Для обеспечения идентичного поведения может потребоваться преобразование всех входных данных с помощьюPyArray_FromAny(obj, NULL, 0, 0, NPY_ARRAY_ENSUREARRAY, NULL).
-
int PyUFunc_checkfperr(int errmask, PyObject* errobj) -
Простой интерфейс для проверки ошибок IEEE. Аргумент errmask — маска
UFUNC_MASK_{ERR}битов, указывающая, какие ошибки следует проверять (и как). Аргумент errobj должен быть кортежем 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) -
Получить значения Python, используемые для обработки ufunc, из области локального хранилища потока, если только значения по умолчанию не были заданы, в этом случае поиск имени пропускается. Имя помещается в строку в первом элементе *errobj. Второй элемент — найденная функция, которая вызывается при обращении к обработчику ошибок. Значение найденного размера буфера для использования передаётся в bufsize, а значение маски ошибок помещается в errmask.
Общие функции
В основе каждой ufunc лежит набор функций, специфичных для типа, которые определяют основную функциональность для каждого из поддерживаемых типов. Эти функции должны вычислять базовую функцию раз. Дополнительные данные могут передаваться и использоваться во время вычисления. Эта возможность позволяет использовать некоторые общие функции в качестве этих основных циклических функций. Общая функция содержит весь код, необходимый для указания переменных на правильные места и настройки вызова функции. Общая функция предполагает, что фактическая функция для вызова передаётся в качестве дополнительных данных и вызывается с правильными значениями. Все эти функции подходят для непосредственного размещения в массиве функций, хранящемся в члене functions структуры PyUFuncObject.
-
void PyUFunc_f_f_As_d_d(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_d_d(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_f_f(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_g_g(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_F_F_As_D_D(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_F_F(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_D_D(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_G_G(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_e_e(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_e_e_As_f_f(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_e_e_As_d_d(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func) -
Специфичные для типа основные функции 1-d для ufunc, где каждое вычисление получается путём вызова функции, принимающей один входной аргумент и возвращающей один выходной. Эта функция передаётся в
func. Буквы соответствуют dtypechar'ам поддерживаемых типов данных (e— получение,f— float,d— double,g— long double,F— cfloat,D— cdouble,G— clongdouble). Аргумент func должен поддерживать ту же сигнатуру. Варианты _As_X_X предполагают ndarray'ы одного типа данных, но преобразуют значения для использования базовой функции, принимающей другой тип данных. Таким образом,PyUFunc_f_f_As_d_dиспользует ndarray'ы типа данныхNPY_FLOAT, но обращается к C-функции, которая принимает double и возвращает double.
-
void PyUFunc_ff_f_As_dd_d(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_ff_f(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_dd_d(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_gg_g(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_FF_F_As_DD_D(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_DD_D(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_FF_F(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_GG_G(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_ee_e(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_ee_e_As_ff_f(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_ee_e_As_dd_d(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func) -
Специфичные для типа, основные 1-d функции для ufuncs, где каждое вычисление получается путём вызова функции, принимающей два входных аргумента и возвращающей один выходной. Базовая функция для вызова передаётся как func. Буквы соответствуют dtypechar'ам специфичных для типа данных, поддерживаемых универсальной функцией. Аргумент
funcдолжен поддерживать соответствующую сигнатуру. Варианты_As_XX_Xпредполагают ndarray'ы одного типа данных, но преобразуют значения на каждой итерации цикла для использования базовой функции, принимающей другой тип данных.
-
void PyUFunc_O_O(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func)
-
void PyUFunc_OO_O(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func) -
Функции ядра 1-d с одним входным и одним выходным параметром и двумя входными и одним выходным параметром для типа данных
NPY_OBJECT. Эти функции обрабатывают проблемы с учётом ссылок и возвращаются при ошибке. Фактическая вызываемая функция — func, и она должна принимать вызовы со сигнатурой(PyObject*) (PyObject*)дляPyUFunc_O_Oили(PyObject*)(PyObject *, PyObject *)дляPyUFunc_OO_O.
-
void PyUFunc_O_O_method(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func) -
Эта универсальная функция ядра 1-d предполагает, что func — строка, представляющая метод объекта входа. На каждой итерации цикла объект Python извлекается из массива, и его метод func вызывается с возвращением результата в выходной массив.
-
void PyUFunc_OO_O_method(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func) -
Эта универсальная функция ядра 1-d предполагает, что func — строка, представляющая метод объекта входа, который принимает один аргумент. Первый аргумент в args — метод, чья функция вызывается, второй аргумент в args — аргумент, передаваемый в функцию. Результат функции хранится в третьем элементе args.
-
void PyUFunc_On_Om(char** args, npy_intp const *dimensions, npy_intp const *steps, void* func) -
Это функция ядра 1-d, используемая динамическими ufuncs, созданными с помощью umath.frompyfunc(function, nin, nout). В этом случае 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с уникальным для вашего кода именем, а затем в файлах исходного кода, не содержащих функцию инициализации модуля, но всё ещё нуждающихся в доступе к API UFUNC, определитеPY_UFUNC_UNIQUE_SYMBOLс тем же именем, что и ранее, а также определитеNO_IMPORT_UFUNC.C-API фактически представляет собой массив указателей на функции. Этот массив создаётся (и к нему указывает глобальная переменная) функцией import_ufunc. Глобальная переменная либо статически определена, либо доступна другим файлам в зависимости от состояния
PY_UFUNC_UNIQUE_SYMBOLиNO_IMPORT_UFUNC.
© 2005–2020 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.19/reference/c-api/ufunc.html