/* StarPU --- Runtime system for heterogeneous multicore architectures. * * Copyright (C) 2010,2011 University of Bordeaux * * StarPU 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.1 of the License, or (at * your option) any later version. * * StarPU 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 in COPYING.LGPL for more details. */ #include #include #include #include /* Uncomment this to activate X11 display */ #define USE_X11 #define SHORT_LOG 1 #define ROUND_ROBIN #ifdef USE_X11 #include #include int use_x11 = 1; #else int use_x11 = 0; #endif int demo = 0; int frames = -1; #include #include #include #include #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(EXIT_FAILURE); } while(0) #define check(err, str) do { if(err != CL_SUCCESS) { fprintf(stderr, "OpenCL Error (%d): %s\n",err, str); exit(EXIT_FAILURE); }} while(0) #ifdef UNUSED #elif defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) #else # define UNUSED(x) x #endif const char * kernel_src = "\ #pragma OPENCL EXTENSION cl_khr_fp64 : enable\n\ #define TYPE double \n\ #define MIN(a,b) (((a)<(b))? (a) : (b))\n\ __kernel void mandelbrot_kernel(__global uint * a,\n\ TYPE leftX, TYPE topY,\n\ TYPE stepX, TYPE stepY,\n\ uint maxIt, uint iby, uint block_size)\n\ {\n\ TYPE xc = leftX + get_global_id(0) * stepX;\n\ TYPE yc = iby*block_size*stepY + topY + get_global_id(1) * stepY;\n\ int it;\n\ TYPE x,y;\n\ x = y = (TYPE)0.0;\n\ for (it=0;it (TYPE)4) break; \n\ TYPE twoxy = (TYPE)2*x*y;\n\ x = x2 - y2 + xc;\n\ y = twoxy + yc;\n\ }\n\ uint v = MIN((1024*((float)(it)/(2000))), 256);\n\ a[get_global_id(0) + get_global_id(1)*get_global_size(0)] = (v<<16|(255-v)<<8); \n\ }"; static cl_uint nblocks = 8; static cl_uint height = 768; static cl_uint width = 1024; static cl_uint maxIt = 20000; static cl_uint group_size = 64; static double leftX = -0.745; static double rightX = -0.74375; static double topY = .15; static double bottomY = .14875; #ifdef USE_X11 /* X11 data */ static Display *dpy; static Window win; static XImage *bitmap; static GC gc; static KeySym Left=-1, Right, Down, Up, Alt ; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static void exit_x11(void) { XDestroyImage(bitmap); XDestroyWindow(dpy, win); XCloseDisplay(dpy); } static void init_x11(int width, int height, cl_uint *buffer) { /* Attempt to open the display */ dpy = XOpenDisplay(NULL); /* Failure */ if (!dpy) exit(0); unsigned long white = WhitePixel(dpy,DefaultScreen(dpy)); unsigned long black = BlackPixel(dpy,DefaultScreen(dpy)); win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, black, white); /* We want to be notified when the window appears */ XSelectInput(dpy, win, StructureNotifyMask); /* Make it appear */ XMapWindow(dpy, win); XTextProperty tp; char name[128] = "Mandelbrot"; char *n = name; Status st = XStringListToTextProperty(&n, 1, &tp); if (st) XSetWMName(dpy, win, &tp); /* Wait for the MapNotify event */ XFlush(dpy); int depth = DefaultDepth(dpy, DefaultScreen(dpy)); Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy)); /* Make bitmap */ bitmap = XCreateImage(dpy, visual, depth, ZPixmap, 0, (char *)buffer, width, height, 32, 0); /* Init GC */ gc = XCreateGC(dpy, win, 0, NULL); XSetForeground(dpy, gc, black); XSelectInput(dpy, win, ExposureMask | KeyPressMask | StructureNotifyMask); Atom wmDeleteMessage; wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, win, &wmDeleteMessage, 1); Left = XStringToKeysym ("Left"); Right = XStringToKeysym ("Right"); Up = XStringToKeysym ("Up"); Down = XStringToKeysym ("Down"); Alt = XStringToKeysym ("Alt"); } static int handle_events(void) { XEvent event; XNextEvent(dpy, &event); KeySym key; char text[255]; double coef = 0.05; if (event.type == KeyPress) { XLookupString(&event.xkey,text,255,&key,0); if (key == Left) { double widthX = rightX - leftX; leftX -= coef*widthX; rightX -= coef*widthX; } else if (key == Right) { double widthX = rightX - leftX; leftX += coef*widthX; rightX += coef*widthX; } else if (key == Down) { double heightY = topY - bottomY; topY += coef*heightY; bottomY += coef*heightY; } else if (key == Up) { double heightY = topY - bottomY; topY -= coef*heightY; bottomY -= coef*heightY; } else { double widthX = rightX - leftX; double heightY = topY - bottomY; if (text[0] == '-') { /* Zoom out */ leftX -= (coef/2)*widthX; rightX += (coef/2)*widthX; topY += (coef/2)*heightY; bottomY -= (coef/2)*heightY; } else if (text[0] == '+') { /* Zoom in */ leftX += (coef/2)*widthX; rightX -= (coef/2)*widthX; topY -= (coef/2)*heightY; bottomY += (coef/2)*heightY; } } if (text[0]=='q') { return -1; } } if (event.type==ButtonPress) { /* tell where the mouse Button was Pressed */ printf("You pressed a button at (%i,%i)\n", event.xbutton.x,event.xbutton.y); } return 0; } #endif //USE_X11 static void parse_args(int argc, char **argv) { int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-h") == 0) { fprintf(stderr, "Usage: %s [-h] [ -width 1024] [-height 768] [-nblocks 16] [-group_size 64] [-no-x11] [-demo] [-frames N] [-pos leftx:rightx:bottomy:topy]\n", argv[0]); exit(-1); } if (strcmp(argv[i], "-width") == 0) { char *argptr; width = strtol(argv[++i], &argptr, 10); } if (strcmp(argv[i], "-frames") == 0) { char *argptr; frames = strtol(argv[++i], &argptr, 10); } if (strcmp(argv[i], "-height") == 0) { char *argptr; height = strtol(argv[++i], &argptr, 10); } if (strcmp(argv[i], "-group_size") == 0) { char *argptr; group_size = strtol(argv[++i], &argptr, 10); } if (strcmp(argv[i], "-nblocks") == 0) { char *argptr; nblocks = strtol(argv[++i], &argptr, 10); } if (strcmp(argv[i], "-pos") == 0) { int ret = sscanf(argv[++i], "%lf:%lf:%lf:%lf", &leftX, &rightX, &bottomY, &topY); assert(ret == 4); } if (strcmp(argv[i], "-demo") == 0) { demo = 1; leftX = -50.22749575062760; rightX = 48.73874621262927; topY = -49.35016705749115; bottomY = 49.64891691946615; } if (strcmp(argv[i], "-no-x11") == 0) { #ifdef USE_X11 use_x11 = 0; #endif } } } int main(int argc, char **argv) { #define MAX_DEVICES 20 cl_platform_id platforms[15]; cl_uint num_platforms; cl_device_id devices[15]; cl_uint num_devices; cl_context context; cl_program program; cl_kernel kernel; cl_command_queue cq[MAX_DEVICES]; cl_int err; cl_uint i; parse_args(argc, argv); cl_uint block_size = height/nblocks; assert((height % nblocks) == 0); assert((width % group_size) == 0); err = clGetPlatformIDs(0, NULL, &num_platforms); if (num_platforms == 0) { printf("No OpenCL platform found. If you use SOCL, this could mean StarPU wasn't configured for OpenCL. Try disabling CUDA support in StarPU (export STARPU_NCUDA=0).\n"); exit(0); } err = clGetPlatformIDs(sizeof(platforms)/sizeof(cl_platform_id), platforms, NULL); check(err, "clGetPlatformIDs"); unsigned int platform_idx; for (platform_idx=0; platform_idx