ufunc API#

Константы#

UFUNC_{THING}_{ERR}

Устарело, используйте NPY_{THING}_{ERR} вместо

UFUNC_FPE_DIVIDEBYZERO#
UFUNC_FPE_OVERFLOW#
UFUNC_FPE_UNDERFLOW#
UFUNC_FPE_INVALID#
PyUFunc_{VALUE}
PyUFunc_One#
PyUFunc_Zero#
PyUFunc_MinusOne#
PyUFunc_ReorderableNone#
PyUFunc_None#
PyUFunc_IdentityValue#

Макросы#

NPY_LOOP_BEGIN_THREADS#

Используется в коде универсальных функций для освобождения Python GIL только если loop->obj не истинно (т.е. это не массив OBJECT цикл). Требует использования NPY_BEGIN_THREADS_DEF в области объявления переменных.

NPY_LOOP_END_THREADS#

Используется в коде универсальной функции для повторного получения Python GIL, если он был освобождён (потому что loop->obj не был истинным).

Типы#

тип PyUFuncGenericFunction#

Указатели на функции, которые фактически реализуют базовую (поэлементную) функцию \(N\) раз со следующей сигнатурой:

void loopfunc(char **args, npy_intp const *измерения, npy_intp const *шаги, void *данные)#
Параметры:
  • args — Массив указателей на фактические данные для входных и выходных массивов. Сначала указаны входные аргументы, затем выходные аргументы.

  • измерения – Указатель на размер измерения, по которому эта функция выполняет цикл.

  • шаги – Указатель на количество байтов для перехода к следующему элементу в этом измерении для каждого из входных и выходных аргументов.

  • данные

    Произвольные данные (дополнительные аргументы, имена функций, и т.д. ) который может храниться с ufunc и будет передан при его вызове. Может быть NULL.

    Изменено в версии 1.23.0: Принимает NULL данные в дополнение к массиву NULL значения.

Это пример функции, специализированной для сложения чисел с плавающей точкой двойной точности, возвращающей числа с плавающей точкой двойной точности.

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;
     }
}

Функции#

PyObject *PyUFunc_FromFuncAndData(PyUFuncGenericFunction *функция, void *const *данные, const char *типы, int ntypes, int nin, int nout, int идентичность, const char *имя, const char *doc, int неиспользуемый)#

Создать новую широковещательную универсальную функцию из требуемых переменных. Каждая ufunc строится вокруг понятия поэлементной операции. Каждый объект ufunc содержит указатели на 1-d циклы, реализующие базовую функциональность для каждого поддерживаемого типа.

Примечание

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

Параметры:
  • функция – Должен указывать на массив, содержащий ntypes PyUFuncGenericFunction элементы.

  • данные – Должно быть NULL или указатель на массив размера ntypes. Этот массив может содержать произвольные дополнительные данные для передачи соответствующей функции цикла в массиве func, включая NULL.

  • типы

    Длина (nin + nout) * ntypes массив из char кодирование numpy.dtype.num (только встроенные) что соответствующая функция в func array принимает. Например, для функции сравнения с тремя 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 – Количество выходов

  • идентичность – Либо PyUFunc_One, PyUFunc_Zero, PyUFunc_MinusOne, или PyUFunc_None. Это указывает, что должно быть возвращено, когда пустой массив передается в метод reduce ufunc. Специальное значение PyUFunc_IdentityValue может использоваться только с PyUFunc_FromFuncAndDataAndSignatureAndIdentity метод, чтобы разрешить использование произвольного объекта Python в качестве идентификатора.

  • имя – Имя для ufunc как NULL завершенная строка. Указание имени 'add' или 'multiply' включает специальное поведение для целочисленных редукций, когда dtype не задан. Если входной тип является целочисленным (или булевым) типом данных, меньшим по размеру, чем numpy.int_ тип данных будет внутренне приведен к numpy.int_ (или numpy.uint) тип данных.

  • doc – Позволяет передать строку документации для хранения вместе с ufunc. Строка документации не должна содержать имя функции или сигнатуру вызова, так как они будут динамически определены из объекта и доступны при обращении к __doc__ атрибут универсальной функции.

  • неиспользуемый – Не используется и присутствует для обратной совместимости C-API.

