Initial commit
[hashcat.git] / tools / clcompile / clcompile.c
1 /**
2 * Author......: Jens Steube <jens.steube@gmail.com>
3 * License.....: MIT
4 */
5
6 #include <errno.h>
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14 #include <CL/cl.h>
15
16 #define CL_PLATFORMS_MAX 128
17 #define CL_DEVICES_MAX 128
18
19 //char options[] = "–x spir -spir-std=1.2 -I.";
20 char options[] = "-I. -x clc++ -cl-std=CL1.2";
21
22 static void checkErr (char *func, cl_int err)
23 {
24 if (err != CL_SUCCESS)
25 {
26 fprintf (stderr, "%s(): ", func);
27
28 switch (err)
29 {
30 case CL_BUILD_PROGRAM_FAILURE :
31 fprintf (stderr, "CL_BUILD_PROGRAM_FAILURE");
32 break;
33
34 case CL_COMPILER_NOT_AVAILABLE :
35 fprintf (stderr, "CL_COMPILER_NOT_AVAILABLE");
36 break;
37
38 case CL_DEVICE_NOT_AVAILABLE :
39 fprintf (stderr, "CL_DEVICE_NOT_AVAILABLE");
40 break;
41
42 case CL_DEVICE_NOT_FOUND :
43 fprintf (stderr, "CL_DEVICE_NOT_FOUND");
44 break;
45
46 case CL_INVALID_BINARY :
47 fprintf (stderr, "CL_INVALID_BINARY");
48 break;
49
50 case CL_INVALID_BUILD_OPTIONS :
51 fprintf (stderr, "CL_INVALID_BUILD_OPTIONS");
52 break;
53
54 case CL_INVALID_CONTEXT :
55 fprintf (stderr, "CL_INVALID_CONTEXT");
56 break;
57
58 case CL_INVALID_DEVICE :
59 fprintf (stderr, "CL_INVALID_DEVICE");
60 break;
61
62 case CL_INVALID_DEVICE_TYPE :
63 fprintf (stderr, "CL_INVALID_DEVICE_TYPE");
64 break;
65
66 case CL_INVALID_OPERATION :
67 fprintf (stderr, "CL_INVALID_OPERATION");
68 break;
69
70 case CL_INVALID_PLATFORM :
71 fprintf (stderr, "CL_INVALID_PLATFORM");
72 break;
73
74 case CL_INVALID_PROGRAM :
75 fprintf (stderr, "CL_INVALID_PROGRAM");
76 break;
77
78 case CL_INVALID_VALUE :
79 fprintf (stderr, "CL_INVALID_VALUE");
80 break;
81
82 case CL_OUT_OF_HOST_MEMORY :
83 fprintf (stderr, "CL_OUT_OF_HOST_MEMORY");
84 break;
85
86 default :
87 fprintf (stderr, "Unknown error code: %d", err);
88 break;
89 }
90
91 fprintf (stderr, "\n");
92
93 exit (err);
94 }
95 }
96
97 static char *load_kernel (const char *kernel_file)
98 {
99 FILE *fp = NULL;
100
101 if ((fp = fopen (kernel_file, "rb")) != NULL)
102 {
103 struct stat st;
104
105 if (stat (kernel_file, &st) == -1)
106 {
107 fprintf (stderr, "! stat() failed (%d) : %s\n", errno, strerror (errno));
108 }
109
110 char *buf = (char *) malloc (st.st_size + 1);
111
112 memset (buf, 0, st.st_size + 1);
113
114 size_t num_read = fread (buf, sizeof (char), st.st_size, fp);
115
116 if (num_read != (size_t) st.st_size)
117 {
118 fprintf (stderr, "! fread() [%s] failed (%d) : %s", kernel_file, errno, strerror (errno));
119 fclose (fp);
120 exit (-1);
121 }
122
123 fclose (fp);
124
125 return buf;
126 }
127 else
128 {
129 fprintf (stderr, "! fopen() [%s] failed (%d) : %s", kernel_file, errno, strerror (errno));
130 exit (-1);
131 }
132
133 return NULL;
134 }
135
136 static int writeProgramBins (char *dst, unsigned char *binary, size_t binary_size)
137 {
138 FILE *fp = fopen (dst, "wb");
139
140 if (!fp)
141 {
142 fprintf(stderr, "! fopen() [%s] failed (%d) : %s\n", dst, errno, strerror (errno));
143 return -1;
144 }
145
146 if (fwrite (binary, sizeof (unsigned char), binary_size, fp) != binary_size)
147 {
148 fprintf(stderr, "! fwrite() [%s] failed (%d) : %s\n", dst, errno, strerror (errno));
149 fclose (fp);
150 return -1;
151 }
152
153 fclose (fp);
154
155 return 0;
156 }
157
158 int main (int argc, char *argv[])
159 {
160 if (argc != 4)
161 {
162 fprintf (stderr, "> Usage: %s ccopts src dst\n", argv[0]);
163
164 return (-1);
165 }
166
167 char *ccopts = argv[1];
168 char *src = argv[2];
169 char *dst = argv[3];
170
171 char *programSrc = load_kernel (src);
172
173 if (programSrc == NULL)
174 {
175 fprintf (stderr, "Unable to open %s. Exiting.\n", src);
176
177 return (-1);
178 }
179
180 cl_device_id devices[1];
181 cl_uint nDevices;
182
183 cl_platform_id platform;
184 cl_uint platforms;
185
186 cl_int err;
187
188 err = clGetPlatformIDs(1, &platform, &platforms);
189
190 checkErr ((char *) "clGetPlatformIDs", err);
191
192 err = clGetDeviceIDs (platform, CL_DEVICE_TYPE_GPU, 1, devices, &nDevices);
193
194 checkErr ((char *) "clGetDeviceIDs", err);
195
196 cl_context context = clCreateContext (NULL, 1, devices, NULL, NULL, &err);
197
198 checkErr ((char *) "clCreateContext", err);
199
200 cl_program program = clCreateProgramWithSource (context, 1, (const char **) &programSrc, NULL, &err);
201
202 checkErr ((char *) "clCreateProgramWithSource", err);
203
204 size_t opt_len = strlen (ccopts) + 1 + strlen (options) + 1;
205
206 char *options2 = (char *) malloc (opt_len + 1);
207
208 memset (options2, 0, opt_len + 1);
209
210 snprintf (options2, opt_len, "%s %s", options, ccopts);
211
212 err = clCompileProgram (program, 1, devices, options2, 0, NULL, NULL, NULL, NULL);
213
214 //checkErr ((char *) "clCompileProgram", err);
215
216 size_t ret_val_size = 0;
217
218 err = clGetProgramBuildInfo (program, devices[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
219
220 checkErr ((char *) "clGetProgramBuildInfo", err);
221
222 if (ret_val_size > 1)
223 {
224 char *build_log = (char *) malloc (ret_val_size + 1);
225
226 memset (build_log, 0, ret_val_size + 1);
227
228 err = clGetProgramBuildInfo (program, devices[0], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
229
230 checkErr ((char *) "clGetProgramBuildInfo", err);
231
232 puts (build_log);
233 }
234
235 size_t binary_size;
236
237 err = clGetProgramInfo (program, CL_PROGRAM_BINARY_SIZES, sizeof (size_t), &binary_size, NULL);
238
239 checkErr ((char *) "clGetProgramInfo", err);
240
241 unsigned char *binary = (unsigned char *) malloc (binary_size);
242
243 memset(binary, 0, binary_size);
244
245 err = clGetProgramInfo (program, CL_PROGRAM_BINARIES, sizeof (binary), &binary, NULL);
246
247 checkErr ((char *) "clGetProgramInfo", err);
248
249 err = writeProgramBins (dst, binary, binary_size);
250
251 checkErr ((char *) "writeProgramBins", err);
252
253 return 0;
254 }