Упростить выражение, сгенерированное с помощью sympy codegen

Я использую sympy.utilities.codegen для создания C-кода, который я использую для числовых вычислений. Например, сгенерированная C-функция выглядит примерно так:

double f(double x, double y, double z){
    return M_PI*sin(M_PI*x)*sin(M_PI*y) + sin(M_PI*y)*sin(M_PI*z);
}

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

double f(double x, double y, double z){
    double sinx = sin(M_PI*x);
    double siny = sin(M_PI*y);
    double sinz = sin(M_PI*z);
    double result;

    result  = M_PI*sinx*siny;
    result += siny*sinz;
    return result;
}

Таким образом, очевидно, что для этих небольших функций эти замены не окупаются, но в целом это единственный способ заставить меня работать для более крупных функций. Итак, мои вопросы: существуют ли какие-либо простые встроенные опции для получения такого поведения? Наиболее важной частью для меня было бы разбить расчет на небольшие шаги. Я предполагаю, что замена может быть выполнена с помощью некоторых процедур замены строк.


person jrsm    schedule 14.08.2014    source источник


Ответы (1)


Скорее всего, вы захотите выполнить удаление общих подвыражений . В вашем примере siny это единственное выражение, которое фактически используется повторно:

>>> expr = pi*sin(pi*x)*sin(pi*y) + sin(pi*y)*sin(pi*z)
>>> print(cse(expr))
([(x0, sin(pi*y))], [pi*x0*sin(pi*x) + x0*sin(pi*z)])

Обычно компиляторы уже должны выполнять эти преобразования - по крайней мере, если вы попросите его игнорировать неассоциативность, например. умножение с плавающей запятой (путем передачи, например, -ffast-math). Однако у меня нет опыта работы с nvcc.

Если вы столкнетесь с ограничениями при работе с codegen для генерации кода CUDA, не стесняйтесь улучшить его и отправить запросы на слияние на Проект SymPy. Не забудьте проверить последнюю основную ветку, так как Джим Крист в настоящее время занимается рефакторингом принтеров кода: https://github.com/sympy/sympy/pull/7823

person Bjoern Dahlgren    schedule 15.08.2014
comment
Спасибо, так что cse помогает мне уменьшить подвыражения, но как я могу использовать это с codegen? т. е. если я использую cse до codegen, у меня много новых переменных, как я могу определить эти переменные внутри функции codegen? - person jrsm; 15.08.2014