Spec-Zone.ru › NumPy 2.0

API ufunc

Константы

UFUNC_{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

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

NPY_LOOP_END_THREADS

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

Типы

типPyUFuncGenericFunction

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

voidloopfunc(char**args, npy_intpconst*dimensions, npy_intpconst*steps, void*data)
Параметры:
  • args – Массив указателей на фактические данные для входных и выходных массивов. Входные аргументы задаются сначала, а затем выходные аргументы.
  • dimensions – Указатель на размерность, по которой эта функция циклируется.
  • steps – Указатель на количество байтов, которые нужно пропустить, чтобы получить следующий элемент в этой размерности для каждого из входных и выходных аргументов.
  • data –

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

    Изменено в версии 1.23.0: Принимает NULL data в дополнение к массиву 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*func, void*const*data, constchar*types, intntypes, intnin, intnout, intidentity, constchar*name, constchar*doc, intunused)

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

Примечание

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

Параметры:
  • func – Должен указывать на массив, содержащий ntypes элементов PyUFuncGenericFunction.
  • data – Должен быть NULL или указатель на массив размером ntypes. Этот массив может содержать произвольные дополнительные данные, которые будут переданы соответствующей функции цикла в массиве func, включая NULL.
  • 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 – Неиспользуемое и присутствующее для совместимости с предыдущими версиями C-API.
PyObject*PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction*func, void*const*data, constchar*types, intntypes, intnin, intnout, intidentity, constchar*name, constchar*doc, intunused, constchar*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)

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

intPyUFunc_ReplaceLoopBySignature(PyUFuncObject*ufunc, PyUFuncGenericFunctionnewfunc, int*signature, PyUFuncGenericFunction*oldfunc)

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

voidPyUFunc_clearfperr()

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

Общие функции

В основе каждой 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)
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-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.

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-вызов с входными аргументами вызывается, а nout выходных значений помещаются в их массивы объектов.

Импорт API

PY_UFUNC_UNIQUE_SYMBOL
NO_IMPORT_UFUNC
intPyUFunc_ImportUFuncAPI(void)

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

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

import_ufunc(void)

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

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

© 2005–2024 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/2.0/reference/c-api/ufunc.html

Spec-Zone.ru

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