assertOpenCL  September 19, 2018
example.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # -*- coding: latin-1 -*-
3 
4 """
5 Simple Python (2 and 3) example
6 to show how run a kernel with assert*() and PRINT*() macros
7 and test them.
8 
9 Piece of assertOpenCL
10 
11 :license: GPLv3 --- Copyright (C) 2018 Olivier Pirson
12 :author: Olivier Pirson --- http://www.opimedia.be/
13 :version: September 19, 2018
14 """
15 
16 from __future__ import division
17 from __future__ import print_function
18 
19 import os.path
20 import sys
21 
22 import numpy as np
23 import pyopencl as cl # https://mathema.tician.de/software/pyopencl/
24 
25 
26 def get_device(platform_i, device_i):
27  """
28  Return the given device of the given platform OpenCL.
29 
30  :param platform_i: int >= 0
31  :param device_i: int >= 0
32 
33  :return: None or OpenCL device
34  """
35  assert isinstance(platform_i, int), type(platform_i)
36  assert platform_i >= 0, platform_i
37 
38  assert isinstance(device_i, int), type(device_i)
39  assert device_i >= 0, device_i
40 
41  platforms = cl.get_platforms()
42  if platform_i >= len(platforms):
43  return None
44 
45  devices = platforms[platform_i].get_devices()
46  if device_i >= len(devices):
47  return None
48 
49  return devices[device_i]
50 
51 
52 def run_example(nb_work_group, nb_work_items_by_work_group,
53  device=None, debug=__debug__):
54  """
55  Run the kernel ../kernel/example.cl.
56 
57  If device is None
58  then use the default device,
59  else use device.
60 
61  If debug
62  then run the kernel in debug mode,
63  else run the kernel with the macro NDEBUG defined.
64 
65  :param nb_work_group: int > 0
66  :param nb_work_items_by_work_group: int > 0
67  :param device: None or OpenCL device
68  :param debug: bool
69  """
70  assert isinstance(nb_work_group, int), type(nb_work_group)
71  assert nb_work_group > 0, nb_work_group
72 
73  assert isinstance(nb_work_items_by_work_group, int), \
74  type(nb_work_items_by_work_group)
75  assert nb_work_items_by_work_group > 0, nb_work_items_by_work_group
76 
77  assert isinstance(debug, bool), type(debug)
78 
79  # Host buffer
80  h_outs = np.empty(2).astype(np.uint32)
81 
82  # OpenCL context
83  context = (cl.create_some_context() if device is None
84  else cl.Context((device, )))
85 
86  # OpenCL kernel
87  path = os.path.dirname(__file__)
88  options = ['-I', os.path.join(path, '../../OpenCL/')]
89  if debug:
90  print('OpenCL in DEBUG mode!', file=sys.stderr)
91  sys.stderr.flush()
92  else: # transmits NDEBUG macro to kernel
93  options.extend(('-D', 'NDEBUG'))
94 
95  kernel_filename = os.path.join(path, '../kernel/example.cl')
96  kernel_src = ('#line 1 "{}"\n{}'
97  .format(kernel_filename,
98  open(os.path.join(path, '../kernel/example.cl'))
99  .read()))
100  program = cl.Program(context, kernel_src).build(options=options)
101 
102  # OpenCL queue
103  queue = cl.CommandQueue(context,
104  properties=cl.command_queue_properties
105  .PROFILING_ENABLE)
106 
107  # OpenCL buffer
108  mf = cl.mem_flags
109  d_outs = cl.Buffer(context, mf.WRITE_ONLY | mf.COPY_HOST_PTR,
110  hostbuf=h_outs)
111 
112  # Params
113  type_params = [np.uint32, None]
114  params = [666, d_outs] # just two parameters for the example
115  if debug: # add extra parameters to receive assertion information
116  h_asserts = np.zeros(2).astype(np.uint64)
117  h_assert_float = np.zeros(1).astype(np.float32)
118 
119  d_asserts = cl.Buffer(context, mf.READ_WRITE | mf.COPY_HOST_PTR,
120  hostbuf=h_asserts)
121  d_assert_float = cl.Buffer(context, mf.READ_WRITE | mf.COPY_HOST_PTR,
122  hostbuf=h_assert_float)
123 
124  type_params.extend((None, None))
125  params.extend((d_asserts, d_assert_float))
126 
127  # Run
128  global_size = nb_work_items_by_work_group * nb_work_group
129  kernel_f = program.example
130  kernel_f.set_scalar_arg_dtypes(type_params)
131  print('===== run kernel =====')
132  sys.stdout.flush()
133 
134  kernel_f(queue, (global_size, ), (nb_work_items_by_work_group, ), *params)
135 
136  queue.finish()
137  queue.flush()
138  sys.stdout.flush()
139  sys.stderr.flush()
140  print('===== end kernel =====')
141  sys.stdout.flush()
142 
143  # Results
144  cl.enqueue_copy(queue, h_outs, d_outs)
145 
146  if debug: # get assertion information
147  cl.enqueue_copy(queue, h_asserts, d_asserts)
148  cl.enqueue_copy(queue, h_assert_float, d_assert_float)
149 
150  line = int(h_asserts[0])
151  if line != 0: # there had (at least) an assertion
152  uint64_value = int(h_asserts[1])
153  sint64_value = int(h_asserts[1].astype(np.int64))
154  float_value = float(h_assert_float[0])
155  print('{}:{}\tAssertion failed | Maybe\t{}\t{} | Maybe\t{}'
156  .format(kernel_filename, line,
157  uint64_value, sint64_value,
158  float_value),
159  file=sys.stderr)
160  # Maybe incoherent assert information
161  # because the parallel execution of work items.
162  # But each element of these information
163  # concern assertion(s) that failed.
164  sys.stderr.flush()
165 
166  print('Results:', tuple(h_outs))
167 
168 
169 ########
170 # Main #
171 ########
172 def main():
173  """
174  Get the optional parameter --device platform:device
175  and run the kernel ../kernel/example.cl
176  """
177  debug = __debug__
178  device = None
179 
180  # Read parameters
181  i = 1
182  while i < len(sys.argv):
183  arg = sys.argv[i]
184  if (arg == '--debug') or (arg == '--ndebug'):
185  debug = (arg == '--debug')
186  elif arg == '--device':
187  i += 1
188  try:
189  both_i = [arg for arg in sys.argv[i].split(':')]
190  platform_i = int(both_i[0])
191  device_i = (int(both_i[1]) if len(both_i) >= 2
192  else 0)
193  if ((platform_i >= 0) and (device_i >= 0) and
194  (len(both_i) <= 2)):
195  device = get_device(platform_i, device_i)
196  else:
197  exit(1)
198  except (IndexError, ValueError):
199  exit(1)
200 
201  i += 1
202 
203  # Print wanted device
204  if device is None:
205  print('Device default')
206  else:
207  print('Device {}:{} {}'.format(platform_i, device_i, device.name))
208  sys.stdout.flush()
209 
210  # Run
211  run_example(3, 4, device=device, debug=debug)
212 
213 if __name__ == '__main__':
214  main()
def run_example(nb_work_group, nb_work_items_by_work_group, device=None, debug=__debug__)
Definition: example.py:53
def get_device(platform_i, device_i)
Definition: example.py:26
def main()
Main #.
Definition: example.py:172