PyObject *PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *функция, void *const *данные, const char *типы, int ntypes, int nin, int nout, int идентичность, const char *имя, const char *doc, int неиспользуемый, const char *сигнатура)#

Эта функция очень похожа на PyUFunc_FromFuncAndData выше, но имеет дополнительный сигнатура аргумент, чтобы определить обобщенные универсальные функцииПодобно тому, как ufuncs построены вокруг поэлементных операций, gufuncs построены вокруг операций над подмассивами, сигнатура определяющие подмассивы для операций.

Параметры:
  • сигнатура – Сигнатура для новой gufunc. Установка значения NULL эквивалентна вызову PyUFunc_FromFuncAndData. Создаётся копия строки, поэтому переданный буфер может быть освобождён.

PyObject *PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction *функция, void **данные, char *типы, int ntypes, int nin, int nout, int идентичность, char *имя, char *doc, int неиспользуемый, char *сигнатура, 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 функция, int *arg_types, void *данные)#

Эта функция позволяет пользователю зарегистрировать одномерный цикл с уже созданной универсальной функцией (ufunc) для использования всякий раз, когда ufunc вызывается с любым из своих входных аргументов в качестве пользовательского типа данных. Это необходимо для того, чтобы ufunc работали со встроенными типами данных. Тип данных должен быть предварительно зарегистрирован в системе numpy. Цикл передается в качестве функция. Этот цикл может принимать произвольные данные, которые должны быть переданы как данные. Типы данных, которые требуются циклу, передаются как arg_types который должен быть указателем на память размером не менее ufunc->nargs.

int PyUFunc_RegisterLoopForDescr(PyUFuncObject *универсальная функция (ufunc), PyArray_Descr *userdtype, PyUFuncGenericFunction функция, PyArray_Descr **arg_dtypes, void *данные)#

Эта функция ведёт себя как PyUFunc_RegisterLoopForType выше, за исключением того, что позволяет пользователю регистрировать одномерный цикл, используя объекты PyArray_Descr вместо числовых значений типов dtype. Это позволяет регистрировать одномерный цикл для структурированных типов данных массивов и пользовательских типов данных вместо скалярных типов данных.

int PyUFunc_ReplaceLoopBySignature(PyUFuncObject *универсальная функция (ufunc), PyUFuncGenericFunction newfunc, int *сигнатура, PyUFuncGenericFunction *oldfunc)#

Заменить одномерный цикл, соответствующий заданному сигнатура в уже созданном универсальная функция (ufunc) с новой 1-d петлей newfunc. Возвращает старую 1-d петлевую функцию в oldfunc. Возвращает 0 при успехе и -1 при неудаче. Эта функция работает только со встроенными типами (используйте PyUFunc_RegisterLoopForType для пользовательских типов). Сигнатура — это массив чисел типов данных, указывающих входные данные, за которыми следуют выходные данные, предполагаемые одномерным циклом.

void PyUFunc_clearfperr()#

Очистить флаги ошибок IEEE.

Универсальные функции#

В основе каждого ufunc лежит набор функций, специфичных для типа, которые определяют базовую функциональность для каждого из поддерживаемых типов. Эти функции должны вычислять основную функцию \(N\geq1\) раз. Дополнительные данные могут передаваться для использования в вычислениях. Эта возможность позволяет использовать некоторые общие функции в качестве этих базовых циклических функций. Общая функция содержит весь код, необходимый для указания переменных в нужное место и настройки вызова функции. Общая функция предполагает, что фактическая вызываемая функция передается в качестве дополнительных данных и вызывает её с правильными значениями. Все эти функции подходят для непосредственного размещения в массиве функций, хранящемся в члене functions структуры PyUFuncObject.

