static const char * source =
"static __constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;                                                                                          \n"
"                                                                                                                                                                                                    \n"
"#if USE_OLD_PSCRN                                                                                                                                                                                   \n"
"static void elliott(float8 * data, const int n) {                                                                                                                                                   \n"
"    for (int i = 0; i < n; i++)                                                                                                                                                                     \n"
"        data[i] = native_divide(data[i], 1.f + fabs(data[i]));                                                                                                                                      \n"
"}                                                                                                                                                                                                   \n"
"                                                                                                                                                                                                    \n"
"static void dotProd(const float8 * data, __constant float * weights, float8 * vals, const int n, const int len) {                                                                                   \n"
"    for (int i = 0; i < n; i++) {                                                                                                                                                                   \n"
"        float8 sum = 0.f;                                                                                                                                                                           \n"
"        for (int j = 0; j < len; j++)                                                                                                                                                               \n"
"            sum += data[j] * weights[mad24(i, len, j)];                                                                                                                                             \n"
"                                                                                                                                                                                                    \n"
"        vals[i] = sum + weights[mad24(n, len, i)];                                                                                                                                                  \n"
"    }                                                                                                                                                                                               \n"
"}                                                                                                                                                                                                   \n"
"                                                                                                                                                                                                    \n"
"static float8 prescreenOld(const __local float (* input)[INPUT_WIDTH], int8 * flag, __constant float * weights) {                                                                                   \n"
"    float8 temp[12];                                                                                                                                                                                \n"
"                                                                                                                                                                                                    \n"
"    for (int i = 0; i < 4; i++) {                                                                                                                                                                   \n"
"        float8 sum = 0.f;                                                                                                                                                                           \n"
"        int j = 0;                                                                                                                                                                                  \n"
"                                                                                                                                                                                                    \n"
"        for (int y = 0; y < 4; y++) {                                                                                                                                                               \n"
"            float8 pixel = vload8(0, input[y]);                                                                                                                                                     \n"
"                                                                                                                                                                                                    \n"
"            for (int x = 0; x < 12 - 1; x++) {                                                                                                                                                      \n"
"                sum += pixel * weights[mad24(i, 48, j++)];                                                                                                                                          \n"
"                                                                                                                                                                                                    \n"
"                pixel = (float8)(pixel.s1234, pixel.s567, input[y][8 + x]);                                                                                                                         \n"
"            }                                                                                                                                                                                       \n"
"                                                                                                                                                                                                    \n"
"            sum += pixel * weights[mad24(i, 48, j++)];                                                                                                                                              \n"
"        }                                                                                                                                                                                           \n"
"                                                                                                                                                                                                    \n"
"        temp[i] = sum + weights[4 * 48 + i];                                                                                                                                                        \n"
"    }                                                                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"    const float8 t = temp[0];                                                                                                                                                                       \n"
"    elliott(temp, 4);                                                                                                                                                                               \n"
"    temp[0] = t;                                                                                                                                                                                    \n"
"    dotProd(temp, weights + 4 * 49, temp + 4, 4, 4);                                                                                                                                                \n"
"    elliott(temp + 4, 4);                                                                                                                                                                           \n"
"    dotProd(temp, weights + 4 * 49 + 4 * 5, temp + 8, 4, 8);                                                                                                                                        \n"
"                                                                                                                                                                                                    \n"
"    *flag = (max(temp[10], temp[11]) <= max(temp[8], temp[9]));                                                                                                                                     \n"
"                                                                                                                                                                                                    \n"
"    return 0.59375f * (vload8(0, input[1] + 5) + vload8(0, input[2] + 5)) - 0.09375f * (vload8(0, input[0] + 5) + vload8(0, input[3] + 5));                                                         \n"
"}                                                                                                                                                                                                   \n"
"#endif                                                                                                                                                                                              \n"
"                                                                                                                                                                                                    \n"
"#if USE_NEW_PSCRN                                                                                                                                                                                   \n"
"static float8 prescreenNew(const __local float (* input)[INPUT_WIDTH], int8 * flag, __constant float * weights) {                                                                                   \n"
"    __constant short * ws = (__constant short *)weights;                                                                                                                                            \n"
"    __constant float * wf = (__constant float *)&ws[4 * 64];                                                                                                                                        \n"
"    float temp1[8], temp2[8];                                                                                                                                                                       \n"
"                                                                                                                                                                                                    \n"
"    for (int i = 0; i < 4; i++) {                                                                                                                                                                   \n"
"        float sum1 = 0.f, sum2 = 0.f;                                                                                                                                                               \n"
"        int j = 0;                                                                                                                                                                                  \n"
"                                                                                                                                                                                                    \n"
"        for (int y = 0; y < 4; y++) {                                                                                                                                                               \n"
"            for (int x = 0; x < 16; x++) {                                                                                                                                                          \n"
"                sum1 += input[y][x] * ws[(i << 3) + ((j >> 3) << 5) + (j & 7)];                                                                                                                     \n"
"                sum2 += input[y][4 + x] * ws[(i << 3) + ((j >> 3) << 5) + (j & 7)];                                                                                                                 \n"
"                j++;                                                                                                                                                                                \n"
"            }                                                                                                                                                                                       \n"
"        }                                                                                                                                                                                           \n"
"                                                                                                                                                                                                    \n"
"        const float t1 = sum1 * wf[i] + wf[4 + i];                                                                                                                                                  \n"
"        const float t2 = sum2 * wf[i] + wf[4 + i];                                                                                                                                                  \n"
"        temp1[i] = native_divide(t1, 1.f + fabs(t1));                                                                                                                                               \n"
"        temp2[i] = native_divide(t2, 1.f + fabs(t2));                                                                                                                                               \n"
"    }                                                                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"    for (int i = 0; i < 4; i++) {                                                                                                                                                                   \n"
"        float sum1 = 0.f, sum2 = 0.f;                                                                                                                                                               \n"
"        for (int j = 0; j < 4; j++) {                                                                                                                                                               \n"
"            sum1 += temp1[j] * wf[8 + i + (j << 2)];                                                                                                                                                \n"
"            sum2 += temp2[j] * wf[8 + i + (j << 2)];                                                                                                                                                \n"
"        }                                                                                                                                                                                           \n"
"                                                                                                                                                                                                    \n"
"        temp1[4 + i] = sum1 + wf[8 + 16 + i];                                                                                                                                                       \n"
"        temp2[4 + i] = sum2 + wf[8 + 16 + i];                                                                                                                                                       \n"
"    }                                                                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"    for (int i = 0; i < 4; i++) {                                                                                                                                                                   \n"
"        ((int *)flag)[i] = select(0, -1, temp1[4 + i] > 0.f);                                                                                                                                       \n"
"        ((int *)flag)[4 + i] = select(0, -1, temp2[4 + i] > 0.f);                                                                                                                                   \n"
"    }                                                                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"    return 0.59375f * (vload8(0, input[1] + 6) + vload8(0, input[2] + 6)) - 0.09375f * (vload8(0, input[0] + 6) + vload8(0, input[3] + 6));                                                         \n"
"}                                                                                                                                                                                                   \n"
"#endif                                                                                                                                                                                              \n"
"                                                                                                                                                                                                    \n"
"static float8 predict(const __local float (* input)[INPUT_WIDTH], __read_only image1d_buffer_t weights) {                                                                                           \n"
"    float8 sum = 0.f, sumsq = 0.f;                                                                                                                                                                  \n"
"                                                                                                                                                                                                    \n"
"    #pragma unroll                                                                                                                                                                                  \n"
"    for (int y = 0; y < YDIA; y++) {                                                                                                                                                                \n"
"        float8 pixel = vload8(0, input[y]);                                                                                                                                                         \n"
"                                                                                                                                                                                                    \n"
"        #pragma unroll                                                                                                                                                                              \n"
"        for (int x = 0; x < XDIA - 1; x++) {                                                                                                                                                        \n"
"            sum += pixel;                                                                                                                                                                           \n"
"            sumsq += pixel * pixel;                                                                                                                                                                 \n"
"                                                                                                                                                                                                    \n"
"            pixel = (float8)(pixel.s1234, pixel.s567, input[y][8 + x]);                                                                                                                             \n"
"        }                                                                                                                                                                                           \n"
"                                                                                                                                                                                                    \n"
"        sum += pixel;                                                                                                                                                                               \n"
"        sumsq += pixel * pixel;                                                                                                                                                                     \n"
"    }                                                                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"    const float8 mstd0 = sum * SCALE_ASIZE;                                                                                                                                                         \n"
"    float8 mstd1 = sumsq * SCALE_ASIZE - mstd0 * mstd0;                                                                                                                                             \n"
"    const int8 cond = (mstd1 <= FLT_EPSILON);                                                                                                                                                       \n"
"    mstd1 = select(native_sqrt(mstd1), 0.f, cond);                                                                                                                                                  \n"
"    const float8 mstd2 = select(native_recip(mstd1), 0.f, cond);                                                                                                                                    \n"
"                                                                                                                                                                                                    \n"
"    float8 mstd3 = 0.f;                                                                                                                                                                             \n"
"                                                                                                                                                                                                    \n"
"    #pragma unroll 1                                                                                                                                                                                \n"
"    for (int q = 0; q < QUAL; q++) {                                                                                                                                                                \n"
"        const int weightsOffset = mul24(DIMS1, q);                                                                                                                                                  \n"
"        float8 vsum = 0.f, wsum = 0.f;                                                                                                                                                              \n"
"                                                                                                                                                                                                    \n"
"        #pragma unroll 1                                                                                                                                                                            \n"
"        for (int i = 0; i < NNS; i++) {                                                                                                                                                             \n"
"            float8 sum1 = 0.f, sum2 = 0.f;                                                                                                                                                          \n"
"            int j = 0;                                                                                                                                                                              \n"
"                                                                                                                                                                                                    \n"
"            #pragma unroll 1                                                                                                                                                                        \n"
"            for (int y = 0; y < YDIA; y++) {                                                                                                                                                        \n"
"                float8 pixel = vload8(0, input[y]);                                                                                                                                                 \n"
"                                                                                                                                                                                                    \n"
"                #pragma unroll                                                                                                                                                                      \n"
"                for (int x = 0; x < XDIA - 1; x++) {                                                                                                                                                \n"
"                    sum1 += pixel * read_imagef(weights, weightsOffset + mad24(i, ASIZE, j)).x;                                                                                                     \n"
"                    sum2 += pixel * read_imagef(weights, weightsOffset + mad24(NNS + i, ASIZE, j++)).x;                                                                                             \n"
"                                                                                                                                                                                                    \n"
"                    pixel = (float8)(pixel.s1234, pixel.s567, input[y][8 + x]);                                                                                                                     \n"
"                }                                                                                                                                                                                   \n"
"                                                                                                                                                                                                    \n"
"                sum1 += pixel * read_imagef(weights, weightsOffset + mad24(i, ASIZE, j)).x;                                                                                                         \n"
"                sum2 += pixel * read_imagef(weights, weightsOffset + mad24(NNS + i, ASIZE, j++)).x;                                                                                                 \n"
"            }                                                                                                                                                                                       \n"
"                                                                                                                                                                                                    \n"
"            sum1 = native_exp(clamp(sum1 * mstd2 + read_imagef(weights, weightsOffset + NNS2 * ASIZE + i).x, -80.f, 80.f));                                                                         \n"
"            sum2 = sum2 * mstd2 + read_imagef(weights, weightsOffset + NNS2 * ASIZE + NNS + i).x;                                                                                                   \n"
"                                                                                                                                                                                                    \n"
"            vsum += sum1 * native_divide(sum2, 1.f + fabs(sum2));                                                                                                                                   \n"
"            wsum += sum1;                                                                                                                                                                           \n"
"        }                                                                                                                                                                                           \n"
"                                                                                                                                                                                                    \n"
"        mstd3 += select(mstd0, native_divide(5.f * vsum, wsum) * mstd1 + mstd0, wsum > 1e-10f);                                                                                                     \n"
"    }                                                                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"    return mstd3 * SCALE_QUAL;                                                                                                                                                                      \n"
"}                                                                                                                                                                                                   \n"
"                                                                                                                                                                                                    \n"
"__kernel __attribute__((reqd_work_group_size(4, 16, 1)))                                                                                                                                            \n"
"void filter_uint(__read_only image2d_t src, __write_only image2d_t dst, __constant float * weights0, __read_only image1d_buffer_t weights1,                                                         \n"
"                 const int srcWidth, const int srcHeight, const int dstWidth, const int dstHeight, const int field_n, const int off, const int swap) {                                              \n"
"    const int globalX = get_global_id(0);                                                                                                                                                           \n"
"    const int globalY = get_global_id(1);                                                                                                                                                           \n"
"    const int localX = get_local_id(0);                                                                                                                                                             \n"
"    const int localY = get_local_id(1);                                                                                                                                                             \n"
"                                                                                                                                                                                                    \n"
"    const int _srcX = -XDIAD2M1 + 32 * (int)get_group_id(0) + localX;                                                                                                                               \n"
"    const int _srcY = field_n - Y_OFFSET + Y_STEP * globalY;                                                                                                                                        \n"
"    const int _dstX = 8 * globalX;                                                                                                                                                                  \n"
"    const int dstYCopy = off + 2 * globalY;                                                                                                                                                         \n"
"    const int dstY = field_n + 2 * globalY;                                                                                                                                                         \n"
"                                                                                                                                                                                                    \n"
"    __local float input[INPUT_HEIGHT][INPUT_WIDTH];                                                                                                                                                 \n"
"                                                                                                                                                                                                    \n"
"    for (int y = localY, j = 0; y < INPUT_HEIGHT; y += 16, j++) {                                                                                                                                   \n"
"        int srcY = _srcY + Y_STRIDE * j;                                                                                                                                                            \n"
"        if (srcY < 0)                                                                                                                                                                               \n"
"            srcY = abs(srcY) + Y_STEP * off;                                                                                                                                                        \n"
"        else if (srcY >= srcHeight)                                                                                                                                                                 \n"
"            srcY = 2 * srcHeight - srcY - 2 * Y_STEP;                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"        for (int x = localX, i = 0; x < INPUT_WIDTH; x += 4, i++) {                                                                                                                                 \n"
"            int srcX = abs(_srcX + 4 * i);                                                                                                                                                          \n"
"            if (srcX >= srcWidth)                                                                                                                                                                   \n"
"                srcX = 2 * srcWidth - srcX - 2;                                                                                                                                                     \n"
"                                                                                                                                                                                                    \n"
"            input[y][x] = read_imageui(src, sampler, select((int2)(srcX, srcY), (int2)(srcY, srcX), (int2)swap)).x;                                                                                 \n"
"        }                                                                                                                                                                                           \n"
"    }                                                                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"    barrier(CLK_LOCAL_MEM_FENCE);                                                                                                                                                                   \n"
"                                                                                                                                                                                                    \n"
"    int8 flag;                                                                                                                                                                                      \n"
"    float8 output = PRESCREEN((const __local float (*)[INPUT_WIDTH])&input[YDIAD2M1 - 1 + localY][XDIAD2M1 - PSCRN_OFFSET + 8 * localX], &flag, weights0);                                          \n"
"    if (!all(flag))                                                                                                                                                                                 \n"
"        output = predict((const __local float (*)[INPUT_WIDTH])&input[localY][X_OFFSET + 8 * localX], weights1);                                                                                    \n"
"                                                                                                                                                                                                    \n"
"    if (dstY < dstHeight) {                                                                                                                                                                         \n"
"        for (int i = 0; i < 8; i++) {                                                                                                                                                               \n"
"            const int dstX = _dstX + i;                                                                                                                                                             \n"
"            if (dstX < dstWidth) {                                                                                                                                                                  \n"
"                write_imageui(dst, select((int2)(dstX, dstYCopy), (int2)(dstYCopy, dstX), (int2)swap), input[YDIAD2M1 + localY + off][XDIAD2M1 + 8 * localX + i]);                                  \n"
"                write_imageui(dst, select((int2)(dstX, dstY), (int2)(dstY, dstX), (int2)swap), clamp((int)(((const float *)&output)[i] + 0.5f), 0, PEAK));                                          \n"
"            }                                                                                                                                                                                       \n"
"        }                                                                                                                                                                                           \n"
"    }                                                                                                                                                                                               \n"
"}                                                                                                                                                                                                   \n"
"                                                                                                                                                                                                    \n"
"__kernel __attribute__((reqd_work_group_size(4, 16, 1)))                                                                                                                                            \n"
"void filter_float(__read_only image2d_t src, __write_only image2d_t dst, __constant float * weights0, __read_only image1d_buffer_t weights1,                                                        \n"
"                  const int srcWidth, const int srcHeight, const int dstWidth, const int dstHeight, const int field_n, const int off, const int swap) {                                             \n"
"    const int globalX = get_global_id(0);                                                                                                                                                           \n"
"    const int globalY = get_global_id(1);                                                                                                                                                           \n"
"    const int localX = get_local_id(0);                                                                                                                                                             \n"
"    const int localY = get_local_id(1);                                                                                                                                                             \n"
"                                                                                                                                                                                                    \n"
"    const int _srcX = -XDIAD2M1 + 32 * (int)get_group_id(0) + localX;                                                                                                                               \n"
"    const int _srcY = field_n - Y_OFFSET + Y_STEP * globalY;                                                                                                                                        \n"
"    const int _dstX = 8 * globalX;                                                                                                                                                                  \n"
"    const int dstYCopy = off + 2 * globalY;                                                                                                                                                         \n"
"    const int dstY = field_n + 2 * globalY;                                                                                                                                                         \n"
"                                                                                                                                                                                                    \n"
"    __local float input[INPUT_HEIGHT][INPUT_WIDTH];                                                                                                                                                 \n"
"                                                                                                                                                                                                    \n"
"    for (int y = localY, j = 0; y < INPUT_HEIGHT; y += 16, j++) {                                                                                                                                   \n"
"        int srcY = _srcY + Y_STRIDE * j;                                                                                                                                                            \n"
"        if (srcY < 0)                                                                                                                                                                               \n"
"            srcY = abs(srcY) + Y_STEP * off;                                                                                                                                                        \n"
"        else if (srcY >= srcHeight)                                                                                                                                                                 \n"
"            srcY = 2 * srcHeight - srcY - 2 * Y_STEP;                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"        for (int x = localX, i = 0; x < INPUT_WIDTH; x += 4, i++) {                                                                                                                                 \n"
"            int srcX = abs(_srcX + 4 * i);                                                                                                                                                          \n"
"            if (srcX >= srcWidth)                                                                                                                                                                   \n"
"                srcX = 2 * srcWidth - srcX - 2;                                                                                                                                                     \n"
"                                                                                                                                                                                                    \n"
"            input[y][x] = read_imagef(src, sampler, select((int2)(srcX, srcY), (int2)(srcY, srcX), (int2)swap)).x;                                                                                  \n"
"        }                                                                                                                                                                                           \n"
"    }                                                                                                                                                                                               \n"
"                                                                                                                                                                                                    \n"
"    barrier(CLK_LOCAL_MEM_FENCE);                                                                                                                                                                   \n"
"                                                                                                                                                                                                    \n"
"    int8 flag;                                                                                                                                                                                      \n"
"    float8 output = PRESCREEN((const __local float (*)[INPUT_WIDTH])&input[YDIAD2M1 - 1 + localY][XDIAD2M1 - PSCRN_OFFSET + 8 * localX], &flag, weights0);                                          \n"
"    if (!all(flag))                                                                                                                                                                                 \n"
"        output = predict((const __local float (*)[INPUT_WIDTH])&input[localY][X_OFFSET + 8 * localX], weights1);                                                                                    \n"
"                                                                                                                                                                                                    \n"
"    if (dstY < dstHeight) {                                                                                                                                                                         \n"
"        for (int i = 0; i < 8; i++) {                                                                                                                                                               \n"
"            const int dstX = _dstX + i;                                                                                                                                                             \n"
"            if (dstX < dstWidth) {                                                                                                                                                                  \n"
"                write_imagef(dst, select((int2)(dstX, dstYCopy), (int2)(dstYCopy, dstX), (int2)swap), input[YDIAD2M1 + localY + off][XDIAD2M1 + 8 * localX + i]);                                   \n"
"                write_imagef(dst, select((int2)(dstX, dstY), (int2)(dstY, dstX), (int2)swap), ((const float *)&output)[i]);                                                                         \n"
"            }                                                                                                                                                                                       \n"
"        }                                                                                                                                                                                           \n"
"    }                                                                                                                                                                                               \n"
"}                                                                                                                                                                                                   \n";
