Spec-Zone.ru › NumPy 1.17

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 с плавающей точкой равен true, код перенаправляется на метку 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 содержит указатели на циклы 1D, реализующие основную функциональность для каждого поддерживаемого типа.

Примечание

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

Параметры:
  • func –

    Должен быть массивом длиной ntypes, содержащим PyUFuncGenericFunction элементы. Эти элементы являются указателями на функции, которые фактически реализуют базовую (элементную по элементу) функцию N раз со следующим сигнатуром:

    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 принимает. Например, для функции 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 – Не используется и присутствует для обеспечения обратной совместимости API C.
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.
int PyUFunc_RegisterLoopForType(PyUFuncObject* ufunc, int usertype, PyUFuncGenericFunction function, int* arg_types, void* data)

Эта функция позволяет пользователю зарегистрировать цикл 1D с уже созданной функцией 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 выше, за исключением того, что она позволяет пользователю регистрировать цикл 1D с использованием объектов PyArray_Descr вместо значений num типа данных. Это позволяет зарегистрировать цикл 1D для типов данных структурированных массивов и пользовательских типов данных вместо скалярных типов данных.

END_OF_DOCUMENT_MARKER
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, из области памяти thread-local, если не были заданы значения по умолчанию, в этом случае поиск имени пропускается. Имя помещается в виде строки в первый элемент *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 - 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)

Это константы и функции для доступа к 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.17.0/reference/c-api.ufunc.html

Spec-Zone.ru

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