UFunc API
Константы
UFUNC_ERR_{HANDLER}-
- UFUNC_ERR_IGNORE
- UFUNC_ERR_WARN
- UFUNC_ERR_RAISE
- UFUNC_ERR_CALL
- UFUNC_ERR_IGNORE
UFUNC_{THING}_{ERR}-
- UFUNC_MASK_DIVIDEBYZERO
- UFUNC_MASK_OVERFLOW
- UFUNC_MASK_UNDERFLOW
- UFUNC_MASK_INVALID
- UFUNC_SHIFT_DIVIDEBYZERO
- UFUNC_SHIFT_OVERFLOW
- UFUNC_SHIFT_UNDERFLOW
- UFUNC_SHIFT_INVALID
- UFUNC_FPE_DIVIDEBYZERO
- UFUNC_FPE_OVERFLOW
- UFUNC_FPE_UNDERFLOW
- UFUNC_FPE_INVALID
- UFUNC_MASK_DIVIDEBYZERO
PyUFunc_{VALUE}-
- PyUFunc_One
- PyUFunc_Zero
- PyUFunc_MinusOne
- PyUFunc_ReorderableNone
- PyUFunc_None
- PyUFunc_IdentityValue
- PyUFunc_One
Макросы
- NPY_LOOP_BEGIN_THREADS
-
Используется в коде универсальных функций для освобождения блокировки Python GIL только в том случае, если loop->obj не равно true (т.е. это не цикл для массивов типа OBJECT). Требуется использование
NPY_BEGIN_THREADS_DEFв области объявления переменных.
- NPY_LOOP_END_THREADS
-
Используется в коде универсальных функций для повторного получения блокировки Python GIL, если она была освобождена (потому что loop->obj не было равно true).
Типы
- typePyUFuncGenericFunction
-
Указатели на функции, которые фактически реализуют базовую (элементо-по-элементу) функцию \(N\) раз со следующим сигнатурой:
- voidloopfunc(char**args, npy_intpconst*dimensions, npy_intpconst*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; } }
- voidloopfunc(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*data)
Функции
- PyObject*PyUFunc_FromFuncAndData(PyUFuncGenericFunction*func, void**data, char*types, intntypes, intnin, intnout, intidentity, char*name, char*doc, intunused)
-
Создание нового универсального функционального объекта (ufunc) на основе предоставленных переменных. Каждый ufunc построен вокруг понятия операции по элементам. Каждый объект ufunc содержит указатели на одномерные циклы, реализующие основную функциональность для каждого поддерживаемого типа.
Примечание
Аргументы func, data, types, name и doc не копируются функцией
PyUFunc_FromFuncAndData. Вызывающая функция должна гарантировать, что память, используемая этими массивами, не освобождается до тех пор, пока объект ufunc жив.- Параметры
-
-
func – Должен указывать на массив длиной ntypes, содержащий элементы типа
PyUFuncGenericFunction. -
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).Правила приведения типов будут использоваться во время выполнения для поиска первой вызываемой функции, подходящей для входных/выходных данных.
- ntypes – Количество функций, реализующих ufunc для различных типов данных.
- nin – Количество входных аргументов операции.
- nout – Количество выходных аргументов.
-
identity – Одно из значений
PyUFunc_One,PyUFunc_Zero,PyUFunc_MinusOneилиPyUFunc_None. Это определяет, что должно возвращаться, когда в метод reduce ufunc передаётся пустой массив. Специальное значениеPyUFunc_IdentityValueможет использоваться только с методомPyUFunc_FromFuncAndDataAndSignatureAndIdentity, чтобы разрешить использование произвольного объекта Python в качестве идентичности. - name – Имя ufunc в виде строки, завершённой нулём.
- doc – Допускает передачу документационной строки для хранения с ufunc. Документационная строка не должна содержать имя функции или вызов, так как это будет динамически определяться из объекта и будет доступно при обращении к атрибуту __doc__ ufunc.
- unused – Не используется и присутствует для обратной совместимости C-API.
-
func – Должен указывать на массив длиной ntypes, содержащий элементы типа
- PyObject*PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction*func, void**data, char*types, intntypes, intnin, intnout, intidentity, char*name, char*doc, intunused, char*signature)
-
Эта функция очень похожа на PyUFunc_FromFuncAndData выше, но имеет дополнительный аргумент signature для определения обобщённых универсальных функций. Аналогично тому, как ufunc построены вокруг операции по элементам, gufunc построены вокруг операций по подмассивам, причём подпись определяет подмассивы, над которыми производится операция.
- Параметры
-
- signature – Подпись для нового gufunc. Установка в NULL эквивалентна вызову PyUFunc_FromFuncAndData. Создаётся копия строки, поэтому переданный буфер можно освободить.
- PyObject*PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction*func, void**data, char*types, intntypes, intnin, intnout, intidentity, char*name, char*doc, intunused, 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. Должен передаваться как
- intPyUFunc_RegisterLoopForType(PyUFuncObject*ufunc, intusertype, PyUFuncGenericFunctionfunction, int*arg_types, void*data)
-
Эта функция позволяет пользователю зарегистрировать цикл 1D с уже созданным ufunc, который будет использоваться всякий раз, когда ufunc вызывается с любым из его входных аргументов в качестве пользовательского типа данных. Это необходимо для работы ufunc с встроенными типами данных. Тип данных должен быть предварительно зарегистрирован в системе numpy. Цикл передаётся как function. Этот цикл может принимать произвольные данные, которые должны передаваться как data. Требуемые типы данных для цикла передаются как arg_types, которые должны быть указателями на память, размер которой не меньше ufunc->nargs.
- intPyUFunc_RegisterLoopForDescr(PyUFuncObject*ufunc, PyArray_Descr*userdtype, PyUFuncGenericFunctionfunction, PyArray_Descr**arg_dtypes, void*data)
-
Эта функция работает аналогично PyUFunc_RegisterLoopForType выше, за исключением того, что она позволяет пользователю регистрировать цикл 1D с использованием объектов PyArray_Descr вместо значений num типа данных. Это позволяет зарегистрировать цикл 1D для структурированных массивов данных и пользовательских типов данных вместо скалярных типов данных.
- intPyUFunc_ReplaceLoopBySignature(PyUFuncObject*ufunc, PyUFuncGenericFunctionnewfunc, int*signature, PyUFuncGenericFunction*oldfunc)
-
Заменить цикл 1D, соответствующий заданному signature, в уже созданном ufunc, новым циклом 1D newfunc. Возвращает старый цикл 1D в oldfunc. Возвращает 0 при успехе и -1 при ошибке. Эта функция работает только со встроенными типами (используйте
PyUFunc_RegisterLoopForTypeдля пользовательских типов). Подпись — массив номеров типов данных, указывающих на входные значения, за которыми следуют выходные значения, предполагаемые циклом 1D.
- intPyUFunc_checkfperr(interrmask, PyObject*errobj)
-
Простой интерфейс для проверки флагов ошибок IEEE. Аргумент errmask — маска
UFUNC_MASK_{ERR}битовых масок, указывающих, какие ошибки нужно проверять (и как их проверять). errobj должен быть кортежем Python с двумя элементами: строкой, содержащей имя, которое будет использоваться при любом сообщении об ошибке, и либо вызываемым объектом Python (функцией обратного вызова), либоPy_None. Вызываемый объект будет использоваться только еслиUFUNC_ERR_CALLзадан как желаемый метод проверки ошибок. Эта функция управляет GIL и её безопасно вызывать даже после освобождения GIL. Если определяется ошибка в совместимом с IEEE оборудовании, возвращается -1, в противном случае возвращается 0.
- voidPyUFunc_clearfperr()
-
Очистить флаги ошибок IEEE.
- voidPyUFunc_GetPyValues(char*name, int*bufsize, int*errmask, PyObject**errobj)
-
Получить значения Python, используемые для обработки ufunc из области локального хранилища потока, если значения по умолчанию не заданы, в этом случае поиск по имени пропускается. Имя помещается в виде строки в первый элемент *errobj. Второй элемент — найденная функция, которая вызывается при обратном вызове по ошибке. Значение искомого размера буфера передаётся в bufsize, а значение маски ошибок — в errmask.
Общие функции
В основе каждого ufunc лежит набор функций, специфичных для типа, которые определяют основную функциональность для каждого поддерживаемого типа. Эти функции должны оценивать базовую функцию \(N\geq1\) раз. Дополнительные данные могут передаваться и использоваться во время вычисления. Эта функция позволяет использовать некоторые общие функции в качестве этих основных циклических функций. Общая функция содержит весь код, необходимый для указания переменных на правильное место и настройки вызова функции. Общая функция предполагает, что фактическая функция для вызова передаётся как дополнительные данные и вызывает её с правильными значениями. Все эти функции подходят для размещения непосредственно в массиве функций, хранящемся в члене функции структуры PyUFuncObject.
- voidPyUFunc_f_f_As_d_d(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_d_d(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_f_f(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_g_g(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_F_F_As_D_D(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_F_F(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_D_D(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_G_G(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_e_e(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_e_e_As_f_f(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_e_e_As_d_d(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
-
Тип-специфические, базовые 1-мерные функции для ufunc, где каждое вычисление получается вызовом функции, принимающей один входной аргумент и возвращающей один выходной. Эта функция передаётся в
func. Буквы соответствуют dtypechar'ам поддерживаемых типов данных (e— полуточная,f— плавающая точка,d— двойная точность,g— длинная двойная точность,F— с плавающей точкой комплексного типа,D— комплексная двойная точность,G— комплексная длинная двойная точность). Аргумент func должен поддерживать ту же сигнатуру. Варианты _As_X_X предполагают ndarray'ы одного типа данных, но преобразуют значения для использования базовой функции, принимающей другой тип данных. Таким образом,PyUFunc_f_f_As_d_dиспользует ndarray'ы типа данныхNPY_FLOAT, но вызывает функцию на С, которая принимает double и возвращает double.
- voidPyUFunc_ff_f_As_dd_d(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_ff_f(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_dd_d(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_gg_g(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_FF_F_As_DD_D(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_DD_D(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_FF_F(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_GG_G(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_ee_e(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_ee_e_As_ff_f(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_ee_e_As_dd_d(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
-
Тип-специфичные, базовые 1-мерные функции для ufunc, где каждое вычисление получается путём вызова функции, принимающей два входных аргумента и возвращающей один выходной. Подлежащая функция для вызова передаётся в виде func. Буквы соответствуют dtypechar значениям конкретного типа данных, поддерживаемого функцией общего назначения. Аргумент
funcдолжен поддерживать соответствующую сигнатуру. Варианты_As_XX_Xпредполагают ndarrays одного типа данных, но преобразуют значения на каждой итерации цикла для использования подлежащей функции, которая принимает другой тип данных.
- voidPyUFunc_O_O(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
- voidPyUFunc_OO_O(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
-
Базовые 1-мерные функции с одним входом, одним выходом и двумя входами, одним выходом для типа данных
NPY_OBJECT. Эти функции обрабатывают вопросы ссылок на счётчики и возвращают результат при ошибке. Фактическая функция для вызова - func, и она должна принимать вызовы со следующей сигнатурой(PyObject*) (PyObject*)дляPyUFunc_O_Oили(PyObject*)(PyObject *, PyObject *)дляPyUFunc_OO_O.
- voidPyUFunc_O_O_method(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
-
Эта функция общего назначения 1-мерного ядра предполагает, что func — это строка, представляющая метод объекта входных данных. На каждой итерации цикла объект Python извлекается из массива, и его метод func вызывается, возвращая результат в массив вывода.
- voidPyUFunc_OO_O_method(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
-
Эта функция общего назначения 1-мерного ядра предполагает, что func — это строка, представляющая метод объекта входных данных, который принимает один аргумент. Первый аргумент в args — это метод, функция которого вызывается, второй аргумент в args — аргумент, передаваемый функции. Результат функции сохраняется в третьем элементе args.
- voidPyUFunc_On_Om(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*func)
-
Это 1-мерная функция ядра, используемая динамическими ufunc, созданными с помощью umath.frompyfunc(function, nin, nout). В этом случае func — указатель на структуру
PyUFunc_PyFuncData, которая имеет определение- typePyUFunc_PyFuncData
-
typedef struct { int nin; int nout; PyObject *callable; } PyUFunc_PyFuncData;
На каждой итерации цикла nin входные объекты извлекаются из их массивов объектов и помещаются в кортеж аргументов, вызываемый Python callable с входными аргументами, и nout выходные данные помещаются в их массивы объектов.
- typePyUFunc_PyFuncData
Импортирование API
- PY_UFUNC_UNIQUE_SYMBOL
- NO_IMPORT_UFUNC
- voidimport_ufunc(void)
-
Это константы и функции для доступа к C-API ufunc из модулей расширения точно так же, как можно получить доступ к 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–2022 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.21/reference/c-api/ufunc.html