Spec-Zone.ru › NumPy 1.15

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} может быть One (1), Zero (0) или None (-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 построена вокруг концепции элементарных операций. Каждый объект ufunc содержит указатели на 1-мерные циклы, реализующие основную функциональность для каждого поддерживаемого типа.

Примечание

Аргументы func, data, types, name и doc не копируются PyUFunc_FromFuncAndData. Вызывающий код должен гарантировать, что память, используемая этими массивами, не будет освобождена до тех пор, пока объект ufunc жив.

Параметры:
  • func – Должен быть массивом длиной ntypes, содержащим PyUFuncGenericFunction элементы. Эти элементы — указатели на функции, которые фактически реализуют функцию элементарных (элемент по элементу) операций N раз.
  • data – Должен быть NULL или указатель на массив размером ntypes. Этот массив может содержать произвольные дополнительные данные, которые будут переданы соответствующей функции 1-мерного цикла в массиве func.
  • types –

    Массив длины (nin + nout) * ntypes из char кодирования PyArray_Descr.type_num (только встроенный), который соответствующая функция в массиве func принимает. Например, для сравнительной ufunc с тремя ntypes, двумя nin и одним nout, где первая функция принимает npy_int32, а вторая npy_int64, и обе возвращают npy_bool, types будет (char[]) {5, 5, 0, 7, 7, 0}, так как NPY_INT32 равно 5, NPY_INT64 равно 7, и NPY_BOOL равно 0 (в стороне Python они представлены через dtype.num, то есть, например, dtype(np.int32).num, dtype(np.int64).num, и dtype(np.bool_).num, соответственно).

    casting-rules будут использоваться во время выполнения, чтобы найти первую func вызываемую функцию по заданным входным/выходным данным.
  • ntypes – Количество различных функций, специфичных для типов данных, реализованных ufunc.
  • nin – Количество входных данных для этой операции.
  • nout – Количество выходных данных
  • name – Название ufunc. Указание имени «add» или «multiply» позволяет использовать специальное поведение для целочисленных уменьшений, когда тип данных не задан. Если тип данных — целочисленный (или булевый) тип данных, меньший размера типа int_, он будет внутри переведен в тип данных int_ (или 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. Создается копия строки, поэтому переданный буфер можно освободить.
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 вместо значений типа dtype type 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)

Вызов универсальной функции общего назначения. 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 лежит набор функций для каждого типа данных, определяющих основные функциональные возможности для каждого из поддерживаемых типов. Эти функции должны вычислять базовую функцию N\geq1 раз. Дополнительные данные могут быть переданы и использованы во время вычислений. Эта функция позволяет использовать некоторые общие функции в качестве этих базовых циклических функций. Общая функция содержит весь необходимый код для указания переменных в нужное место и настройки вызова функции. Общая функция предполагает, что фактическая функция для вызова передается в качестве дополнительных данных и вызывается с правильными значениями. Все эти функции подходят для непосредственного размещения в массиве функций, хранящемся в члене functions структуры 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 — полуточная, f — плавающая точка, d — двойная, g — удлинённая двойная, F — комплексная плавающая точка, D — комплексная двойная, G — комплексная удлинённая двойная). Аргумент 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-функция callable с входными аргументами, а nout выходов помещаются в их массивы объектов.

Импорт API

PY_UFUNC_UNIQUE_SYMBOL
NO_IMPORT_UFUNC
void import_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–2019 NumPy Developers
Licensed under the 3-clause BSD License.
https://docs.scipy.org/doc/numpy-1.15.4/reference/c-api.ufunc.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API