1 """Interface with Nvidia CUDA."""
2
3 from __future__ import division
4
5 __copyright__ = "Copyright (C) 2008 Andreas Kloeckner"
6
7 __license__ = """
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see U{http://www.gnu.org/licenses/}.
20 """
21
22
23
24
25 import numpy
26 import numpy.linalg as la
27 from pytools import memoize_method
28
29
30
31
33 dtype = numpy.dtype(dtype)
34 if dtype == numpy.int32:
35 return "int"
36 elif dtype == numpy.uint32:
37 return "unsigned int"
38 elif dtype == numpy.int16:
39 return "short int"
40 elif dtype == numpy.uint16:
41 return "short unsigned int"
42 elif dtype == numpy.int8:
43 return "signed char"
44 elif dtype == numpy.uint8:
45 return "unsigned char"
46 elif dtype == numpy.intp or dtype == numpy.uintp:
47 return "void *"
48 elif dtype == numpy.float32:
49 return "float"
50 elif dtype == numpy.float64:
51 return "double"
52 else:
53 raise ValueError, "unable to map dtype '%s'" % dtype
54
55
56
57
61
63 - def generate(self, with_semicolon=True):
64 tp_lines, tp_decl = self.get_decl_pair()
65 tp_lines = list(tp_lines)
66 for line in tp_lines[:-1]:
67 yield line
68 sc = ";"
69 if not with_semicolon:
70 sc = ""
71 if tp_decl is None:
72 yield "%s%s" % (tp_lines[-1], sc)
73 else:
74 yield "%s %s%s" % (tp_lines[-1], tp_decl, sc)
75
76 - def inline(self, with_semicolon=True):
77 tp_lines, tp_decl = self.get_decl_pair()
78 tp_lines = " ".join(tp_lines)
79 if tp_decl is None:
80 return tp_lines
81 else:
82 return "%s %s" % (tp_lines, tp_decl)
83
84 -class POD(Declarator):
97
100 self.typename = typename
101 self.name = name
102
104 return [self.typename], self.name
105
107 raise RuntimeError, "named-type values can't be put into structs"
108
111
112
113
114
117 self.subdecl = subdecl
118
119 @property
121 return self.subdecl.name
122
125
128
131
136
138 def add_spec(sub_it):
139 it = iter(sub_it)
140 try:
141 yield "%s %s" % (self.spec, it.next())
142 except StopIteration:
143 pass
144
145 for line in it:
146 yield line
147
148 sub_tp, sub_decl = self.subdecl.get_decl_pair()
149 return add_spec(sub_tp), sub_decl
150
154
158
162
166
170
174
175
176
177 -class Const(NestedDeclarator):
179 sub_tp, sub_decl = self.subdecl.get_decl_pair()
180 return sub_tp, ("const %s" % sub_decl)
181
183 - def __init__(self, subdecl, count=None):
186
188 sub_tp, sub_decl = self.subdecl.get_decl_pair()
189 return sub_tp, ("*%s" % sub_decl)
190
193
196
198 - def __init__(self, subdecl, count=None):
201
203 sub_tp, sub_decl = self.subdecl.get_decl_pair()
204 if self.count is None:
205 count_str = ""
206 else:
207 count_str = str(self.count)
208 return sub_tp, ("%s[%s]" % (sub_decl, count_str))
209
212
218
219
220
221
223 - def __init__(self, subdecl, arg_decls):
226
228 sub_tp, sub_decl = self.subdecl.get_decl_pair()
229
230 return sub_tp, ("%s(%s)" % (
231 sub_decl,
232 ", ".join(ad.inline() for ad in self.arg_decls)))
233
235 raise RuntimeError, "function pointers can't be put into structs"
236
239
240
241
242
244 - def __init__(self, tpname, fields, declname=None, debug=False):
245 self.tpname = tpname
246 self.fields = fields
247 self.declname = declname
248 self.debug = debug
249
251 def get_tp():
252 if self.tpname is not None:
253 yield "struct %s" % self.tpname
254 else:
255 yield "struct"
256 yield "{"
257 for f in self.fields:
258 for f_line in f.generate():
259 yield " " + f_line
260 yield "}"
261 return get_tp(), self.declname
262
263 - def make(self, **kwargs):
276
277 @memoize_method
280
281 @memoize_method
283 from struct import calcsize
284 return calcsize(self.struct_format())
285
286
287
288
289
290 -class If(Generable):
291 - def __init__(self, condition, then_, else_=None):
292 self.condition = condition
293 self.then_ = then_
294 self.else_ = else_
295
297 yield "if (%s)" % self.condition
298
299 if isinstance(self.then_, Block):
300 for line in self.then_.generate():
301 yield line
302 else:
303 for line in self.then_.generate():
304 yield " "+line
305
306 if self.else_ is not None:
307 yield "else"
308 if isinstance(self.else_, Block):
309 for line in self.else_.generate():
310 yield line
311 else:
312 for line in self.else_.generate():
313 yield " "+line
314
317 self.condition = condition
318 self.body = body
319
321 yield "while (%s)" % self.condition
322
323 if isinstance(self.body, Block):
324 for line in self.body.generate():
325 yield line
326 else:
327 for line in self.body.generate():
328 yield " "+line
329
330 -class For(Generable):
331 - def __init__(self, start, condition, end, body):
332 self.start = start
333 self.condition = condition
334 self.end = end
335 self.body = body
336
338 yield "for (%s; %s; %s)" % (self.start, self.condition, self.end)
339
340 if isinstance(self.body, Block):
341 for line in self.body.generate():
342 yield line
343 else:
344 for line in self.body.generate():
345 yield " "+line
346
349 self.condition = condition
350 self.body = body
351
353 yield "do"
354 if isinstance(self.body, Block):
355 for line in self.body.generate():
356 yield line
357 else:
358 for line in self.body.generate():
359 yield " "+line
360 yield "while (%s)" % self.condition
361
363 for cond, block in conditions_and_blocks[::-1]:
364 base = If(cond, block, base)
365 return base
366
367
368
369
370
373 self.symbol = symbol
374 self.value = value
375
377 yield "#define %s %s" % (self.symbol, self.value)
378
382
384 yield "#pragma %s" % (self.value)
385
392
395 self.lvalue = lvalue
396 self.rvalue = rvalue
397
399 yield "%s = %s;" % (self.lvalue, self.rvalue)
400
401 -class Line(Generable):
407
414
415
416
417
420 self.vdecl = vdecl
421 self.data = data
422
424 tp_lines, tp_decl = self.vdecl.get_decl_pair()
425 tp_lines = list(tp_lines)
426 for line in tp_lines[:-1]:
427 yield line
428 yield "%s %s = %s;" % (tp_lines[-1], tp_decl, self.data)
429
432
435 self.vdecl = vdecl
436 self.data = data
437
439 for v_line in self.vdecl.generate(with_semicolon=False):
440 yield v_line
441 yield " = { %s };" % (", ".join(str(item) for item in self.data))
442
443 -class FunctionBody(Generable):
444 - def __init__(self, fdecl, body):
445 self.fdecl = fdecl
446 self.body = body
447
448 - def generate(self):
449 for f_line in self.fdecl.generate(with_semicolon=False):
450 yield f_line
451 for b_line in self.body.generate():
452 yield b_line
453
454
455
456
457
458
461 self.contents = contents[:]
462
464 yield "{"
465 for item in self.contents:
466 for item_line in item.generate():
467 yield " " + item_line
468 yield "}"
469
472
475
480
483 for c in self.contents:
484 for line in c.generate():
485 yield line
486
487
488
489
490
492 s = Struct("yuck", [
493 POD(numpy.float32, "h", ),
494 POD(numpy.float32, "order"),
495 POD(numpy.float32, "face_jacobian"),
496 ArrayOf(POD(numpy.float32, "normal"), 17),
497 POD(numpy.uint16, "a_base"),
498 POD(numpy.uint16, "b_base"),
499 CudaGlobal(POD(numpy.uint8, "a_ilist_number")),
500 POD(numpy.uint8, "b_ilist_number"),
501 POD(numpy.uint8, "bdry_flux_number"),
502 POD(numpy.uint8, "reserved"),
503 POD(numpy.uint32, "b_global_base"),
504 ])
505 f_decl = FunctionDeclaration(POD(numpy.uint16, "get_num"), [
506 POD(numpy.uint8, "reserved"),
507 POD(numpy.uint32, "b_global_base"),
508 ])
509 f_body = FunctionBody(f_decl, Block([
510 POD(numpy.uint32, "i"),
511 For("i = 0", "i < 17", "++i",
512 If("a > b",
513 Assign("a", "b"),
514 Block([
515 Assign("a", "b-1", "+="),
516 Break(),
517 ])
518 ),
519 ),
520 BlankLine(),
521 Comment("all done"),
522 ]))
523 print s
524 print f_body
525
526
527
528
529 if __name__ == "__main__":
530 _test()
531