UFunc API
Константы
-
UFUNC_ERR_{HANDLER} -
{HANDLER}может быть IGNORE, WARN, RAISE или CALL
-
UFUNC_{THING}_{ERR} -
{THING}может быть MASK, SHIFT или FPE, а{ERR}может быть DIVIDEBYZERO, OVERFLOW, UNDERFLOW и INVALID.
-
PyUFunc_{VALUE} -
{VALUE}может быть Один (1), Ноль (0) или Нет (-1)
Макросы
-
NPY_LOOP_BEGIN_THREADS -
Используется в коде универсальной функции, чтобы освободить блокировку Python GIL только в том случае, если loop->obj не равно true (т.е. это не цикл для массива OBJECT). Требует использования
NPY_BEGIN_THREADS_DEFв области объявления переменных.
-
NPY_LOOP_END_THREADS -
Используется в коде универсальной функции, чтобы повторно получить блокировку Python GIL, если она была освобождена (потому что loop->obj не было true).
-
UFUNC_CHECK_ERROR(loop) -
Внутренний макрос, используемый для проверки ошибок и перехода к метке fail, если ошибка найдена. Этот макрос требует метки fail в текущем блоке кода. Переменная loop должна иметь по меньшей мере члены (obj, errormask и errorobj). Если loop ->obj отлично от нуля, то вызывается
PyErr_Occurred() (это означает, что GIL должна быть захвачена). Если loop ->obj равно нулю, то если loop ->errormask отлично от нуля, вызываетсяPyUFunc_checkfperrс аргументами loop ->errormask и loop ->errobj. Если результат этой проверки регистров IEEE с плавающей запятой истинный, то код перенаправляется к метке fail, которая должна быть определена.
-
UFUNC_CHECK_STATUS(ret) -
Устарело: используйте npy_clear_floatstatus из npy_math.h вместо этого.
Макрос, который расширяется до платформозависимого кода. Переменная 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 содержит указатели на циклы 1-d, реализующие основную функциональность для каждого поддерживаемого типа.
Примечание
Аргументы func, data, types, name и doc не копируются функцией
PyUFunc_FromFuncAndData. Вызывающая сторона должна гарантировать, что память, используемая этими массивами, не освобождается до тех пор, пока объект ufunc жив.Параметры: -
func –
Должен быть массивом длиной ntypes, содержащим
PyUFuncGenericFunctionэлементы. Эти элементы — указатели на функции, которые фактически реализуют базовую (элемент-по-элементу) функциюраз со следующим сигнатуром:
-
void loopfunc( -
char** args, npy_intp* dimensions, npy_intp* steps, void* data) -
args
Массив указателей на фактические данные для входных и выходных массивов. Входные аргументы задаются первыми, затем выходные.dimensions
Указатель на размер измерения, по которому эта функция выполняет цикл.steps
Указатель на количество байт, которое нужно перепрыгнуть, чтобы перейти к следующему элементу в этом измерении для каждого из входных и выходных аргументов.data
Произвольные данные (дополнительные аргументы, имена функций и т. д.), которые могут быть сохранены с ufunc и будут переданы при вызове.Это пример функции, специализированной для сложения чисел с двойной точностью, возвращающей числа с двойной точностью.
static void double_add(char **args, npy_intp *dimensions, npy_intp *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. Например, для универсальной функции сравнения с тремя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 – Сколько различных функций, специфичных для типа данных, реализовала универсальная функция.
- nin – Количество входов для этой операции.
- nout – Количество выходов
-
identity –
PyUFunc_One,PyUFunc_Zero,PyUFunc_MinusOne, илиPyUFunc_None. Определяет, что должно возвращаться при передаче пустого массива в метод reduce универсальной функции. Специальное значениеPyUFunc_IdentityValueможет использоваться только с методомPyUFunc_FromFuncAndDataAndSignatureAndIdentity, чтобы разрешить использование произвольного объекта Python в качестве идентичности. -
name – Имя универсальной функции в виде строки, завершённой символом
NULL. Указание имени 'add' или 'multiply' активирует специальное поведение для целочисленных сокращений без указания типа данных. Если тип входных данных — целочисленный (или логический) тип данных, меньший размера типа данныхnumpy.int_, он будет неявно преобразован к типу данныхnumpy.int_(илиnumpy.uint). - doc – Позволяет передать строку документации, которая будет храниться с универсальной функцией. Строка документации не должна содержать имя функции или сигнатуру вызова, так как это будет динамически определено из объекта и доступно при обращении к атрибуту __doc__ универсальной функции.
- unused – Не используется и присутствует для обратной совместимости C-API.
-
func –
-
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 для определения обобщенных универсальных функций. Аналогично тому, как универсальные функции строятся вокруг операции элемент за элементом, обобщенные универсальные функции строятся вокруг операций подмассив за подмассивом, причем сигнатура определяет подмассивы, над которыми будут выполняться операции.
Параметры: - signature – Сигнатура для новой обобщенной универсальной функции. Установка его в 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 для определения произвольной идентичности для универсальной функции, когдаidentityпередается какPyUFunc_IdentityValue.Параметры: -
identity_value – Идентичность для новой обобщенной универсальной функции. Должен передаваться как
NULLесли аргументidentityнеPyUFunc_IdentityValue. Установка его в NULL эквивалентна вызову PyUFunc_FromFuncAndDataAndSignature.
-
identity_value – Идентичность для новой обобщенной универсальной функции. Должен передаваться как
-
int PyUFunc_RegisterLoopForType(PyUFuncObject* ufunc, int usertype, PyUFuncGenericFunction function, int* arg_types, void* data) -
Эта функция позволяет пользователю зарегистрировать цикл 1-d с уже созданной универсальной функцией, чтобы использовать его всякий раз, когда универсальная функция вызывается с любым из ее входных аргументов в качестве пользовательского типа данных. Это необходимо для работы универсальных функций со встроенными типами данных. Тип данных должен быть предварительно зарегистрирован в системе 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-d, используя объекты PyArray_Descr вместо значений типа данных dtype num. Это позволяет зарегистрировать цикл 1-d для типов данных массивов со структурированными данными и пользовательских типов данных вместо скалярных типов данных.
-
int PyUFunc_ReplaceLoopBySignature(PyUFuncObject* ufunc, PyUFuncGenericFunction newfunc, int* signature, PyUFuncGenericFunction* oldfunc) -
Заменить цикл 1-d, соответствующий заданной подписи в уже созданном ufunc, новым циклом 1-d newfunc. Возвращает функцию старого цикла 1-d в oldfunc. Возвращает 0 при успехе и -1 при ошибке. Эта функция работает только со встроенными типами (используйте
PyUFunc_RegisterLoopForTypeдля типов, определённых пользователем). Подпись — это массив чисел типа данных, указывающих на входные данные, за которыми следуют выходные данные, предполагаемые циклом 1-d.
-
int PyUFunc_GenericFunction(PyUFuncObject* self, PyObject* args, PyObject* kwds, PyArrayObject** mps) -
Общий вызов ufunc. Ufunc передаётся как self, аргументы ufunc — как args и kwds. Аргумент mps — это массив указателей на
PyArrayObject, значения которых игнорируются, и которые получают преобразованные входные аргументы, а также выходные данные ufunc при успешном возврате. Пользователь отвечает за управление этим массивом, и для каждого массива в mps он получает новую ссылку. Общее количество массивов в mps задаётся значением self ->nin + self ->nout.Возвращает 0 при успехе, -1 при ошибке.
-
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 лежит набор функций для каждого типа данных, определяющих базовую функциональность для каждого поддерживаемого типа. Эти функции должны вычислить базовую функцию раз. Дополнительные данные могут быть переданы и использованы во время вычислений. Эта функция позволяет использовать некоторые общие функции в качестве этих основных циклических функций. Общая функция содержит весь необходимый код для указания переменных в нужное место и настройки вызова функции. Общая функция предполагает, что фактическая вызываемая функция передаётся в качестве дополнительных данных и вызывается с правильными значениями. Все эти функции подходят для непосредственного размещения в массиве функций, хранящихся в члене функции структуры PyUFuncObject.
-
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) -
Функции 1-d, специфичные для типа, ядра ufunc, где каждое вычисление получается путём вызова функции, принимающей один входной аргумент и возвращающей один выходной аргумент. Эта функция передаётся в
func. Буквы соответствуют dtypechar'ам поддерживаемых типов данных (e— half,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* 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) -
Функции 1-d, специфичные для типа, ядра ufunc, где каждое вычисление получается путём вызова функции, принимающей два входных аргумента и возвращающей один выходной аргумент. Базовая вызываемая функция передаётся как func. Буквы соответствуют dtypechar'ам конкретного типа данных, поддерживаемого универсальной функцией. Аргумент
funcдолжен поддерживать соответствующую подпись. Варианты_As_XX_Xпредполагают ndarray'ы одного типа данных, но преобразуют значения на каждой итерации цикла для использования базовой функции, принимающей другой тип данных.
-
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) -
Функции ядра 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* dimensions, npy_intp* steps, void* func) -
Эта общая функция ядра 1-d предполагает, что func — это строка, представляющая метод входного объекта. На каждой итерации цикла объект Python извлекается из массива, и его метод func вызывается с возвращением результата в массив вывода.
-
void PyUFunc_OO_O_method(char** args, npy_intp* dimensions, npy_intp* steps, void* func) -
Эта общая функция ядра 1-d предполагает, что func — это строка, представляющая метод входного объекта, принимающего один аргумент. Первый аргумент в args — это метод, функция которого вызывается, второй аргумент в args — это аргумент, передаваемый функции. Вывод функции сохраняется в третьем элементе args.
-
void PyUFunc_On_Om(char** args, npy_intp* dimensions, npy_intp* steps, void* func) -
Это функция ядра 1-d, используемая динамическими ufunc, созданными с помощью 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 из модулей расширения точно так же, как к 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–2019 NumPy Developers
Licensed under the 3-clause BSD License.
https://docs.scipy.org/doc/numpy-1.16.1/reference/c-api.ufunc.html