assertOpenCL  September 19, 2018
Example.java
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 /** \file examples/Java/Example.java
3  * \brief
4  * Simple Java (at least since Java 1.8) example
5  * to show how run a kernel with assert*() and PRINT*() macros
6  * and test them.
7  *
8  * Piece of assertOpenCL
9  * --- GPLv3 --- Copyright (C) 2018 Olivier Pirson
10  * --- http://www.opimedia.be/
11  * --- September 19, 2018
12  */
13 
14 import java.math.BigInteger;
15 
16 import java.nio.file.Files;
17 import java.nio.file.Paths;
18 
19 
20 import static org.jocl.CL.*; // http://www.jocl.org/
21 
22 import org.jocl.*;
23 
24 
25 
26 /** \brief
27  * Simple Java example to show how run a kernel with assert*() and PRINT*() macros
28  * and test them.
29  */
30 public class Example {
31 
32  /** \brief Number of bytes for the float type. */
33  static final int FLOAT_FIELD_SIZE = 4;
34 
35  /** \brief Number of bytes for the int type. */
36  static final int INT_FIELD_SIZE = 4;
37 
38  /** \brief Number of bytes for the long type. */
39  static final int LONG_FIELD_SIZE = 8;
40 
41  static {
42  assert Float.BYTES == FLOAT_FIELD_SIZE;
43  assert Integer.BYTES == INT_FIELD_SIZE;
44  assert Long.BYTES == LONG_FIELD_SIZE;
45 
46  assert Sizeof.cl_float == FLOAT_FIELD_SIZE;
47  assert Sizeof.cl_int == INT_FIELD_SIZE;
48  assert Sizeof.cl_long == LONG_FIELD_SIZE;
49  }
50 
51 
52 
53  /** \brief
54  * True iff assertions are enabled.
55  */
56  private static boolean assertsEnabled = false;
57 
58  static {
59  assert assertsEnabled = true; // intentional side-effect
60  }
61 
62 
63 
64  /** \brief
65  * Read the file and return its content to a string.
66  * If failed then throw an exception.
67  */
68  static String fileToString(final String filename) throws Exception {
69  return ("#line 1 \"" + filename + "\"\n"
70  + new String(Files.readAllBytes(Paths.get(filename))));
71  }
72 
73 
74  /** \brief
75  * Return the given id device of the given platform OpenCL,
76  * or exit if doesn't exists.
77  */
78  static cl_device_id getDeviceId(int platformI, int deviceI) throws Exception {
79  assert platformI >= 0;
80  assert deviceI >= 0;
81 
82  // Get number of platforms
83  final int[] platformNbArray = new int[1];
84 
85  clGetPlatformIDs(0, null, platformNbArray);
86 
87  final int platformNb = platformNbArray[0];
88 
89  if (platformI >= platformNb) {
90  throw new Exception("Wrong platformI: " + platformI);
91  }
92 
93  // Get all platform ids
94  final cl_platform_id[] platformIds = new cl_platform_id[platformNb];
95 
96  clGetPlatformIDs(platformIds.length, platformIds, null);
97 
98  // The wanted platform
99  final cl_platform_id platformId = platformIds[platformI];
100 
101  // Get number of devices for the wanted platform
102  final int[] deviceNbArray = new int[1];
103 
104  clGetDeviceIDs(platformId, CL_DEVICE_TYPE_ALL, 0, null, deviceNbArray);
105 
106  final int deviceNb = deviceNbArray[0];
107 
108  if (deviceI >= deviceNb) {
109  throw new Exception("Wrong deviceI: " + deviceI);
110  }
111 
112  // Get all device ids for the wanted platform
113  final cl_device_id[] deviceIds = new cl_device_id[deviceNb];
114 
115  clGetDeviceIDs(platformId, CL_DEVICE_TYPE_ALL, deviceNb, deviceIds, null);
116 
117  // The wanted device
118  return deviceIds[deviceI];
119  }
120 
121 
122  /** \brief
123  * Return a string corresponding to device info parameter.
124  */
125  static String getDeviceInfoString(cl_device_id deviceId, int paramName) {
126  // Get length of result
127  final long[] size = new long[1];
128 
129  clGetDeviceInfo(deviceId, paramName, 0, null, size);
130 
131  // Get the wanted string
132  final byte[] buffer = new byte[(int) size[0]];
133 
134  clGetDeviceInfo(deviceId, paramName, buffer.length, Pointer.to(buffer), null);
135 
136  return new String(buffer, 0, buffer.length - 1);
137  }
138 
139 
140  /** \brief
141  * Run the kernel ../kernel/example.cl.
142 
143  * If debug
144  * then run the kernel in debug mode,
145  * else run the kernel with the macro NDEBUG defined.
146  */
147  static void runExample(int nbWorkGroup, int nbWorkItemsByWorkGroup,
148  cl_device_id deviceId, boolean debug) throws Exception {
149  // Host buffer
150  final int[] hOuts = new int[2];
151  final int hOutsByteSize = INT_FIELD_SIZE * 2;
152 
153  final long[] hAsserts = {0, 0};
154  final int hAssertsByteSize = LONG_FIELD_SIZE * 2;
155 
156  final float[] hAssertFloat = {0};
157  final int hAssertFloatByteSize = FLOAT_FIELD_SIZE;
158 
159 
160  // OpenCL context
161  final cl_device_id[] devicesIds = new cl_device_id[]{deviceId};
162  final cl_context context = clCreateContext(null, 1, devicesIds, null, null, null);
163 
164 
165  // OpenCL kernel
166  String options = "-I../../OpenCL/";
167 
168  if (debug) {
169  System.err.println("OpenCL in DEBUG mode!");
170  System.err.flush();
171  } else {
172  options += " -DNDEBUG";
173  }
174 
175  final String kernelFilename = "../kernel/example.cl";
176  final String kernelSrc = fileToString(kernelFilename);
177  final cl_program program = clCreateProgramWithSource(context,
178  1, new String[]{kernelSrc},
179  null, null);
180 
181  clBuildProgram(program, 1, devicesIds, options, null, null);
182 
183  final cl_kernel kernel = clCreateKernel(program, "example", null);
184 
185 
186  // OpenCL queue
187  final cl_command_queue queue = clCreateCommandQueue(context, deviceId,
188  CL_QUEUE_PROFILING_ENABLE, null);
189 
190 
191  // OpenCL buffers
192  final cl_mem dOuts = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
193  hOutsByteSize, Pointer.to(hOuts), null);
194 
195  cl_mem dAsserts = null;
196  cl_mem dAssertFloat = null;
197 
198  if (debug) {
199  dAsserts = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
200  hAssertsByteSize, Pointer.to(hAsserts), null);
201  dAssertFloat = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
202  hAssertFloatByteSize, Pointer.to(hAssertFloat), null);
203  }
204 
205 
206  // Params: just two parameters for the example
207  clSetKernelArg(kernel, 0, Sizeof.cl_uint, Pointer.to(new int[]{666}));
208  clSetKernelArg(kernel, 1, Sizeof.cl_mem, Pointer.to(dOuts));
209 
210  if (debug) { // extra parameters to receive assertion information
211  final int nbArgs = 2;
212 
213  clSetKernelArg(kernel, nbArgs, Sizeof.cl_mem, Pointer.to(dAsserts));
214  clSetKernelArg(kernel, nbArgs + 1, Sizeof.cl_mem, Pointer.to(dAssertFloat));
215  }
216 
217 
218  // Run
219  final int globalSize = nbWorkItemsByWorkGroup * nbWorkGroup;
220 
221  System.out.println("===== run kernel =====");
222  System.out.flush();
223 
224  clEnqueueNDRangeKernel(queue, kernel,
225  1,
226  null,
227  new long[]{globalSize},
228  new long[]{nbWorkItemsByWorkGroup},
229  0,
230  null,
231  null);
232 
233  clFinish(queue);
234  clFlush(queue);
235  System.out.flush();
236  System.err.flush();
237  System.out.println("===== end kernel =====");
238  System.out.flush();
239 
240 
241  // Results
242  clEnqueueReadBuffer(queue, dOuts, CL_TRUE, 0,
243  hOutsByteSize, Pointer.to(hOuts), 0, null, null);
244 
245  if (debug) {
246  clEnqueueReadBuffer(queue, dAsserts, CL_TRUE, 0,
247  hAssertsByteSize, Pointer.to(hAsserts), 0, null, null);
248  clEnqueueReadBuffer(queue, dAssertFloat, CL_TRUE, 0,
249  hAssertFloatByteSize, Pointer.to(hAssertFloat), 0, null, null);
250 
251  final long line = hAsserts[0];
252 
253  if (line != 0) { // there had (at least) an assertion
254  final BigInteger uint64Value = uint64(hAsserts[1]);
255  final long sint64Value = hAsserts[1];
256  final float floatValue = hAssertFloat[0];
257 
258  System.err.println(String.format("%s:%d\tAssertion failed | Maybe\t%s\t%d | Maybe\t%f",
259  kernelFilename, line,
260  uint64Value, sint64Value, floatValue));
261  /*
262  Maybe incoherent assert information because the parallel execution of work items.
263  But each element of these information concern assertion(s) that failed.
264  */
265  System.err.flush();
266  }
267  }
268 
269  System.out.println(String.format("Results: (%d, %d)", hOuts[0], hOuts[1]));
270 
271 
272  // Free OpenCL resources
273  clReleaseMemObject(dOuts);
274  if (debug) {
275  clReleaseMemObject(dAsserts);
276  clReleaseMemObject(dAssertFloat);
277  }
278 
279  clReleaseCommandQueue(queue);
280  clReleaseProgram(program);
281  clReleaseKernel(kernel);
282  clReleaseContext(context);
283  }
284 
285 
286  /** \brief
287  * Return in a long the value of n considered as an unsigned integer on 32 bits.
288  */
289  static long uint32(int n) {
290  return (n >= 0
291  ? n
292  : 4294967296L + n); // 2^32 + n
293  }
294 
295 
296  /** \brief
297  * Return in a BigInteger the value of n considered as an unsigned integer on 64 bits.
298  */
299  static BigInteger uint64(long n) {
300  final Long longN = n;
301  final BigInteger bigN = new BigInteger(longN.toString());
302 
303  return (n >= 0
304  ? bigN
305  : new BigInteger("18446744073709551616").add(bigN)); // 2^64 + n
306  }
307 
308 
309 
310  /** \brief
311  * Get the optional parameter --device platform:device
312  * and run the kernel ../kernel/example.cl .
313  */
314  public static void main(String[] args) throws Exception {
315  CL.setExceptionsEnabled(true); // enable exceptions when error with OpenCL
316 
317 
318  boolean debug = assertsEnabled;
319  int deviceI = 0;
320  int platformI = 0;
321 
322  // Read parameters
323  {
324  int i = 0;
325 
326  while (i < args.length) {
327  final String arg = args[i];
328 
329  if ("--debug".equals(arg) || "--ndebug".equals(arg)) {
330  debug = "--debug".equals(arg);
331  } else if ("--device".equals(arg)) {
332  ++i;
333 
334  if (i >= args.length) {
335  throw new Exception("Missing parameter");
336  }
337 
338  final String[] bothI = args[i].split(":");
339 
340  platformI = Integer.parseInt(bothI[0]);
341  if (bothI.length >= 2) {
342  deviceI = Integer.parseInt(bothI[1]);
343  }
344 
345  if ((platformI < 0) || (deviceI < 0)) {
346  throw new Exception("Wrong parameter: " + args[i]);
347  }
348  }
349  ++i;
350  }
351  }
352 
353  // Get wanted device
354  final cl_device_id deviceId = getDeviceId(platformI, deviceI);
355 
356  // Get device name and print
357  System.out.println(String.format("Device %d:%d %s",
358  platformI, deviceI,
359  getDeviceInfoString(deviceId, CL_DEVICE_NAME)));
360  System.out.flush();
361 
362  // Run
363  runExample(3, 4, deviceId, debug);
364  }
365 }
static cl_device_id getDeviceId(int platformI, int deviceI)
Return the given id device of the given platform OpenCL, or exit if doesn&#39;t exists.
Definition: Example.java:78
static final int LONG_FIELD_SIZE
Number of bytes for the long type.
Definition: Example.java:39
static final int FLOAT_FIELD_SIZE
Number of bytes for the float type.
Definition: Example.java:33
static boolean assertsEnabled
True iff assertions are enabled.
Definition: Example.java:56
static String fileToString(final String filename)
Read the file and return its content to a string. If failed then throw an exception.
Definition: Example.java:68
static BigInteger uint64(long n)
Return in a BigInteger the value of n considered as an unsigned integer on 64 bits.
Definition: Example.java:299
static final int INT_FIELD_SIZE
Number of bytes for the int type.
Definition: Example.java:36
static String getDeviceInfoString(cl_device_id deviceId, int paramName)
Return a string corresponding to device info parameter.
Definition: Example.java:125
#define assert(test)
If test is true then do nothing. Else init (if they are still null) assert_result and assert_result_f...
Definition: assert.cl:162
static void runExample(int nbWorkGroup, int nbWorkItemsByWorkGroup, cl_device_id deviceId, boolean debug)
Run the kernel ../kernel/example.cl.
Definition: Example.java:147
static long uint32(int n)
Return in a long the value of n considered as an unsigned integer on 32 bits.
Definition: Example.java:289
static void main(String[] args)
Get the optional parameter –device platform:device and run the kernel ../kernel/example.cl .
Definition: Example.java:314
Simple Java example to show how run a kernel with assert*() and PRINT*() macros and test them...
Definition: Example.java:30