| 
					
				 | 
			
			
				@@ -26,6 +26,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <starpu_opencl.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <starpu_profiling.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <core/workers.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <common/utils.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "driver_opencl_utils.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "driver_opencl.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -164,8 +165,83 @@ char *_starpu_opencl_load_program_source(const char *filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return source; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-int starpu_opencl_load_opencl_from_string(const char *opencl_program_source, struct starpu_opencl_program *opencl_programs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					  const char* build_options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+char *_starpu_opencl_load_program_binary(const char *filename, size_t *len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct stat statbuf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	FILE        *fh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	char        *binary; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	fh = fopen(filename, "r"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (fh == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	stat(filename, &statbuf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	binary = (char *) malloc(statbuf.st_size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!binary) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return binary; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	fread(binary, statbuf.st_size, 1, fh); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*len = statbuf.st_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return binary; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void _starpu_opencl_create_binary_directory(char *path, size_t maxlen) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	static int _directory_created = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	snprintf(path, maxlen, "%s/.starpu/opencl/", _starpu_get_home_path()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (_directory_created == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		_STARPU_DEBUG("Creating directory %s\n", path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		_starpu_mkpath_and_check(path, S_IRWXU); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		_directory_created = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+char *_starpu_opencl_get_device_type_as_string(int id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cl_device_type type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	type = _starpu_opencl_get_device_type(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case CL_DEVICE_TYPE_GPU: return "gpu"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case CL_DEVICE_TYPE_ACCELERATOR: return "acc"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case CL_DEVICE_TYPE_CPU: return "cpu"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: return "unk"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int _starpu_opencl_get_binary_name(char *binary_file_name, size_t maxlen, const char *source_file_name, int dev, cl_device_id device) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	char binary_directory[1024]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	char *p; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cl_int err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cl_uint vendor_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_starpu_opencl_create_binary_directory(binary_directory, 1024); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	p = strrchr(source_file_name, '/'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	snprintf(binary_file_name, maxlen, "%s/%s", binary_directory, p?p:source_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	p = strstr(binary_file_name, ".cl"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (p == NULL) p=binary_file_name + strlen(binary_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	err = clGetDeviceInfo(device, CL_DEVICE_VENDOR_ID, sizeof(vendor_id), &vendor_id, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (err != CL_SUCCESS) STARPU_OPENCL_REPORT_ERROR(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sprintf(p, ".%s.vendor_id_%d_device_id_%d", _starpu_opencl_get_device_type_as_string(dev), (int)vendor_id, dev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return CL_SUCCESS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int _starpu_opencl_compile_or_load_opencl_from_string(const char *opencl_program_source, const char* build_options, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						      struct starpu_opencl_program *opencl_programs, const char* source_file_name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         unsigned int dev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         unsigned int nb_devices; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -179,7 +255,8 @@ int starpu_opencl_load_opencl_from_string(const char *opencl_program_source, str 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 cl_program   program; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 cl_int       err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                opencl_programs->programs[dev] = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (opencl_programs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			opencl_programs->programs[dev] = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 starpu_opencl_get_device(dev, &device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 starpu_opencl_get_context(dev, &context); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -220,32 +297,69 @@ int starpu_opencl_load_opencl_from_string(const char *opencl_program_source, str 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // Store program 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                opencl_programs->programs[dev] = program; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (opencl_programs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			opencl_programs->programs[dev] = program; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			char binary_file_name[1024]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			char *binary; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			size_t binary_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			FILE *fh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			err = _starpu_opencl_get_binary_name(binary_file_name, 1024, source_file_name, dev, device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (err != CL_SUCCESS) STARPU_OPENCL_REPORT_ERROR(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			err = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binary_len, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (err != CL_SUCCESS) STARPU_OPENCL_REPORT_ERROR(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			binary = malloc(binary_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			err = clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(binary), &binary, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (err != CL_SUCCESS) STARPU_OPENCL_REPORT_ERROR(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			fh = fopen(binary_file_name, "w"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (fh == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				_STARPU_DISP("Error: Failed to open file <%s>\n", binary_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				perror("fopen"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return EXIT_FAILURE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			fwrite(binary, binary_len, 1, fh); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			fclose(fh); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			free(binary); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			_STARPU_DEBUG("File <%s> created\n", binary_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return EXIT_SUCCESS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-int starpu_opencl_load_opencl_from_file(const char *source_file_name, struct starpu_opencl_program *opencl_programs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const char* build_options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void starpu_opencl_load_program_source(const char *source_file_name, char *located_file_name, char *located_dir_name, char *opencl_program_source) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Locate source file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        _starpu_opencl_locate_file(source_file_name, located_file_name, located_dir_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        _STARPU_DEBUG("Source file name : <%s>\n", located_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        _STARPU_DEBUG("Source directory name : <%s>\n", located_dir_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Load the compute program from disk into a char * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        char *source = _starpu_opencl_load_program_source(located_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!source) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _STARPU_ERROR("Failed to load compute program from file <%s>!\n", located_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sprintf(opencl_program_source, "%s", source); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int _starpu_opencl_compile_or_load_opencl_from_file(const char *source_file_name, struct starpu_opencl_program *opencl_programs, const char* build_options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int nb_devices; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         char located_file_name[1024]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         char located_dir_name[1024]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	char new_build_options[1024]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	char opencl_program_source[16384]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// Do not try to load and compile the file if there is no devices 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	nb_devices = starpu_opencl_worker_get_count(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (nb_devices == 0) return EXIT_SUCCESS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Locate source file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _starpu_opencl_locate_file(source_file_name, located_file_name, located_dir_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _STARPU_DEBUG("Source file name : <%s>\n", located_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _STARPU_DEBUG("Source directory name : <%s>\n", located_dir_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Load the compute program from disk into a cstring buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        char *opencl_program_source = _starpu_opencl_load_program_source(located_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(!opencl_program_source) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _STARPU_ERROR("Failed to load compute program from file <%s>!\n", located_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	starpu_opencl_load_program_source(source_file_name, located_file_name, located_dir_name, opencl_program_source); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!strcmp(located_dir_name, "")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		strcpy(new_build_options, build_options); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -255,7 +369,98 @@ int starpu_opencl_load_opencl_from_file(const char *source_file_name, struct sta 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		sprintf(new_build_options, "-I %s", located_dir_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	_STARPU_DEBUG("Build options: <%s>\n", new_build_options); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return starpu_opencl_load_opencl_from_string(opencl_program_source, opencl_programs, new_build_options); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return _starpu_opencl_compile_or_load_opencl_from_string(opencl_program_source, new_build_options, opencl_programs, source_file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_opencl_compile_opencl_from_file(const char *source_file_name, const char* build_options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return _starpu_opencl_compile_or_load_opencl_from_file(source_file_name, NULL, build_options); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_opencl_compile_opencl_from_string(const char *opencl_program_source, const char *file_name, const char* build_options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return _starpu_opencl_compile_or_load_opencl_from_string(opencl_program_source, build_options, NULL, file_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_opencl_load_opencl_from_string(const char *opencl_program_source, struct starpu_opencl_program *opencl_programs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					  const char* build_options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return _starpu_opencl_compile_or_load_opencl_from_string(opencl_program_source, build_options, opencl_programs, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int starpu_opencl_load_opencl_from_file(const char *source_file_name, struct starpu_opencl_program *opencl_programs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					const char* build_options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	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_binary(binary_file_name, &length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 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) 
			 |