static const char* noise_cell_cl_source =
"#define MAX_RANK 3                                                            \n"
"                                                                              \n"
"/* Random feature counts following the Poisson distribution with              \n"
"   lambda equal to 7. */                                                      \n"
"                                                                              \n"
"const __constant char poisson[256] = {                                        \n"
"  7, 9, 12, 12, 8, 7, 5, 5, 6, 7, 8, 6, 10, 7, 6, 2, 8, 3, 9, 5, 13, 10, 9,   \n"
"  8, 8, 9, 3, 8, 9, 6, 8, 7, 4, 9, 6, 3, 10, 7, 7, 7, 6, 7, 4, 14, 7, 6, 11,  \n"
"  7, 7, 7, 12, 7, 10, 6, 8, 11, 3, 5, 7, 7, 8, 7, 9, 8, 5, 8, 11, 3, 4, 5, 8, \n"
"  8, 7, 8, 9, 2, 7, 8, 12, 4, 8, 2, 11, 8, 14, 7, 8, 2, 3, 10, 4, 6, 9, 5, 8, \n"
"  7, 10, 10, 10, 14, 5, 7, 6, 4, 5, 6, 11, 8, 7, 3, 11, 5, 5, 2, 9, 7, 7, 7,  \n"
"  9, 2, 7, 6, 9, 7, 6, 5, 12, 5, 3, 11, 9, 12, 8, 6, 8, 6, 8, 5, 5, 7, 5, 2,  \n"
"  9, 5, 5, 8, 11, 8, 8, 10, 6, 4, 7, 14, 7, 3, 10, 7, 7, 4, 9, 10, 10, 9, 8,  \n"
"  8, 7, 6, 5, 10, 10, 5, 10, 7, 7, 10, 7, 4, 9, 9, 6, 8, 5, 10, 7, 3, 9, 9,   \n"
"  7, 8, 9, 7, 5, 7, 6, 5, 5, 12, 4, 7, 5, 5, 4, 5, 7, 10, 8, 7, 9, 4, 6, 11,  \n"
"  6, 3, 7, 8, 9, 5, 8, 6, 7, 8, 7, 7, 3, 7, 7, 9, 4, 5, 5, 6, 9, 7, 6, 12, 4, \n"
"  9, 10, 8, 8, 6, 4, 9, 9, 8, 11, 6, 8, 13, 8, 9, 12, 6, 9, 8                 \n"
"};                                                                            \n"
"                                                                              \n"
"uint                                                                          \n"
"philox (uint s,                                                               \n"
"        uint t,                                                               \n"
"        uint k)                                                               \n"
"{                                                                             \n"
"  ulong p;                                                                    \n"
"  int   i;                                                                    \n"
"                                                                              \n"
"  for (i = 0 ; i < 3 ; i += 1)                                                \n"
"    {                                                                         \n"
"      p = s * 0xcd9e8d57ul;                                                   \n"
"                                                                              \n"
"      s = ((uint)(p >> 32)) ^ t ^ k;                                          \n"
"      t = (uint)p;                                                            \n"
"                                                                              \n"
"      k += 0x9e3779b9u;                                                       \n"
"    }                                                                         \n"
"                                                                              \n"
"  return s;                                                                   \n"
"}                                                                             \n"
"                                                                              \n"
"float                                                                         \n"
"lcg (uint *hash)                                                              \n"
"{                                                                             \n"
"  return (*hash = *hash * 1664525u + 1013904223u) / 4294967296.0f;            \n"
"}                                                                             \n"
"                                                                              \n"
"void                                                                          \n"
"search_box (float              *closest,                                      \n"
"            uint               *feature,                                      \n"
"            int                 s,                                            \n"
"            int                 t,                                            \n"
"            float               x,                                            \n"
"            float               y,                                            \n"
"            float               shape,                                        \n"
"            uint                rank,                                         \n"
"            uint                seed)                                         \n"
"{                                                                             \n"
"  uint hash;                                                                  \n"
"  int  i, n;                                                                  \n"
"                                                                              \n"
"  hash = philox ((uint)s, (uint)t, seed);                                     \n"
"  n = poisson[hash >> 24];                                                    \n"
"                                                                              \n"
"  for (i = 0 ; i < n ; i += 1)                                                \n"
"    {                                                                         \n"
"      float delta_x, delta_y, d;                                              \n"
"      int   j, k;                                                             \n"
"                                                                              \n"
"      /* Calculate the distance to each feature point. */                     \n"
"                                                                              \n"
"      delta_x = s + lcg (&hash) - x;                                          \n"
"      delta_y = t + lcg (&hash) - y;                                          \n"
"                                                                              \n"
"      if (shape == 2)                                                         \n"
"        d = delta_x * delta_x + delta_y * delta_y;                            \n"
"      else if (shape == 1)                                                    \n"
"        d = fabs (delta_x) + fabs (delta_y);                                  \n"
"      else                                                                    \n"
"        d = pow (fabs (delta_x), shape) +                                     \n"
"          pow (fabs (delta_y), shape);                                        \n"
"                                                                              \n"
"      /* Insert it into the list of n closest distances if needed. */         \n"
"                                                                              \n"
"      for (j = 0 ; j < rank && d > closest[j] ; j += 1);                      \n"
"                                                                              \n"
"      if (j < rank)                                                           \n"
"        {                                                                     \n"
"          for (k = rank - 1 ; k > j ; k -= 1)                                 \n"
"            {                                                                 \n"
"              closest[k] = closest[k - 1];                                    \n"
"            }                                                                 \n"
"                                                                              \n"
"          closest[j] = d;                                                     \n"
"                                                                              \n"
"          if (j == rank - 1)                                                  \n"
"            *feature = hash;                                                  \n"
"        }                                                                     \n"
"    }                                                                         \n"
"}                                                                             \n"
"                                                                              \n"
"__kernel void kernel_noise (__global float *out,                              \n"
"                            const int       x_0,                              \n"
"                            const int       y_0,                              \n"
"                            const uint      iterations,                       \n"
"                            float           scale,                            \n"
"                            float           shape,                            \n"
"                            uint            rank,                             \n"
"                            uint            seed,                             \n"
"                            int             palettize)                        \n"
"{                                                                             \n"
"  const int gidx = get_global_id(0);                                          \n"
"  const int gidy = get_global_id(1);                                          \n"
"                                                                              \n"
"  float c, d, n, closest[MAX_RANK], *d_0 = &closest[MAX_RANK - 1];            \n"
"  uint  feature;                                                              \n"
"  int   i, j;                                                                 \n"
"                                                                              \n"
"  for (j = 0, n = 0, c = 1, d = scale;                                        \n"
"       j < iterations;                                                        \n"
"       c *= 2, d *= 2, j += 1)                                                \n"
"    {                                                                         \n"
"      float d_l, d_r, d_t, d_b;                                               \n"
"      float x = (float)(gidx + x_0) * d;                                      \n"
"      float y = (float)(gidy + y_0) * d;                                      \n"
"      int   s = (int)floor(x);                                                \n"
"      int   t = (int)floor(y);                                                \n"
"                                                                              \n"
"      for (i = 0 ; i < rank ; closest[i] = 1.0f / 0.0f, i += 1);              \n"
"                                                                              \n"
"      /* Search the box the point is in. */                                   \n"
"                                                                              \n"
"      search_box (closest, &feature, s, t, x, y, shape, rank, seed);          \n"
"                                                                              \n"
"      d_0 = &closest[rank - 1];                                               \n"
"      d_l = x - s; d_l *= d_l;                                                \n"
"      d_r = 1.0f - x + s; d_r *= d_r;                                         \n"
"      d_b = y - t; d_b *= d_b;                                                \n"
"      d_t = 1.0f - y + t; d_t *= d_t;                                         \n"
"                                                                              \n"
"      /* Search adjacent boxes if it is possible for them to contain a        \n"
"       * nearby feature point. */                                             \n"
"                                                                              \n"
"      if (d_l < *d_0)                                                         \n"
"        {                                                                     \n"
"          if (d_l + d_b < *d_0)                                               \n"
"            search_box (closest, &feature, s - 1, t - 1, x, y,                \n"
"                        shape, rank, seed);                                   \n"
"                                                                              \n"
"          search_box (closest, &feature, s - 1, t, x, y,                      \n"
"                      shape, rank, seed);                                     \n"
"                                                                              \n"
"          if (d_l + d_t < *d_0)                                               \n"
"              search_box (closest, &feature, s - 1, t + 1, x, y,              \n"
"                          shape, rank, seed);                                 \n"
"        }                                                                     \n"
"                                                                              \n"
"      if (d_b < *d_0)                                                         \n"
"          search_box (closest, &feature, s, t - 1, x, y,                      \n"
"                      shape, rank, seed);                                     \n"
"                                                                              \n"
"      if (d_t < *d_0)                                                         \n"
"          search_box (closest, &feature, s, t + 1, x, y,                      \n"
"                      shape, rank, seed);                                     \n"
"                                                                              \n"
"      if (d_r < *d_0)                                                         \n"
"        {                                                                     \n"
"          if (d_r + d_b < *d_0)                                               \n"
"              search_box (closest, &feature, s + 1, t - 1, x, y,              \n"
"                          shape, rank, seed);                                 \n"
"                                                                              \n"
"          search_box (closest, &feature, s + 1, t, x, y,                      \n"
"                      shape, rank, seed);                                     \n"
"                                                                              \n"
"          if (d_r + d_t < *d_0)                                               \n"
"              search_box (closest, &feature, s + 1, t + 1, x, y,              \n"
"                          shape, rank, seed);                                 \n"
"        }                                                                     \n"
"                                                                              \n"
"      /* If palettized output is requested return the normalized hash of      \n"
"       * the closest feature point, otherwise return the closest              \n"
"       * distance. */                                                         \n"
"                                                                              \n"
"      if(palettize)                                                           \n"
"        {                                                                     \n"
"          n += feature / 4294967295.0f / c;                                   \n"
"        }                                                                     \n"
"      else                                                                    \n"
"        {                                                                     \n"
"          n += pow(closest[rank - 1], 1 / shape) / c;                         \n"
"        }                                                                     \n"
"    }                                                                         \n"
"                                                                              \n"
"  out[gidy * get_global_size(0) + gidx] = n;                                  \n"
"}                                                                             \n"
;
