~ubuntu-branches/ubuntu/wily/pyopencl/wily

« back to all changes in this revision

Viewing changes to doc/howto.rst

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-10-22 18:08:41 UTC
  • mfrom: (2.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20131022180841-1lcaecrns774y1ys
Tags: 2013.1+git20130916-1build1
No change rebuild for Boost 1.54 transition.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
How-tos
 
2
=======
 
3
 
 
4
How to use struct types with PyOpenCL
 
5
-------------------------------------
 
6
 
 
7
We import and initialize PyOpenCL as usual:
 
8
 
 
9
.. doctest::
 
10
    :options: +ELLIPSIS
 
11
 
 
12
    >>> import numpy as np
 
13
    >>> import pyopencl as cl
 
14
    >>> import pyopencl.tools
 
15
    >>> import pyopencl.array
 
16
 
 
17
    >>> ctx = cl.create_some_context(interactive=False)
 
18
    >>> queue = cl.CommandQueue(ctx)
 
19
 
 
20
Then, suppose we would like to declare a struct consisting of an integer and a
 
21
floating point number. We first create a :class:`numpy.dtype` along these
 
22
lines:
 
23
 
 
24
.. doctest::
 
25
 
 
26
    >>> my_struct = np.dtype([("field1", np.int32), ("field2", np.float32)])
 
27
    >>> print my_struct
 
28
    [('field1', '<i4'), ('field2', '<f4')]
 
29
 
 
30
.. note::
 
31
 
 
32
    Not all :mod:`numpy` dtypes are supported yet. For example strings (and
 
33
    generally things that have a shape of their own) are not supported.
 
34
 
 
35
Since OpenCL C may have a different opinion for :mod:`numpy` on how the struct
 
36
should be laid out, for example because of `alignment
 
37
<https://en.wikipedia.org/wiki/Data_structure_alignment>`_. So as a first step, we
 
38
match our dtype against CL's version:
 
39
 
 
40
.. doctest::
 
41
 
 
42
    >>> my_struct, my_struct_c_decl = cl.tools.match_dtype_to_c_struct(
 
43
    ...    ctx.devices[0], "my_struct", my_struct)
 
44
    >>> print my_struct_c_decl
 
45
    typedef struct {
 
46
      int field1;
 
47
      float field2;
 
48
    } my_struct;
 
49
    <BLANKLINE>
 
50
    <BLANKLINE>
 
51
 
 
52
We then tell PyOpenCL about our new type.
 
53
 
 
54
.. doctest::
 
55
 
 
56
    >>> my_struct = cl.tools.get_or_register_dtype("my_struct", my_struct)
 
57
 
 
58
Next, we can create some data of that type on the host and transfer it to
 
59
the device:
 
60
 
 
61
.. doctest::
 
62
 
 
63
    >>> ary_host = np.empty(20, my_struct)
 
64
    >>> ary_host["field1"].fill(217)
 
65
    >>> ary_host["field2"].fill(1000)
 
66
    >>> ary_host[13]["field2"] = 12
 
67
    >>> print ary_host
 
68
    [(217, 1000.0) (217, 1000.0) (217, 1000.0) (217, 1000.0) (217, 1000.0)
 
69
     (217, 1000.0) (217, 1000.0) (217, 1000.0) (217, 1000.0) (217, 1000.0)
 
70
     (217, 1000.0) (217, 1000.0) (217, 1000.0) (217, 12.0) (217, 1000.0)
 
71
     (217, 1000.0) (217, 1000.0) (217, 1000.0) (217, 1000.0) (217, 1000.0)]
 
72
 
 
73
    >>> ary = cl.array.to_device(queue, ary_host)
 
74
 
 
75
We can then operate on the array with our own kernels:
 
76
 
 
77
.. doctest::
 
78
 
 
79
    >>> prg = cl.Program(ctx, my_struct_c_decl + """
 
80
    ...     __kernel void set_to_1(__global my_struct *a)
 
81
    ...     {
 
82
    ...         a[get_global_id(0)].field1 = 1;
 
83
    ...     }
 
84
    ...     """).build()
 
85
 
 
86
    >>> evt = prg.set_to_1(queue, ary.shape, None, ary.data)
 
87
    >>> print ary
 
88
    [(1, 1000.0) (1, 1000.0) (1, 1000.0) (1, 1000.0) (1, 1000.0) (1, 1000.0)
 
89
     (1, 1000.0) (1, 1000.0) (1, 1000.0) (1, 1000.0) (1, 1000.0) (1, 1000.0)
 
90
     (1, 1000.0) (1, 12.0) (1, 1000.0) (1, 1000.0) (1, 1000.0) (1, 1000.0)
 
91
     (1, 1000.0) (1, 1000.0)]
 
92
 
 
93
as well as with PyOpenCL's built-in operations:
 
94
 
 
95
    >>> from pyopencl.elementwise import ElementwiseKernel
 
96
    >>> elwise = ElementwiseKernel(ctx, "my_struct *a", "a[i].field1 = 2;",
 
97
    ...    preamble=my_struct_c_decl)
 
98
    >>> evt = elwise(ary)
 
99
    >>> print ary
 
100
    [(2, 1000.0) (2, 1000.0) (2, 1000.0) (2, 1000.0) (2, 1000.0) (2, 1000.0)
 
101
     (2, 1000.0) (2, 1000.0) (2, 1000.0) (2, 1000.0) (2, 1000.0) (2, 1000.0)
 
102
     (2, 1000.0) (2, 12.0) (2, 1000.0) (2, 1000.0) (2, 1000.0) (2, 1000.0)
 
103
     (2, 1000.0) (2, 1000.0)]