Skip to content

Instantly share code, notes, and snippets.

@jkominek
Created April 24, 2013 04:13
Show Gist options
  • Save jkominek/5449575 to your computer and use it in GitHub Desktop.
Save jkominek/5449575 to your computer and use it in GitHub Desktop.
A simple OpenCL program for Racket
#lang racket
(require ffi/unsafe)
(require ffi/unsafe/cvector)
(require ffi/vector)
(require (planet jaymccarthy/opencl:3:=4/c))
(define count 1024000)
(define kernel_source
#"
__kernel void square(
__global float* input,
__global float* output,
const unsigned int count)
{
int i = get_global_id(0);
if(i < count)
output[i] = input[i] * input[i];
}
")
(define data
(apply f32vector
(for/list ([x (in-range 0 count)])
(random))))
(define results (make-f32vector count))
(define platform (cvector-ref (clGetPlatformIDs:vector) 0))
(for ([p (in-list '(CL_PLATFORM_PROFILE CL_PLATFORM_VERSION CL_PLATFORM_NAME CL_PLATFORM_VENDOR CL_PLATFORM_EXTENSIONS))])
(printf "~a ~a~n" p (clGetPlatformInfo:generic platform p)))
(define device
(cvector-ref (clGetDeviceIDs:vector platform 'CL_DEVICE_TYPE_GPU) 0))
(define context
(clCreateContext (vector 0) (vector device)))
(define commands (clCreateCommandQueue context device
'()))
(define program (clCreateProgramWithSource context (vector kernel_source)))
(clBuildProgram program (vector device) #"")
(define kernel (clCreateKernel program #"square"))
(define input (clCreateBuffer context 'CL_MEM_READ_ONLY (* count (ctype-sizeof _float)) #f))
(define output (clCreateBuffer context 'CL_MEM_WRITE_ONLY (* count (ctype-sizeof _float)) #f))
(clEnqueueWriteBuffer commands input 'CL_TRUE 0 (* count (ctype-sizeof _float)) (f32vector->cpointer data) (vector))
(clSetKernelArg:_cl_mem kernel 0 input)
(clSetKernelArg:_cl_mem kernel 1 output)
(clSetKernelArg:_cl_uint kernel 2 count)
(printf "length: ~a~n" (clGetKernelWorkGroupInfo:length kernel device 'CL_KERNEL_WORK_GROUP_SIZE))
(printf "length: ~a~n" (clGetKernelWorkGroupInfo:length kernel device 'CL_KERNEL_COMPILE_WORK_GROUP_SIZE))
(define local (clGetKernelWorkGroupInfo:_size_t kernel device 'CL_KERNEL_WORK_GROUP_SIZE))
(printf "kernel work group size: ~a~n" local)
(clEnqueueNDRangeKernel commands kernel 1 (vector count) (vector local) (vector))
(clFinish commands)
(clEnqueueReadBuffer commands output 'CL_TRUE 0 (* count (ctype-sizeof _float)) (f32vector->cpointer results) (vector))
(clReleaseMemObject input)
(clReleaseMemObject output)
(clReleaseProgram program)
(clReleaseKernel kernel)
(clReleaseCommandQueue commands)
(clReleaseContext context)
(/
(for/sum ([cl (in-list (f32vector->list results))]
[orig (in-list (f32vector->list data))])
(abs (- cl (* orig orig))))
count)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment