Browse Source

OpenCL: new function starpu_opencl_load_binary_opencl() to load a binary OpenCL kernel

Nathalie Furmento 13 years ago
parent
commit
0b1d4dad0f
3 changed files with 78 additions and 0 deletions
  1. 6 0
      doc/chapters/basic-api.texi
  2. 2 0
      include/starpu_opencl.h
  3. 70 0
      src/drivers/opencl/driver_opencl_utils.c

+ 6 - 0
doc/chapters/basic-api.texi

@@ -2340,6 +2340,12 @@ OpenCL device, and the filename is suffixed with the vendor id and the
 device id of the OpenCL device.
 @end deftypefun
 
+@deftypefun int starpu_opencl_load_binary_opencl ({const char *}@var{kernel_id}, {struct starpu_opencl_program *}@var{opencl_programs})
+Compile the binary OpenCL kernel identified with @var{id}. For every
+OpenCL device, the binary OpenCL kernel will be loaded from the file
+@code{$STARPU_HOME/.starpu/opencl/<kernel_id>.<device_type>.vendor_id_<vendor_id>_device_id_<device_id>}.
+@end deftypefun
+
 @node Loading OpenCL kernels
 @subsection Loading OpenCL kernels
 

+ 2 - 0
include/starpu_opencl.h

@@ -63,6 +63,8 @@ void starpu_opencl_load_program_source(const char *source_file_name, char *locat
 int starpu_opencl_compile_opencl_from_file(const char *source_file_name, const char* build_options);
 int starpu_opencl_compile_opencl_from_string(const char *opencl_program_source, const char *file_name, const char* build_options);
 
+int starpu_opencl_load_binary_opencl(const char *kernel_id, struct starpu_opencl_program *opencl_programs);
+
 int starpu_opencl_load_opencl_from_file(const char *source_file_name, struct starpu_opencl_program *opencl_programs, const char* build_options);
 int starpu_opencl_load_opencl_from_string(const char *opencl_program_source, struct starpu_opencl_program *opencl_programs, const char* build_options);
 int starpu_opencl_unload_opencl(struct starpu_opencl_program *opencl_programs);

+ 70 - 0
src/drivers/opencl/driver_opencl_utils.c

@@ -370,6 +370,76 @@ int starpu_opencl_load_opencl_from_file(const char *source_file_name, struct sta
 	return _starpu_opencl_compile_or_load_opencl_from_file(source_file_name, opencl_programs, build_options);
 }
 
+int starpu_opencl_load_binary_opencl(const char *kernel_id, struct starpu_opencl_program *opencl_programs)
+{
+        unsigned int dev;
+        unsigned int nb_devices;
+
+        nb_devices = _starpu_opencl_get_device_count();
+        // Iterate over each device
+        for(dev = 0; dev < nb_devices; dev ++)
+	{
+                cl_device_id device;
+                cl_context   context;
+                cl_program   program;
+                cl_int       err;
+		char        *binary;
+		char         binary_file_name[1024];
+		size_t       length;
+		cl_int       binary_status;
+
+		opencl_programs->programs[dev] = NULL;
+
+                starpu_opencl_get_device(dev, &device);
+                starpu_opencl_get_context(dev, &context);
+                if (context == NULL)
+		{
+                        _STARPU_DEBUG("[%d] is not a valid OpenCL context\n", dev);
+                        continue;
+                }
+
+		// Load the binary buffer
+		err = _starpu_opencl_get_binary_name(binary_file_name, 1024, kernel_id, dev, device);
+		if (err != CL_SUCCESS) STARPU_OPENCL_REPORT_ERROR(err);
+		binary = _starpu_opencl_load_program_source(binary_file_name);
+		length = strlen(binary);
+
+                // Create the compute program from the binary buffer
+                program = clCreateProgramWithBinary(context, 1, &device, &length, (const unsigned char **) &binary, &binary_status, &err);
+                if (!program || err != CL_SUCCESS) {
+			_STARPU_DISP("Error: Failed to load program binary!\n");
+			return EXIT_FAILURE;
+		}
+
+                // Build the program executable
+                err = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
+
+		// Get the status
+		{
+		     cl_build_status status;
+		     size_t len;
+		     static char buffer[4096] = "";
+
+		     clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len);
+		     if (len > 2)
+			  _STARPU_DISP("Compilation output\n%s\n", buffer);
+
+		     clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_STATUS, sizeof(status), &status, NULL);
+		     if (err != CL_SUCCESS || status != CL_BUILD_SUCCESS)
+		     {
+			  _STARPU_DISP("Error: Failed to build program executable!\n");
+			  _STARPU_DISP("clBuildProgram: %d - clGetProgramBuildInfo: %d\n", err, status);
+			  return EXIT_FAILURE;
+		     }
+
+		}
+
+                // Store program
+		opencl_programs->programs[dev] = program;
+	}
+	return 0;
+}
+
 int starpu_opencl_unload_opencl(struct starpu_opencl_program *opencl_programs)
 {
         unsigned int dev;