Automatic Single- to Double-Precision Conversion
Write code that will use the maximum available precision on the specific CUDA or OpenCL device.
code = "
#ifdef USING_DOUBLE_PRECISIONQ
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#pragma OPENCL EXTENSION cl_amd_fp64 : enable
#endif /* USING_DOUBLE_PRECISIONQ */
__kernel void julia_kernel(__global Real_t * set, int width, int height, Real_t cx, Real_t cy) {
int xIndex = get_global_id(0);
int yIndex = get_global_id(1);
int ii;
Real_t x = ZOOM_LEVEL*(width/2 - xIndex);
Real_t y = ZOOM_LEVEL*(height/2 - yIndex);
Real_t tmp;
Real_t c;
if (xIndex < width && yIndex < height) {
for (ii = 0; ii < MAX_ITERATIONS && x*x + y*y < BAILOUT; ii++) {
tmp = x*x - y*y + cx;
y = 2*x*y + cy;
x = tmp;
}
c = log(0.1f + sqrt(x*x + y*y));
set[xIndex + yIndex*width] = c;
}
}
";Needs["OpenCLLink`"]
{width, height} = {512, 512};
jset = OpenCLMemoryAllocate[Real, {height, width}];
JuliaCalculate = OpenCLFunctionLoad[code, "julia_kernel", {{_Real, _, "Output"}, _Integer, _Integer, _Real, _Real}, {16, 16}, "Defines" -> {"MAX_ITERATIONS" -> 10, "ZOOM_LEVEL" -> "0.0050", "BAILOUT" -> "4.0"}];Manipulate[
JuliaCalculate[jset, width, height, c[[1]], c[[2]], {width, height}];
ReliefPlot[OpenCLMemoryGet[jset], DataRange -> {{-2.0, 2.0}, {-2.0, 2.0}}, ImageSize -> 256, ColorFunction -> "SunsetColors"],
{{c, {0, 1}}, {-2, -2}, {2, 2}, Locator}]