/***** GCL Generated File *********************/
/* Automatically generated file, do not edit! */
/**********************************************/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <dispatch/dispatch.h>
#include <OpenCL/opencl.h>
#include <OpenCL/gcl_priv.h>
#include "box_blur_cl_source.h"

static void initBlocks(void);

// Initialize static data structures
static block_kernel_pair pair_map[2] = {
      { NULL, NULL },
      { NULL, NULL }
};

static block_kernel_map bmap = { 0, 2, initBlocks, pair_map };

// Block function
void (^BoxRowsLmem_kernel)(const cl_ndrange *ndrange, cl_float4* uc4Source, cl_float4* uiDest, size_t uc4LocalData, cl_int width, cl_int height, cl_int iRadius, cl_int iRadiusAligned, cl_uint uiNumOutputPix) =
^(const cl_ndrange *ndrange, cl_float4* uc4Source, cl_float4* uiDest, size_t uc4LocalData, cl_int width, cl_int height, cl_int iRadius, cl_int iRadiusAligned, cl_uint uiNumOutputPix) {
  int err = 0;
  cl_kernel k = bmap.map[0].kernel;
  if (!k) {
    initBlocks();
    k = bmap.map[0].kernel;
  }
  if (!k)
    gcl_log_fatal("kernel BoxRowsLmem does not exist for device");
  kargs_struct kargs;
  gclCreateArgsAPPLE(k, &kargs);
  err |= gclSetKernelArgMemAPPLE(k, 0, uc4Source, &kargs);
  err |= gclSetKernelArgMemAPPLE(k, 1, uiDest, &kargs);
  err |= gclSetKernelArgAPPLE(k, 2, uc4LocalData, NULL, &kargs);
  err |= gclSetKernelArgAPPLE(k, 3, sizeof(width), &width, &kargs);
  err |= gclSetKernelArgAPPLE(k, 4, sizeof(height), &height, &kargs);
  err |= gclSetKernelArgAPPLE(k, 5, sizeof(iRadius), &iRadius, &kargs);
  err |= gclSetKernelArgAPPLE(k, 6, sizeof(iRadiusAligned), &iRadiusAligned, &kargs);
  err |= gclSetKernelArgAPPLE(k, 7, sizeof(uiNumOutputPix), &uiNumOutputPix, &kargs);
  gcl_log_cl_fatal(err, "setting argument for BoxRowsLmem failed");
  err = gclExecKernelAPPLE(k, ndrange, &kargs);
  gcl_log_cl_fatal(err, "Executing BoxRowsLmem failed");
  gclDeleteArgsAPPLE(k, &kargs);
};

void (^BoxColumns_kernel)(const cl_ndrange *ndrange, cl_float4* inputImage, cl_float4* outputImage, cl_int width, cl_int height, cl_int iRadius) =
^(const cl_ndrange *ndrange, cl_float4* inputImage, cl_float4* outputImage, cl_int width, cl_int height, cl_int iRadius) {
  int err = 0;
  cl_kernel k = bmap.map[1].kernel;
  if (!k) {
    initBlocks();
    k = bmap.map[1].kernel;
  }
  if (!k)
    gcl_log_fatal("kernel BoxColumns does not exist for device");
  kargs_struct kargs;
  gclCreateArgsAPPLE(k, &kargs);
  err |= gclSetKernelArgMemAPPLE(k, 0, inputImage, &kargs);
  err |= gclSetKernelArgMemAPPLE(k, 1, outputImage, &kargs);
  err |= gclSetKernelArgAPPLE(k, 2, sizeof(width), &width, &kargs);
  err |= gclSetKernelArgAPPLE(k, 3, sizeof(height), &height, &kargs);
  err |= gclSetKernelArgAPPLE(k, 4, sizeof(iRadius), &iRadius, &kargs);
  gcl_log_cl_fatal(err, "setting argument for BoxColumns failed");
  err = gclExecKernelAPPLE(k, ndrange, &kargs);
  gcl_log_cl_fatal(err, "Executing BoxColumns failed");
  gclDeleteArgsAPPLE(k, &kargs);
};

// Initialization functions
static void initBlocks(void) {
  const char* build_opts = "";
  static dispatch_once_t once;
  dispatch_once(&once,
    ^{ int err = gclBuildProgramBinaryAPPLE("OpenCL/box_blur_cl_source", "com.macphun.noiselessPro", &bmap, build_opts);
       if (!err) {
          assert(bmap.map[0].block_ptr == BoxRowsLmem_kernel && "mismatch block");
          bmap.map[0].kernel = clCreateKernel(bmap.program, "BoxRowsLmem", &err);
          assert(bmap.map[1].block_ptr == BoxColumns_kernel && "mismatch block");
          bmap.map[1].kernel = clCreateKernel(bmap.program, "BoxColumns", &err);
       }
     });
}

__attribute__((constructor))
static void RegisterMap(void) {
  gclRegisterBlockKernelMap(&bmap);
  bmap.map[0].block_ptr = BoxRowsLmem_kernel;
  bmap.map[1].block_ptr = BoxColumns_kernel;
}

