From 58df17d0e7fb50901abbe96b64dbbe12eac9cdaa Mon Sep 17 00:00:00 2001 From: Benjamin Segovia Date: Fri, 4 May 2012 19:22:44 +0000 Subject: [PATCH] Started to implement mandelbrot --- kernels/mandelbrot.cl | 50 +++++++++++++++++++++++++++++++++++++++++++++++ utests/CMakeLists.txt | 1 + utests/app_mandelbrot.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 kernels/mandelbrot.cl create mode 100644 utests/app_mandelbrot.cpp diff --git a/kernels/mandelbrot.cl b/kernels/mandelbrot.cl new file mode 100644 index 0000000..66bab32 --- /dev/null +++ b/kernels/mandelbrot.cl @@ -0,0 +1,50 @@ +// Used to ID into the 1D array, so that we can use +// it effectively as a 2D array +int ID(int x, int y, int width) { + return 4*width*y + x*4; +} + +float mapX(float x) { return x*3.25f - 2.f; } +float mapY(float y) { return y*2.5f - 1.25f; } + +__kernel void mandelbrot(__global char *out) { + int x_dim = get_global_id(0); + int y_dim = get_global_id(1); + int width = get_global_size(0); + int height = get_global_size(1); + int idx = ID(x_dim, y_dim, width); + + float x_origin = mapX((float) x_dim / (float) width); + float y_origin = mapY((float) y_dim / (float) height); + + // The Escape time algorithm, it follows the pseduocode from Wikipedia + // _very_ closely + float x = 0.0f; + float y = 0.0f; + + int iteration = 0; + + // This can be changed, to be more or less precise + int max_iteration = 256; + while(x*x + y*y <= 4 && iteration < max_iteration) { + float xtemp = x*x - y*y + x_origin; + y = 2*x*y + y_origin; + x = xtemp; + iteration++; + } + + if(iteration == max_iteration) { + // This coordinate did not escape, so it is in the Mandelbrot set + out[idx] = 0; + out[idx + 1] = 0; + out[idx + 2] = 0; + out[idx + 3] = 255; + } else { + // This coordinate did escape, so color based on quickly it escaped + out[idx] = iteration; + out[idx + 1] = iteration; + out[idx + 2] = iteration; + out[idx + 3] = 255; + } + +} diff --git a/utests/CMakeLists.txt b/utests/CMakeLists.txt index aa0dd0d..c66e152 100644 --- a/utests/CMakeLists.txt +++ b/utests/CMakeLists.txt @@ -7,6 +7,7 @@ ADD_LIBRARY(utests SHARED utest_file_map.cpp utest_assert.cpp utest.cpp + app_mandelbrot.cpp compiler_write_only.cpp compiler_copy_buffer.cpp compiler_copy_buffer_row.cpp diff --git a/utests/app_mandelbrot.cpp b/utests/app_mandelbrot.cpp new file mode 100644 index 0000000..36b645a --- /dev/null +++ b/utests/app_mandelbrot.cpp @@ -0,0 +1,46 @@ +/* + * Copyright © 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Benjamin Segovia + */ + +#include "utest_helper.hpp" + +static int *dst = NULL; +static const size_t w = 64; +static const size_t h = 64; +static const size_t iter = 4; + +static void mandelbrot(void) +{ + const size_t global[2] = {w, h}; + const size_t local[2] = {16, 1}; + const size_t sz = w * h * sizeof(char[4]); + + OCL_CREATE_KERNEL("mandelbrot"); + + cl_mem cl_dst = clCreateBuffer(ctx, 0, sz, NULL, NULL); + OCL_CALL (clSetKernelArg, kernel, 0, sizeof(cl_mem), &cl_dst); + OCL_CALL (clEnqueueNDRangeKernel, queue, kernel, 2, NULL, global, local, 0, NULL, NULL); + dst = (int *) clIntelMapBuffer(cl_dst, NULL); + + //writeBmp(dst, w, h, "mandelbrot.bmp"); + OCL_CALL (clIntelUnmapBuffer, cl_dst); + OCL_CALL (clReleaseMemObject, cl_dst); +} + +MAKE_UTEST_FROM_FUNCTION(mandelbrot); + -- 2.7.4