Explorar el Código

Minor code refactoring and parse some arguments from command line when
available (use -h for help).

Cédric Augonnet hace 14 años
padre
commit
03f2852f53
Se han modificado 1 ficheros con 168 adiciones y 99 borrados
  1. 168 99
      examples/mandelbrot/mandelbrot.c

+ 168 - 99
examples/mandelbrot/mandelbrot.c

@@ -18,11 +18,15 @@
 #ifdef STARPU_USE_OPENCL
 #include <starpu_opencl.h>
 #endif
+#include <sys/time.h>
+
 #ifdef STARPU_HAVE_X11
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+int use_x11 = 1;
 #endif
 
+
 /* NB: The X11 code is inspired from the http://locklessinc.com/articles/mandelbrot/ article */
 
 static int nblocks = 16;
@@ -35,9 +39,9 @@ static double rightX = -0.74375;
 static double topY = .15;
 static double bottomY = .14875;
 
-#ifdef STARPU_USE_OPENCL
-static struct starpu_opencl_program opencl_programs;
-#endif
+/*
+ *	X11 window management
+ */
 
 #ifdef STARPU_HAVE_X11
 /* X11 data */
@@ -46,7 +50,6 @@ 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)
 {
@@ -110,35 +113,117 @@ static void init_x11(int width, int height, unsigned *buffer)
         Down = XStringToKeysym ("Down");
         Alt = XStringToKeysym ("Alt");
 }
