/* * Conway's Game of Life using OpenCL C. Originally from * http://ptgmedia.pearsoncmg.com/images/art_chisnall_opencl/elementLinks/opencl.c.html */ #include #include #include #include #include #include #include #include #include #include const char *kernel_source = "__kernel void life( \n" " constant bool*input, \n" " global bool* output, \n" " const unsigned int height, \n" " const unsigned int width) \n" "{ \n" " int i = get_global_id(0); \n" " int rowUp = i - width; \n" " int rowDown = i + width; \n" " bool outOfBounds = (i < width); \n" " outOfBounds |= (i > (width * (height-1))); \n" " outOfBounds |= (i % width == 0); \n" " outOfBounds |= (i % width == width-1); \n" " if (outOfBounds) { output[i] = false; return; } \n" " int neighbours = input[rowUp-1] + input[rowUp] + input[rowUp+1]; \n" " neighbours += input[i-1] + input[i+1]; \n" " neighbours += input[rowDown-1] + input[rowDown] + input[rowDown+1]; \n" " if (neighbours == 3 || (input[i] && neighbours == 2)) \n" " output[i] = true; \n" " else \n" " output[i] = false; \n" "} \n"; void fail(const char *message) { fprintf(stderr, "%s\n", message); exit(1); } cl_kernel createKernelFromSource(cl_device_id device_id, cl_context context, const char *source, const char *name) { int err; // Load the source cl_program program = clCreateProgramWithSource(context, 1, &source , NULL, &err); if (err != CL_SUCCESS) { fail("Unable to create program"); } // Compile it. err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); if (err != CL_SUCCESS) { size_t len; char buffer[2048]; clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len); fprintf(stderr, "%s\n", buffer); fail("Unable to build program"); } // Load it. cl_kernel kernel = clCreateKernel(program, name, &err); if (!kernel || err != CL_SUCCESS) { fail("Unable to create kernel"); } clReleaseProgram(program); return kernel; } // The board static const int width = 128; static const int height = 64; static const size_t board_size = width * height; static _Bool board[board_size]; // Storage for the board. static cl_mem input; static cl_mem output; // OpenCL state static cl_command_queue queue; static cl_kernel kernel; static cl_device_id device_id; static cl_context context; void printBoard(void) { unsigned i = 0; for (unsigned y=0 ; y (INT_MAX / 2); createQueue(); kernel = createKernelFromSource(device_id, context, kernel_source, "life"); prepareKernel(); printBoard(); int iterations = 0; do { printf("Run for how many iterations (0 to exit)? "); scanf("%d", &iterations); runGame(iterations); printBoard(); } while(iterations > 0); clReleaseMemObject(input); clReleaseMemObject(output); clReleaseKernel(kernel); clReleaseCommandQueue(queue); clReleaseContext(context); return 0; }