Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 19 Dec 2012 15:01:00 -0200
From: Claudio André <claudioandre.br@...il.com>
To: john-dev@...ts.openwall.com
Subject: Re: Opencl build from binary

Em 18-12-2012 17:39, magnum escreveu:
> From a quick look at opencl_cryptsha512_fmt.c in your repo, I wonder 
> why you didn't make more of it shared? The format could just call 
> opencl_build_kernel() and the common code could use the binary if 
> available, transparent to the format. However, I guess we need some 
> kind of version-control. Or is there already? I didn't look very 
> closely. It could be like

I tried to do something not invasive in common-opencl. Now one (only if 
he wants to use new functionality) have to change source code:

From:
opencl_init("$JOHN/cryptmd5_kernel.cl", ocl_gpu_id, platform_id);

To:
opencl_init_dev(ocl_gpu_id, platform_id);
opencl_build_kernel_save("$JOHN/cryptmd5_kernel.cl", ocl_gpu_id, 
magumOptions=NULL, saveBinary=1, warnAboutCompilation=1);

BTW: If needed/wanted, it is easy to create a new function opencl_init_save.


> if (no binary) OR (timestamp of source is newer than timestamp of binary)
> 	build [and write/overwrite binary]
> else
> 	use binary
>
> Or is that too simple? I can't think of any problems with that.

Implemented this way. Depending on how many GPUs someone have, one file 
for each device name.

Attached and diff here: 
https://github.com/magnumripper/JohnTheRipper/pull/135/files

Claudio


[ CONTENT OF TYPE text/html SKIPPED ]

>>From e836562568e8ffca023f866a5d06500ecb6ca65d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Claudio=20Andr=C3=A9?= <claudio.andre@...reios.net.br>
Date: Wed, 19 Dec 2012 14:36:19 -0200
Subject: [PATCH 3/3] Shared code to allow to build and use binary OpenCL
 kernels.

---
 src/common-opencl.c |  121 ++++++++++++++++++++++++++++++++++++++-------------
 src/common-opencl.h |    2 +
 2 files changed, 93 insertions(+), 30 deletions(-)

diff --git a/src/common-opencl.c b/src/common-opencl.c
index eb6fadc..77c2f19 100644
--- a/src/common-opencl.c
+++ b/src/common-opencl.c
@@ -4,6 +4,9 @@
 #include <assert.h>
 #include <string.h>
 #include <ctype.h>
+#include <sys/stat.h>
+#include <time.h>
+
 #define LOG_SIZE 1024*16
 
 static char opencl_log[LOG_SIZE];
@@ -121,7 +124,7 @@ static char *include_source(char *pathname, int dev_id, char *options)
 	return include;
 }
 
-static void build_kernel(int dev_id, char *options)
+static void build_kernel(int dev_id, char *options, int save, char * file_name)
 {
 	cl_int build_code;
         char * build_log; size_t log_size;
@@ -156,28 +159,34 @@ static void build_kernel(int dev_id, char *options)
 		fprintf(stderr, "Compilation log: %s\n", build_log);
 #endif
         MEM_FREE(build_log);
-#if 0
-	FILE *file;
-	size_t source_size;
-	char *source;
-
-	HANDLE_CLERROR(clGetProgramInfo(program[dev_id],
-		CL_PROGRAM_BINARY_SIZES,
-		sizeof(size_t), &source_size, NULL), "error");
-	fprintf(stderr, "source size %zu\n", source_size);
-	source = malloc(source_size);
-
-	HANDLE_CLERROR(clGetProgramInfo(program[dev_id],
-		CL_PROGRAM_BINARIES, sizeof(char *), &source, NULL), "error");
-
-	file = fopen("program.bin", "w");
-	if (file == NULL)
-		fprintf(stderr, "Error opening binary file\n");
-	else if (fwrite(source, source_size, 1, file) != 1)
-		fprintf(stderr, "error writing binary\n");
-	fclose(file);
-	MEM_FREE(source);
+
+	if (save) {
+		FILE *file;
+		size_t source_size;
+		char *source;
+
+		HANDLE_CLERROR(clGetProgramInfo(program[dev_id],
+			CL_PROGRAM_BINARY_SIZES,
+			sizeof(size_t), &source_size, NULL), "error");
+#if DEBUG
+		fprintf(stderr, "source size %zu\n", source_size);
 #endif
+		source = malloc(source_size);
+
+		HANDLE_CLERROR(clGetProgramInfo(program[dev_id],
+			CL_PROGRAM_BINARIES, sizeof(char *), &source, NULL), "error");
+
+		file = fopen(path_expand(file_name), "w");
+
+		if (file == NULL)
+			fprintf(stderr, "Error creating binary file %s\n", file_name);
+		else {
+			if (fwrite(source, source_size, 1, file) != 1)
+				fprintf(stderr, "error writing binary\n");
+			fclose(file);
+		}
+		MEM_FREE(source);
+	}
 }
 
 static void build_kernel_from_binary(int dev_id)

 
