Neutrales Element für min () und max () in der OpenCL-Reduktion
Ich reduziere (finde das Minimum und das Maximum) von afloat[]
Array auf einer GPU über OpenCL.
Ich lade die ein paar Elemente ausglobal
Erinnerung inlocal
Speicher für jede Arbeitsgruppe. Wenn die globale Größe nicht ein Vielfaches der Arbeitsgruppengröße ist, fülle ich die globale Größe so auf, dass sie ein Vielfaches der globalen Größe wird. Workitems nach dem Ende des Arrays setzen das neutrale Element der Reduktion inlocal
Erinnerung.
Aber wofür sollte dieses neutrale Element sein?max()
- die maximale Funktion?Die OpenCL-Dokumentation gibtMAXFLOAT
, HUGE_VALF
undINFINITY
als sehr groß positiv (oder ohne Vorzeichen)float
Werte. Ist es sinnvoll, das neutrale Element zu haben?-INFINITY
zum Beispiel?
Im Moment benutze ichHUGE_VALF
als neutrales Element fürmin()
, aber die docs sagen das auchHUGE_VALF
wird als Fehlerwert verwendet, also ist das vielleicht eine schlechte Idee.
Reduktionskernel (Code):
#define NEUTRAL_ELEMENT HUGE_VALF
#define REDUCTION_OP min
__kernel void reduce(__global float* weights,
__local float* weights_cached
)
{
unsigned int id = get_global_id(0);
// Load data
if (id < {{ point_count }}) {
weights_cached[get_local_id(0)] = weights[id];
} else {
weights_cached[get_local_id(0)] = NEUTRAL_ELEMENT;
}
barrier(CLK_LOCAL_MEM_FENCE);
// Reduce
for(unsigned int stride = get_local_size(0) / 2; stride >= 1; stride /= 2) {
if (get_local_id(0) < stride) {
weights_cached[get_local_id(0)] = REDUCTION_OP(weights_cached[get_local_id(0)], weights_cached[get_local_id(0) + stride]);
barrier(CLK_LOCAL_MEM_FENCE);
}
// Save
weights[get_group_id(0)] = weights_cached[0];
}
Bearbeiten: Ich habe tatsächlich verwendetfmin()
undfmax()
zusammen mitNAN
als neutrales Element - dies funktioniert garantiert grundsätzlich nach demOpenCL-Dokumentation da der numerische Wert immer zurückgegeben wird (NAN
wird nur zurückgegeben, wenn zweiNAN
Werte sind angegeben).