void PyUFunc_f_f_As_d_d(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_d_d(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_f_f(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_g_g(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_F_F_As_D_D(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_F_F(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_D_D(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_G_G(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_e_e(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_e_e_As_f_f(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_e_e_As_d_d(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#

Тип-специфичные, основные 1-d функции для ufunc, где каждый расчёт получается вызовом функции, принимающей один входной аргумент и возвращающей один выходной. Эта функция передаётся в func. Буквы соответствуют dtypechar поддерживаемых типов данных ( e - half, f - float, d - double, g - long double, F - cfloat, D - cdouble, G - clongdouble). Аргумент функция должен поддерживать ту же сигнатуру. Варианты _As_X_X предполагают ndarray одного типа данных, но приводят значения для использования базовой функции, которая принимает другой тип данных. Таким образом, PyUFunc_f_f_As_d_d использует ndarrays типа данных NPY_FLOAT но вызывает C-функцию, которая принимает double и возвращает double.

void PyUFunc_ff_f_As_dd_d(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_ff_f(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void Когда предоставлено меньше индексов, чем количество осей, отсутствующие индексы считаются полными срезами(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_gg_g(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_FF_F_As_DD_D(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_DD_D(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_FF_F(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_GG_G(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_ee_e(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_ee_e_As_ff_f(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_ee_e_As_dd_d(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#

Тип-специфичные, основные одномерные функции для ufuncs, где каждый расчёт получается вызовом функции, принимающей два входных аргумента и возвращающей один выходной. Базовая функция для вызова передаётся как функция. Буквы соответствуют dtypechar конкретного типа данных, поддерживаемого универсальной функцией. Аргумент func должен поддерживать соответствующую сигнатуру. The _As_XX_X варианты предполагают ndarrays одного типа данных, но приводят значения на каждой итерации цикла к использованию базовой функции, которая принимает другой тип данных.

void PyUFunc_O_O(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#
void PyUFunc_OO_O(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#

Одновходовые, одно- и двухвходовые, одно-выходные основные 1-d функции для NPY_OBJECT тип данных. Эти функции обрабатывают проблемы с подсчётом ссылок и возвращаются раньше при ошибке. Фактическая вызываемая функция — функция и он должен принимать вызовы с сигнатурой (PyObject*) (PyObject*) для PyUFunc_O_O или (PyObject*)(PyObject *, PyObject *) для PyUFunc_OO_O.

void PyUFunc_O_O_method(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#

Эта универсальная 1-d основная функция предполагает, что функция является строкой, представляющей метод входного объекта. Для каждой итерации цикла объект Python извлекается из массива и его функция метод вызывается, возвращая результат в выходной массив.

void PyUFunc_OO_O_method(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#

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

void PyUFunc_On_Om(char **args, npy_intp const *измерения, npy_intp const *шаги, void *функция)#

Это основная одномерная функция, используемая динамическими ufuncs, созданными umath.frompyfunc(function, nin, nout). В этом случае функция является указателем на 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#
int PyUFunc_ImportUFuncAPI(void)#

Гарантирует, что C-API UFunc импортирован и готов к использованию. Возвращает 0 при успехе и -1 с установленной ошибкой, если NumPy не удалось импортировать. Хотя предпочтительно вызывать его один раз при инициализации модуля, эта функция очень легковесна при многократном вызове.

Новое в версии 2.0: Эта функция в основном проверяет PyUFunc_API == NULL так что его можно вручную перенести обратно, если требуется.

import_ufunc(void)#

Это константы и функции для доступа к C-API ufunc из модулей расширения точно так же, как можно получить доступ к array C-API. import_ufunc () функция всегда должна вызываться (в подпрограмме инициализации модуля расширения). Если ваш модуль расширения состоит из одного файла, то это всё, что требуется. Две другие константы полезны, если ваш модуль расширения использует несколько файлов. В этом случае определите PY_UFUNC_UNIQUE_SYMBOL на что-то уникальное для вашего кода, а затем в исходных файлах, которые не содержат функцию инициализации модуля, но все еще нуждаются в доступе к UFUNC API, определите PY_UFUNC_UNIQUE_SYMBOL к тому же имени, использованному ранее, и также определить NO_IMPORT_UFUNC.

C-API фактически является массивом указателей на функции. Этот массив создается (и на него указывает глобальная переменная) функцией import_ufunc. Глобальная переменная либо статически определена, либо доступна для других файлов в зависимости от состояния PY_UFUNC_UNIQUE_SYMBOL и NO_IMPORT_UFUNC.