Spec-Zone.ru › NumPy 1.21

UFunc API

Константы

UFUNC_ERR_{HANDLER}
UFUNC_ERR_IGNORE
UFUNC_ERR_WARN
UFUNC_ERR_RAISE
UFUNC_ERR_CALL
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
PyUFunc_{VALUE}
PyUFunc_One
PyUFunc_Zero
PyUFunc_MinusOne
PyUFunc_ReorderableNone
PyUFunc_None
PyUFunc_IdentityValue

Макросы

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

Функции

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.
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.
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)
END_OF_DOCUMENT_MARKER
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 выходные данные помещаются в их массивы объектов.

Импортирование API

PY_UFUNC_UNIQUE_SYMBOL
NO_IMPORT_UFUNC
END_OF_DOCUMENT_MARKER
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

Spec-Zone.ru

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