#define SUM(a, b) (a + b) #define MUL(a, b) (a * b) #define MIN(a, b) min(a, b) #define MAX(a, b) max(a, b) __kernel void greduce( __global float* buffer, __global float* result, __local float* scratch, __const int length) { int global_index = get_global_id(0); int local_index = get_local_id(0); // Load data into local memory if (global_index < length) { scratch[local_index] = buffer[global_index]; } else { // Infinity is the identity element for the sum operation scratch[local_index] = NEUTRAL; } barrier(CLK_LOCAL_MEM_FENCE); for(int offset = 1; offset < get_local_size(0); offset <<= 1) { int mask = (offset << 1) - 1; if ((local_index & mask) == 0) { float other = scratch[local_index + offset]; float mine = scratch[local_index]; scratch[local_index] = OP(mine, other); } barrier(CLK_LOCAL_MEM_FENCE); } if (local_index == 0) { result[get_group_id(0)] = scratch[0]; } }