+
+static int handle_events(void)
+{
+	XEvent event;
+	XNextEvent(dpy, &event);
+
+	KeySym key;
+	char text[255];
+
+	if (event.type == KeyPress)
+	{
+		XLookupString(&event.xkey,text,255,&key,0);
+		if (key == Left)
+		{
+			double widthX = rightX - leftX;
+			leftX -= 0.25*widthX;
+			rightX -= 0.25*widthX;
+		}
+		else if (key == Right)
+		{
+			double widthX = rightX - leftX;
+			leftX += 0.25*widthX;
+			rightX += 0.25*widthX;
+		}
+		else if (key == Up)
+		{
+			double heightY = topY - bottomY;
+			topY += 0.25*heightY;
+			bottomY += 0.25*heightY;
+		}
+		else if (key == Down)
+		{
+			double heightY = topY - bottomY;
+			topY -= 0.25*heightY;
+			bottomY -= 0.25*heightY;
+		}
+		else {
+			double widthX = rightX - leftX;
+			double heightY = topY - bottomY;
+
+			if (text[0] == '-')
+			{
+				/* Zoom out */
+				leftX -= 0.125*widthX;
+				rightX += 0.125*widthX;
+				topY += 0.125*heightY;
+				bottomY -= 0.125*heightY;
+			}
+			else if (text[0] == '+')
+			{
+				/* Zoom in */
+				leftX += 0.125*widthX;
+				rightX -= 0.125*widthX;
+				topY -= 0.125*heightY;
+				bottomY += 0.125*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
 
+/*
+ *	OpenCL kernel
+ */
+
 #ifdef STARPU_USE_OPENCL
 char *mandelbrot_opencl_src = "\
 #pragma OPENCL EXTENSION cl_khr_fp64 : enable\n\
-#define MIN(a,b) (((a)<(b))? (a) : (b))\n\
-__kernel void mandelbrot_kernel(__global unsigned* a,\n\
-          double leftX, double topY,\n\
-          double stepX, double stepY,\n\
-          int maxIt, int iby, int block_size)\n\
-{\n\
-    double xc = leftX + get_global_id(0) * stepX;\n\
-    double yc = -iby*block_size*stepY + topY  - get_global_id(1) * stepY;\n\
-    int it;\n\
-    double x,y;\n\
-    x = y = (double)0.0;\n\
-    for (it=0;it<maxIt;it++)\n\
-    {\n\
-      double x2 = x*x;\n\
-      double y2 = y*y;\n\
-      if (x2+y2 > 4.0) break; \n\
-      double twoxy = (double)2.0*x*y;\n\
-      x = x2 - y2 + xc;\n\
-      y = twoxy + yc;\n\
-    }\n\
-   unsigned 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\
+#define MIN(a,b) (((a)<(b))? (a) : (b))					\n\
+__kernel void mandelbrot_kernel(__global unsigned* a,			\n\
+          double leftX, double topY,					\n\
+          double stepX, double stepY,					\n\
+          int maxIt, int iby, int block_size, int width)		\n\
+{									\n\
+    size_t id_x = get_global_id(0);	\n\
+    size_t id_y = get_global_id(1);	\n\
+    if ((id_x < width) && (id_y < block_size))				\n\
+    {									\n\
+        double xc = leftX + id_x * stepX;				\n\
+        double yc = topY - (id_y + iby*block_size) * stepY;		\n\
+        int it;								\n\
+        double x,y;							\n\
+        x = y = (double)0.0;						\n\
+        for (it=0;it<maxIt;it++)					\n\
+        {								\n\
+          double x2 = x*x;						\n\
+          double y2 = y*y;						\n\
+          if (x2+y2 > 4.0) break;					\n\
+          double twoxy = (double)2.0*x*y;				\n\
+          x = x2 - y2 + xc;						\n\
+          y = twoxy + yc;						\n\
+        }								\n\
+       unsigned int v = MIN((1024*((float)(it)/(2000))), 256);		\n\
+       a[id_x + width * id_y] = (v<<16|(255-v)<<8);			\n\
+   }									\n\
 }";
 
+static struct starpu_opencl_program opencl_programs;
+
 static void compute_block_opencl(void *descr[], void *cl_arg)
 {
 	int iby, block_size;
@@ -163,15 +248,21 @@ static void compute_block_opencl(void *descr[], void *cl_arg)
 	clSetKernelArg(kernel, 5, sizeof(int), &maxIt);
 	clSetKernelArg(kernel, 6, sizeof(int), &iby);
 	clSetKernelArg(kernel, 7, sizeof(int), &block_size);
+	clSetKernelArg(kernel, 8, sizeof(int), &width);
 
-	size_t local[3] = {64, 1, 1};
-	size_t global[3] = {width, block_size, 1};
-	clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global, local, 0, NULL, NULL);
+	unsigned dim = 16;
+	size_t local[2] = {dim, 1};
+	size_t global[2] = {width, block_size};
+	clEnqueueNDRangeKernel(queue, kernel, 2, NULL, global, local, 0, NULL, NULL);
 	clFinish(queue);
 	starpu_opencl_release_kernel(kernel);
 }
 #endif
 
+/*
+ *	CPU kernel
+ */
+
 static void compute_block(void *descr[], void *cl_arg)
 {
 	int ix, iy;
@@ -226,88 +317,55 @@ static starpu_codelet mandelbrot_cl = {
 	.nbuffers = 1
 };
 
-#ifdef STARPU_HAVE_X11
-static int handle_events(void)
+static void parse_args(int argc, char **argv)
 {
-	XEvent event;
-	XNextEvent(dpy, &event);
-
-	KeySym key;
-	char text[255];
-
-	if (event.type == KeyPress)
-	{
-		XLookupString(&event.xkey,text,255,&key,0);
-		if (key == Left)
-		{
-			double widthX = rightX - leftX;
-			leftX -= 0.25*widthX;
-			rightX -= 0.25*widthX;
-		}
-		else if (key == Right)
-		{
-			double widthX = rightX - leftX;
-			leftX += 0.25*widthX;
-			rightX += 0.25*widthX;
+	int i;
+	for (i = 1; i < argc; i++) {
+		if (strcmp(argv[i], "-h") == 0) {
+			fprintf(stderr, "Usage: %s [-h] [ -width 800] [-height 600] [-nblocks 16] [-no-x11] [-pos leftx:rightx:bottomy:topy]\n", argv[0]);
+			exit(-1);
 		}
-		else if (key == Up)
-		{
-			double heightY = topY - bottomY;
-			topY += 0.25*heightY;
-			bottomY += 0.25*heightY;
+
+		if (strcmp(argv[i], "-width") == 0) {
+			char *argptr;
+			width = strtol(argv[++i], &argptr, 10);
 		}
-		else if (key == Down)
-		{
-			double heightY = topY - bottomY;
-			topY -= 0.25*heightY;
-			bottomY -= 0.25*heightY;
+
+		if (strcmp(argv[i], "-height") == 0) {
+			char *argptr;
+			height = strtol(argv[++i], &argptr, 10);
 		}
-		else {
-			double widthX = rightX - leftX;
-			double heightY = topY - bottomY;
 
-			if (text[0] == '-')
-			{
-				/* Zoom out */
-				leftX -= 0.125*widthX;
-				rightX += 0.125*widthX;
-				topY += 0.125*heightY;
-				bottomY -= 0.125*heightY;
-			}
-			else if (text[0] == '+')
-			{
-				/* Zoom in */
-				leftX += 0.125*widthX;
-				rightX -= 0.125*widthX;
-				topY -= 0.125*heightY;
-				bottomY += 0.125*heightY;
-			}
+		if (strcmp(argv[i], "-nblocks") == 0) {
+			char *argptr;
+			nblocks = strtol(argv[++i], &argptr, 10);
 		}
 
-		if (text[0]=='q') {
-			return -1;
+		if (strcmp(argv[i], "-pos") == 0) {
+			int ret = sscanf(argv[++i], "%lf:%lf:%lf:%lf", &leftX, &rightX, &bottomY, &topY);
+			assert(ret == 4);
 		}
-	}
 
-	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);
+		if (strcmp(argv[i], "-no-x11") == 0) {
+#ifdef STARPU_HAVE_X11
+			use_x11 = 0;
+#endif
+		}
 	}
-
-	return 0;
 }
-#endif
 
 int main(int argc, char **argv)
 {
+	parse_args(argc, argv);
+
 	starpu_init(NULL);
 
 	unsigned *buffer;
 	starpu_data_malloc_pinned_if_possible((void **)&buffer, height*width*sizeof(unsigned));
 
 #ifdef STARPU_HAVE_X11
-	init_x11(width, height, buffer);
+	if (use_x11)
+		init_x11(width, height, buffer);
 #endif
 
 	int block_size = height/nblocks;
@@ -332,6 +390,10 @@ int main(int argc, char **argv)
 		double stepX = (rightX - leftX)/width;
 		double stepY = (topY - bottomY)/height;
 
+		struct timeval start, end;
+
+		gettimeofday(&start, NULL);
+
 		for (iby = 0; iby < nblocks; iby++)
 		{
 			starpu_insert_task(&mandelbrot_cl,
@@ -347,24 +409,31 @@ int main(int argc, char **argv)
 		{
 			starpu_data_acquire(block_handles[iby], STARPU_R);
 #ifdef STARPU_HAVE_X11
-			pthread_mutex_lock(&mutex);
-			XPutImage(dpy, win, gc, bitmap,
-				0, iby*block_size,
-				0, iby*block_size,
-				width, block_size);
-			pthread_mutex_unlock(&mutex);
+			if (use_x11)
+			{
+				XPutImage(dpy, win, gc, bitmap,
+					0, iby*block_size,
+					0, iby*block_size,
+					width, block_size);
+			}
 #endif
 			starpu_data_release(block_handles[iby]);
 		}
 
+		gettimeofday(&end, NULL);
+		double timing = (double)((end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec));
+
+		fprintf(stderr, "Time to generate frame : %f ms\n", timing/1000.0);
+
 #ifdef STARPU_HAVE_X11
-		if (handle_events())
+		if (use_x11 && handle_events())
 			break;
 #endif
 	}
 
 #ifdef STARPU_HAVE_X11
-	exit_x11();
+	if (use_x11)
+		exit_x11();
 #endif
 
 	for (iby = 0; iby < nblocks; iby++)