Guest User

Untitled

a guest
Apr 11th, 2017
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.40 KB | None | 0 0
  1. import pyopencl as cl
  2. import numpy as np
  3. from PIL import Image
  4. from decimal import Decimal
  5.  
  6. def mandel(ctx, x, y, zoom, max_iter=1000, iter_steps=1, width=500, height=500, use_double=False):
  7.     mf = cl.mem_flags
  8.     cl_queue = cl.CommandQueue(ctx)
  9.     # build program
  10.     code = """
  11.    #if real_t == double
  12.        #pragma OPENCL EXTENSION cl_khr_fp64 : enable
  13.    #endif
  14.    kernel void mandel(
  15.        __global real_t2 *coords,
  16.        __global uint *ids_map,
  17.        __global uint *output,
  18.        uint max_iter,
  19.        uint start_iter    
  20.    ){
  21.        uint id = get_global_id(0);
  22.        uint rid = ids_map[id];
  23.        real_t2 my_coords = coords[rid];          
  24.        real_t x = my_coords.x;
  25.        real_t y = my_coords.y;
  26.        uint iter = 0;
  27.        for(iter=start_iter; iter<max_iter; ++iter){
  28.            if(x*x + y*y > 4.0f){
  29.                break;
  30.            }
  31.            real_t xtemp = x*x - y*y + my_coords.x;
  32.            y = 2*x*y + my_coords.y;
  33.            x = xtemp;
  34.        }
  35.        // copy the current x,y pair back
  36.        my_coords.x = x;
  37.        my_coords.y = y;
  38.        coords[rid] = my_coords;
  39.        output[id] = iter;
  40.    }        
  41.    """
  42.     _cltype, _nptype = ("double",np.float64) if use_double else ("float", np.float32)
  43.     prg = cl.Program(ctx, code).build("-cl-opt-disable -D real_t=%s -D real_t2=%s2" % (_cltype, _cltype))
  44.    
  45.     # Calculate the "viewport".
  46.     x0 = x - ((Decimal(3) * zoom)/Decimal(2.))
  47.     y0 = y - ((Decimal(2) * zoom)/Decimal(2.))
  48.     x1 = x + ((Decimal(3) * zoom)/Decimal(2.))
  49.     y1 = y + ((Decimal(2) * zoom)/Decimal(2.))
  50.  
  51.     # Create index map in x,y pairs
  52.     xx = np.arange(_nptype(x0), _nptype(x1), _nptype((x1-x0)/Decimal(width)), dtype=_nptype)
  53.     yy = np.arange(_nptype(y0), _nptype(y1), _nptype((y1-y0)/Decimal(height)), dtype=_nptype)
  54.     coord_map = np.dstack(np.meshgrid(xx, yy)).astype(_nptype).flatten()
  55.     buffer_coords_cl = cl.Buffer(ctx, mf.COPY_HOST_PTR, hostbuf=coord_map)
  56.     # Create input and output buffer
  57.     indices = np.arange(0, width*height, 1, np.uint32)
  58.     buffer_in_cl = cl.Buffer(ctx, mf.READ_ONLY, size=indices.nbytes)
  59.     buffer_out = np.zeros(width*height, dtype=np.uint32) # This will contain the iteration values of that run
  60.     buffer_out_cl = cl.Buffer(ctx, mf.WRITE_ONLY, size=buffer_out.nbytes)        
  61.     # 2D Buffer to collect the iterations needed per pixel
  62.     iter_map = np.zeros(width*height, dtype=np.uint32)
  63.    
  64.     start_max_iter = 0
  65.     to_do = indices.size
  66.     steps_size = int(max_iter / float(iter_steps))
  67.     while to_do > 0 and start_max_iter < max_iter:
  68.         end_max_iter = min(max_iter, start_max_iter + steps_size )
  69.         print "Iterations from iteration %i to %i for %i numbers" % (start_max_iter, end_max_iter, to_do)
  70.         # copy indices to device
  71.         cl.enqueue_copy(cl_queue, buffer_in_cl, indices[:to_do]).wait()        
  72.         # and finally call the ocl function
  73.         prg.mandel(cl_queue, (to_do,), None,
  74.             buffer_coords_cl,
  75.             buffer_in_cl,              
  76.             buffer_out_cl,
  77.             np.uint32(end_max_iter),
  78.             np.uint32(start_max_iter)
  79.         ).wait()
  80.         # Copy the output back
  81.         cl.enqueue_copy(cl_queue, buffer_out, buffer_out_cl).wait()
  82.         # Get indices of "found" escapes
  83.         done = np.where(buffer_out[:to_do] < end_max_iter)[0]        
  84.         done_index = indices[done]
  85.         # Write needed iteration to out buffer
  86.         iter_map[done_index] = buffer_out[done]
  87.         # Write non escapes back to indices for the next loop
  88.         undone = np.where(buffer_out[:to_do] >= end_max_iter)[0]
  89.         indices[:undone.size] = indices[undone]
  90.         to_do = undone.size
  91.         start_max_iter = end_max_iter        
  92.         print "%i done. %i unknown" % (done.size, undone.size)                            
  93.    
  94.     # simple coloring by modulo 255 on the iter_map
  95.     return (iter_map % 255).astype(np.uint8).reshape((height, width))
  96.  
  97.  
  98. if __name__ == '__main__':
  99.     ctx = cl.create_some_context(interactive=True)
  100.     img = mandel(ctx,
  101.           x=Decimal("-0.7546546453361122021732941811"),
  102.           y=Decimal("0.05020518634419688663435986387"),
  103.           zoom=Decimal("0.0002046859427855630601247281079"),
  104.           max_iter=2000,
  105.           iter_steps=10,
  106.           width=500,
  107.           height=400,
  108.           use_double=False
  109.     )
  110.     Image.fromarray(img).show()
Advertisement
Add Comment
Please, Sign In to add comment