В настоящее время, если для p_N определено значение 5, то при анализе ядра и выводе все экземпляры p_N заменяются на 5.
Было бы полезно добавить опцию парсера, чтобы #define включались в сгенерированный исходный код, а переменные компилятора, такие как p_N, оставались в сгенерированном исходном коде.
Это значительно упростит чтение сгенерированного кода.
К сожалению, все определения должны быть расширены для применения преобразований кода.
Значения #define
можно найти в двух местах.
> head ~/.occa/cache/c8141715ac4e4272/raw_source.cpp
#define block 256
/* The MIT License (MIT)
*
> cat ~/.occa/cache/c8141715ac4e4272/build.json | jq .kernel.props.defines
{
"block": 256
}
Я согласен, что это полезно сделать для извлечения фактических границ цикла, и я полагаю, что синтаксический анализатор предназначен для этого. Однако кажется маловероятным, что невозможно сохранить определения в коде. Отслеживание того, как вычисляются значения, избавило бы от необходимости печатать их числовые значения.
Поддерживать код и преобразовывать его сложнее, чем кажется.
Определяет может быть что угодно, даже частичный код
#define foo 3 +
for (int i = 0; i < foo 5; ++i) {}
Сохранение строк #define
также может вызвать проблемы, поскольку компилятор по-прежнему будет запускать препроцессор.
... а если Define - это просто числовая константа... ?
...и зачем нам для этого лишняя логика....?
Это пример выходного ядра
extern "C" __global__ void _occa_ellipticPreconCoarsenHex3D_0(const int Nelements,
const double * __restrict__ R,
const double * __restrict__ qf,
double * __restrict__ qc) {
{
int e = 0 + blockIdx.x;
__shared__ double s_qfff[8][8][8];
__shared__ double s_qcff[2][8][8];
__shared__ double s_qccf[2][2][8];
__shared__ double s_qccc[2][2][2];
__shared__ double s_R[2][8];
{
int k = 0 + threadIdx.z;
{
int j = 0 + threadIdx.y;
{
int i = 0 + threadIdx.x;
const int id = i + j * 8 + k * 8 * 8 + e * 512;
s_qfff[k][j][i] = qf[id];
if ((k == 0) && (j < 2)) {
s_R[j][i] = R[j * 8 + i];
}
}
}
}
Ядра теряют читабельность при переводе. Все эти номера были определены.
Сделав шаг назад, причина запроса функции заключалась в том, чтобы
сделать сгенерированный код намного легче для чтения
Сгенерированный код предназначен для компилятора, а не для пользователей (аналогично предварительно обработанным выводам компилятора). Если есть проблема с синтаксическим анализом, особенно потому, что синтаксический анализатор еще не разработан, это может помочь взглянуть на него. Однако со временем эти проблемы должны быть решены.
Если цель состоит в том, чтобы упростить отладку, я согласен, что мы должны добавить #line
, чтобы он соответствовал исходному исходному коду.
Согласен, что для отладки это было бы настоящим бонусом — хорошая идея!
Я должен был яснее пояснить причину этого запроса: один важный вариант использования, который я предполагаю для новых инструментов генерации кода в OCCA 1.0, — это транслятор с OKL на родной язык потоков для приложений, отличных от OCCA. В этом случае будет важно сохранить удобочитаемость, так как сгенерированный код CUDA/OpenCL/HIP/OpenMP будет отделен от кода OKL.
Это звучит разумно
Есть несколько функций, которые необходимо добавить в первую очередь.
#define
#defines
слишком сложно, так как нам нужно будет отслеживать, где они определены и какие области видимости они затрагивают после преобразований.parser::getExpression
замените constexpr
их значениями.const
constexpr
функций#define
наверх, как обычно.Спасибо за рассмотрение запроса функции!
Самый полезный комментарий
Это звучит разумно
Есть несколько функций, которые необходимо добавить в первую очередь.
#define
#defines
слишком сложно, так как нам нужно будет отслеживать, где они определены и какие области видимости они затрагивают после преобразований.parser::getExpression
заменитеconstexpr
их значениями.const
constexpr
функций#define
наверх, как обычно.