Bläddra i källkod

Implemented device selection for leukocyte

We now use parameters as the way to select OpenCL platform, device and
type instead of having the hardcoded in the code. In this way we can
easily change the type of the benchmark without recompiling it.

Since the available argument parsing was really artisanal, I rewrote it using
the standard getopt helper function.
Andrea Gussoni 8 år sedan
förälder
incheckning
9f0ccf1917

+ 48 - 12
opencl/leukocyte/OpenCL/detect_main.c

@@ -6,26 +6,62 @@ cl_context context;
 cl_command_queue command_queue;
 cl_device_id device;
 
+// Helper function to print usage
+void usage(char *argv0) {
+    char *help =
+    "\nUsage: %s [switches] \n\n"
+		"    -i               :input file           \n"
+    "    -f               :frames to process    \n"
+    "    -p platform_id   :OCL platform to use [default=0]\n"
+    "    -d device_id     :OCL device to use   [default=0]\n"
+    "    -g use_gpu       :1 for GPU 0 for CPU [default=0]\n";
+    fprintf(stderr, help, argv0);
+    exit(-1);
+}
+
 int main(int argc, char ** argv) {
 	
-	// Make sure the command line arguments have been specified
-	if (argc !=3)	{
-		fprintf(stderr, "Usage: %s <input file> <number of frames to process>", argv[0]);
-		exit(EXIT_FAILURE);
-	}
+  // Let the user specify the number of frames to process
+	int num_frames = 0;
+	
+	// Open video file
+	char *video_file_name = 0;
+  
+  // Arguments parsing for platform, device and type
+  // Variables to store information on platform and device to use_gpu
+  int platform_id = 0;
+  int device_id = 0;
+  int use_gpu = 0;
+
+  /* obtain command line arguments and change appropriate options */
+  int opt;
+  extern char *optarg;
+  while ((opt=getopt(argc,argv,"i:f:p:d:g:"))!= EOF) {
+      switch (opt) {
+          case 'p': platform_id = atoi(optarg);
+                    break;
+          case 'd': device_id = atoi(optarg);
+                    break;
+          case 'g': use_gpu = atoi(optarg);
+                    break;      
+          case 'i': video_file_name = optarg;
+                    break;      
+          case 'f': num_frames = atoi(optarg);
+                    break;                                                            
+          case '?': usage(argv[0]);
+                    break;
+          default: usage(argv[0]);
+                    break;
+      }
+  }
+
 
 	// Choose the best GPU in case there are multiple available
-	choose_GPU();
+	choose_GPU(platform_id, device_id, use_gpu);
 
 	// Keep track of the start time of the program
 	long long program_start_time = get_time();
 	
-	// Let the user specify the number of frames to process
-	int num_frames = atoi(argv[2]);
-	
-	// Open video file
-	char *video_file_name = argv[1];
-	
 	avi_t *cell_file = AVI_open_input_file(video_file_name, 1);
 	if (cell_file == NULL)	{
 		AVI_print_error("Error with AVI_open_input_file");

+ 2 - 2
opencl/leukocyte/OpenCL/find_ellipse.c

@@ -81,8 +81,8 @@ MAT * chop_flip_image(unsigned char *image, int height, int width, int top, int
 
 
 // Chooses the best GPU on the current machine
-void choose_GPU() {
-	select_device();
+void choose_GPU(int platform_id, int device_id, int use_gpu) {
+	select_device(platform_id, device_id, use_gpu);
 }
 
 

+ 29 - 31
opencl/leukocyte/OpenCL/find_ellipse_opencl.c

@@ -214,7 +214,7 @@ float *dilate_OpenCL(int max_gicov_m, int max_gicov_n, int strel_m, int strel_n)
 
 
 // Chooses the most appropriate GPU on which to execute
-void select_device() {
+void select_device(int platform_id, int device_id, int use_gpu) {
 	cl_int error;
 
 	// Determine the number of platforms
@@ -231,39 +231,37 @@ void select_device() {
 	// Get the list of platforms
 	cl_platform_id *platform_ids = (cl_platform_id *) malloc(sizeof(cl_platform_id) * num_platforms);
 	error = clGetPlatformIDs(num_platforms, platform_ids, NULL);
+  check_error(error, __FILE__, __LINE__);
+  
+  // Selector for the device type in accordance to what passed as parameter
+  cl_device_type device_type = use_gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU;
+
+	// Create an OpenCL context
+	cl_context_properties ctxprop[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform_ids[platform_id], 0};
+	context = clCreateContextFromType(ctxprop, device_type, NULL, NULL, &error);
+	// If this platform has no GPU, try the next one
 	check_error(error, __FILE__, __LINE__);
 	
-	// Iterate through all available platforms, choosing the first one that has a GPU
-	int i;
-	for (i = 0; i < num_platforms; i++) {
+	// Get the list of devices (GPUs or CPUs)
+	size_t size;
+	error = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &size);
+	check_error(error, __FILE__, __LINE__);
+	cl_device_id *device_list = (cl_device_id *) malloc(size);
+	error = clGetContextInfo(context, CL_CONTEXT_DEVICES, size, device_list, NULL);
+	check_error(error, __FILE__, __LINE__);
+
+	// Create a command queue for the device passed as parameter
+	device = device_list[device_id];
+	command_queue = clCreateCommandQueue(context, device, 0, &error);
+	check_error(error, __FILE__, __LINE__);
+	
+	// Print the device name
+	char cBuffer[1024];
+	clGetDeviceInfo(device_list[0], CL_DEVICE_NAME, sizeof(cBuffer), &cBuffer, NULL);
+	printf("Running on: %s\n", cBuffer);
+	
+	return;
 	
-		// Create an OpenCL context
-		cl_context_properties ctxprop[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform_ids[i], 0};
-		context = clCreateContextFromType(ctxprop, CL_DEVICE_TYPE_GPU, NULL, NULL, &error);
-		// If this platform has no GPU, try the next one
-		if (error == CL_DEVICE_NOT_FOUND) continue;
-		check_error(error, __FILE__, __LINE__);
-		
-		// Get the list of devices (GPUs)
-		size_t size;
-		error = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &size);
-		check_error(error, __FILE__, __LINE__);
-		cl_device_id *device_list = (cl_device_id *) malloc(size);
-		error = clGetContextInfo(context, CL_CONTEXT_DEVICES, size, device_list, NULL);
-		check_error(error, __FILE__, __LINE__);
-
-		// Create a command queue for the first device
-		device = device_list[0];
-		command_queue = clCreateCommandQueue(context, device, 0, &error);
-		check_error(error, __FILE__, __LINE__);
-		
-		// Print the device name
-		char cBuffer[1024];
-		clGetDeviceInfo(device_list[0], CL_DEVICE_NAME, sizeof(cBuffer), &cBuffer, NULL);
-		printf("Running on: %s\n", cBuffer);
-		
-		return;
-	}
 	
 	// If we reach here, no platform has a GPU
 	printf("Error: None of the platforms has a GPU\n");

+ 1 - 1
opencl/leukocyte/OpenCL/run-cpu

@@ -1 +1 @@
-./leukocyte ../../../data/leukocyte/testfile.avi 100
+./leukocyte -i ../../../data/leukocyte/testfile.avi -f 100 -p 1 -d 0 -g 0

+ 1 - 0
opencl/leukocyte/OpenCL/run-gpu

@@ -0,0 +1 @@
+./leukocyte -i ../../../data/leukocyte/testfile.avi -f 100 -p 0 -d 0 -g 1