Wenn derzeit p_N auf 5 definiert ist, werden beim Analysieren und Ausgeben eines Kernels alle Instanzen von p_N durch 5 ersetzt.
Es wäre nützlich, eine Parser-Option hinzuzufügen, damit die #defines in den generierten Quellcode aufgenommen werden und die Compiler-Variablen wie p_N im generierten Quellcode verbleiben.
Dadurch wird der generierte Code viel einfacher zu lesen.
Leider müssen alle Definitionen erweitert werden, um Codetransformationen anzuwenden
#define
-Werte können an zwei Stellen gefunden werden
> 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
}
Ich stimme zu, dass es nützlich ist, dies zu tun, um tatsächliche Schleifengrenzen zu extrahieren, und ich stelle mir vor, dass der Parser dafür ausgelegt ist. Es scheint jedoch unwahrscheinlich, dass es unmöglich ist, die Definitionen im Code beizubehalten. Das Nachverfolgen, wie die Werte berechnet werden, würde die Notwendigkeit vermeiden, ihre numerischen Werte auszudrucken.
Es ist schwieriger, als es scheint, den Code zu pflegen und zu transformieren
Defines können alles sein, sogar Teilcode
#define foo 3 +
for (int i = 0; i < foo 5; ++i) {}
Das Beibehalten der #define
-Zeilen kann ebenfalls zu Problemen führen, da der Compiler weiterhin den Präprozessor ausführt
... und wenn das Define nur eine numerische Konstante ist ... ?
... und warum brauchen wir dafür extra Logik ....?
Dies ist ein Beispiel für den Ausgabe-Kernel
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];
}
}
}
}
Die Kernel verlieren bei der Übersetzung an Lesbarkeit. Alle diese Nummern waren Defines.
Einen Schritt zurücktretend, war der Grund für die Feature-Anfrage zu
machen den generierten Code viel leichter lesbar
Der generierte Code ist für den Compiler gedacht, nicht für Benutzer (ähnlich wie vorverarbeitete Ausgaben des Compilers). Wenn es ein Parsing-Problem gibt, insbesondere da der Parser noch nicht ausgereift ist, könnte es hilfreich sein, sich das anzusehen. Diese Probleme sollten jedoch im Laufe der Zeit behoben werden.
Wenn der Zweck darin besteht, das Debuggen zu erleichtern, stimme ich zu, dass wir #line
hinzufügen sollten, um mit dem ursprünglichen Quellcode übereinzustimmen
Ich stimme zu, dass dies zum Debuggen ein echter Bonus wäre – nette Idee!
Ich hätte die Gründe für diese Anfrage klarer formulieren sollen: Ein wichtiger Anwendungsfall, den ich mir für die neuen Codegenerierungstools in OCCA 1.0 vorstelle, ist der Übersetzer von OKL in die native Threading-Sprache für Nicht-OCCA-Anwendungen. In diesem Fall ist es wichtig, die Lesbarkeit zu bewahren, da der generierte CUDA/OpenCL/HIP/OpenMP-Code vom OKL-Code getrennt wird.
Das klingt vernünftig
Es gibt ein paar Funktionen, die zuerst hinzugefügt werden müssen
#define
#defines
zu tun, ist zu schwierig, da wir nachverfolgen müssten, wo sie definiert sind und welche Bereiche sie nach Transformationen berührenparser::getExpression
constexpr
durch ihre Werteconst
Variablenconstexpr
Funktionen#define
Zeilen hinzuVielen Dank, dass Sie die Feature-Anfrage berücksichtigt haben!
Hilfreichster Kommentar
Das klingt vernünftig
Es gibt ein paar Funktionen, die zuerst hinzugefügt werden müssen
#define
#defines
zu tun, ist zu schwierig, da wir nachverfolgen müssten, wo sie definiert sind und welche Bereiche sie nach Transformationen berührenparser::getExpression
constexpr
durch ihre Werteconst
Variablenconstexpr
Funktionen#define
Zeilen hinzu