Spec-Zone.ru › NumPy 1.11

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, и он содержит типы данных (только встроенные), с которыми может работать соответствующая функция в массиве 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. Это позволяет зарегистрировать цикл 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. Функция 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 раз. Дополнительные данные могут передаваться и могут использоваться во время вычисления. Эта функция позволяет использовать некоторые общие функции в качестве этих основных циклов. Общая функция содержит весь код, необходимый для указания переменных на правильное место и подготовки вызова функции. Общая функция предполагает, что фактическая функция для вызова передаётся как дополнительные данные и вызывает её с правильными значениями. Все эти функции подходят для размещения непосредственно в массиве функций, хранящемся в члене функций структуры 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-мерные функции для ufuncs, где каждое вычисление получается вызовом функции, принимающей один входной аргумент и возвращающей один выходной. Эта функция передается в 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-мерные функции для ufuncs, где каждое вычисление получается вызовом функции, принимающей два входных аргумента и возвращающей один выходной. Базовая вызываемая функция передается как 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-го измерения с одним входом, одним выходом и двумя входами, одним выходом для типа данных 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-мерная функция ядра предполагает, что func — это строка, представляющая метод входного объекта. На каждой итерации цикла Python-объект извлекается из массива, и его метод func вызывается, возвращая результат в выходной массив.

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

Эта универсальная 1-мерная функция ядра предполагает, что func — это строка, представляющая метод входного объекта, принимающий один аргумент. Первый аргумент в args — это метод, функция которого вызывается, второй аргумент в args — это аргумент, переданный функции. Результат функции сохраняется в третьем элементе args.

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

Это функция ядра 1-го измерения, используемая динамическими 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.

© 2008–2016 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.11.0/reference/c-api.ufunc.html

Spec-Zone.ru

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