@@ -456,7 +470,7 @@ void opencl_init_dev(unsigned int dev_id, unsigned int platform_id)
 void opencl_build_kernel_opt(char *kernel_filename, unsigned int dev_id, char *options)
 {
 	read_kernel_source(kernel_filename);
-	build_kernel(dev_id, options);
+	build_kernel(dev_id, options, 0, NULL);
 }
 
 void opencl_build_kernel(char *kernel_filename, unsigned int dev_id)
@@ -465,6 +479,53 @@ void opencl_build_kernel(char *kernel_filename, unsigned int dev_id)
 	opencl_build_kernel_opt(kernel_filename, dev_id, NULL);
 }
 
+//Only AMD gpu code will benefit from this routine.
+void opencl_build_kernel_save(char *kernel_filename, unsigned int dev_id, char *options, int save, int warn) {
+	struct stat source_stat, bin_stat;
+	char dev_name[128], bin_name[128];
+	char * p;
+	uint64_t startTime, runtime;
+
+	kernel_loaded = 0;
+
+	if (!gpu_amd(device_info[ocl_gpu_id]) || !save || stat(path_expand(kernel_filename), &source_stat))
+		opencl_build_kernel_opt(kernel_filename, dev_id, options);
+
+	else {
+		startTime = (unsigned long) time(NULL);
+
+		//Get device name.
+		HANDLE_CLERROR(clGetDeviceInfo(devices[ocl_gpu_id], CL_DEVICE_NAME,
+			sizeof (dev_name), dev_name, NULL), "Error querying DEVICE_NAME");
+
+		//Decide the binary name.
+		p = strstr(kernel_filename, ".cl");
+		strncpy(bin_name, kernel_filename, (p - kernel_filename));
+		sprintf(bin_name, "%s_%s.bin", bin_name, dev_name);
+
+		//Select the kernel to run.
+		if (!stat(path_expand(bin_name), &bin_stat) && (source_stat.st_mtime < bin_stat.st_mtime)) {
+			read_kernel_source(bin_name);
+			build_kernel_from_binary(dev_id);
+
+		} else {
+
+			if (warn) {
+				fprintf(stderr, "Building the kernel, this could take a while\n");
+				fflush(stdout);
+			}
+			read_kernel_source(kernel_filename);
+			build_kernel(dev_id, options, 1, bin_name);
+
+			if (warn) {
+				if ((runtime = (unsigned long) (time(NULL) - startTime)) > 2UL)
+					fprintf(stderr, "Elapsed time: %lu seconds\n", runtime);
+				fflush(stdout);
+			}
+		}
+	}
+}
+
 void opencl_build_kernel_from_binary(char *kernel_filename, unsigned int dev_id)
 {
 	read_kernel_source(kernel_filename);
diff --git a/src/common-opencl.h b/src/common-opencl.h
index f143929..e15451d 100644
--- a/src/common-opencl.h
+++ b/src/common-opencl.h
@@ -58,6 +58,8 @@ void opencl_init_opt(char *kernel_filename, unsigned int dev_id,
 void opencl_init_from_binary(char *kernel_filename, unsigned int dev_id,
                  unsigned int platform_id);
 void opencl_build_kernel(char *kernel_filename, unsigned int dev_id);
+void opencl_build_kernel_from_binary(char *kernel_filename, unsigned int dev_id);
+void opencl_build_kernel_save(char *kernel_filename, unsigned int dev_id, char *options, int save, int warn);
 void opencl_find_best_workgroup(struct fmt_main *self);
 void opencl_find_best_workgroup_limit(struct fmt_main *self, size_t group_size_limit);
 
-- 
1.7.9.5



Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