… | |
… | |
7 | use OpenCL; |
7 | use OpenCL; |
8 | |
8 | |
9 | =head1 DESCRIPTION |
9 | =head1 DESCRIPTION |
10 | |
10 | |
11 | This is an early release which is not useful yet. |
11 | This is an early release which is not useful yet. |
|
|
12 | |
|
|
13 | =head1 HELPFUL RESOURCES |
|
|
14 | |
|
|
15 | The OpenCL spec used to dveelop this module (1.2 spec was available, but |
|
|
16 | no implementation was available to me :). |
|
|
17 | |
|
|
18 | http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf |
|
|
19 | |
|
|
20 | OpenCL manpages: |
|
|
21 | |
|
|
22 | http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/ |
|
|
23 | |
|
|
24 | =head1 EXAMPLES |
12 | |
25 | |
13 | Enumerate all devices and get contexts for them; |
26 | Enumerate all devices and get contexts for them; |
14 | |
27 | |
15 | for my $platform (OpenCL::platforms) { |
28 | for my $platform (OpenCL::platforms) { |
16 | warn $platform->info (OpenCL::PLATFORM_NAME); |
29 | warn $platform->info (OpenCL::PLATFORM_NAME); |
… | |
… | |
26 | |
39 | |
27 | my $dev = ((OpenCL::platforms)[0]->devices)[0]; |
40 | my $dev = ((OpenCL::platforms)[0]->devices)[0]; |
28 | my $ctx = $dev->context_simple; |
41 | my $ctx = $dev->context_simple; |
29 | my $queue = $ctx->command_queue_simple ($dev); |
42 | my $queue = $ctx->command_queue_simple ($dev); |
30 | |
43 | |
|
|
44 | Create a buffer with some predefined data, read it back synchronously, |
|
|
45 | then asynchronously: |
|
|
46 | |
|
|
47 | my $buf = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, "helmut"); |
|
|
48 | |
|
|
49 | $queue->enqueue_read_buffer ($buf, 1, 1, 3, my $data); |
|
|
50 | warn $data; |
|
|
51 | |
|
|
52 | my $ev = $queue->enqueue_read_buffer ($buf, 0, 1, 3, my $data); |
|
|
53 | $ev->wait; |
|
|
54 | warn $data; |
|
|
55 | |
|
|
56 | Print all supported image formats: |
|
|
57 | |
|
|
58 | for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) { |
|
|
59 | say "supported image formats for ", OpenCL::enum2str $type; |
|
|
60 | |
|
|
61 | for my $f ($ctx->supported_image_formats (0, $type)) { |
|
|
62 | printf " %-10s %-20s\n", OpenCL::enum2str $f->[0], OpenCL::enum2str $f->[1]; |
|
|
63 | } |
|
|
64 | } |
|
|
65 | |
|
|
66 | Create and build a program, then create a kernel out of one of its |
|
|
67 | functions: |
|
|
68 | |
|
|
69 | my $src = ' |
|
|
70 | __kernel void |
|
|
71 | squareit (__global float *input, __global float *output) |
|
|
72 | { |
|
|
73 | size_t id = get_global_id (0); |
|
|
74 | output [id] = input [id] * input [id]; |
|
|
75 | } |
|
|
76 | '; |
|
|
77 | |
|
|
78 | my $prog = $ctx->program_with_source ($src); |
|
|
79 | |
|
|
80 | eval { $prog->build ($dev); 1 } |
|
|
81 | or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG); |
|
|
82 | |
|
|
83 | my $kernel = $prog->kernel ("squareit"); |
|
|
84 | |
|
|
85 | Create some input and output float buffers, then call squareit on them: |
|
|
86 | |
|
|
87 | my $input = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, pack "f*", 1, 2, 3, 4.5); |
|
|
88 | my $output = $ctx->buffer (0, OpenCL::SIZEOF_FLOAT * 5); |
|
|
89 | |
|
|
90 | # set buffer |
|
|
91 | $kernel->set_buffer (0, $input); |
|
|
92 | $kernel->set_buffer (1, $output); |
|
|
93 | |
|
|
94 | # execute it for all 4 numbers |
|
|
95 | $queue->enqueue_nd_range_kernel ($kernel, undef, [4], undef); |
|
|
96 | |
|
|
97 | # enqueue a barrier ot ensure in-order execution (not really needed in this case) |
|
|
98 | $queue->enqueue_barrier; |
|
|
99 | |
|
|
100 | # enqueue an async read (could easily be blocking here though), then wait for it: |
|
|
101 | my $ev = $queue->enqueue_read_buffer ($output, 0, 0, OpenCL::SIZEOF_FLOAT * 4, my $data); |
|
|
102 | $ev->wait; |
|
|
103 | |
|
|
104 | # print the results: |
|
|
105 | say join ", ", unpack "f*", $data; |
|
|
106 | |
31 | =over 4 |
107 | =over 4 |
32 | |
108 | |
33 | =cut |
109 | =cut |
34 | |
110 | |
35 | package OpenCL; |
111 | package OpenCL; |
36 | |
112 | |
37 | use common::sense; |
113 | use common::sense; |
38 | |
114 | |
39 | BEGIN { |
115 | BEGIN { |
40 | our $VERSION = '0.01'; |
116 | our $VERSION = '0.02'; |
41 | |
117 | |
42 | require XSLoader; |
118 | require XSLoader; |
43 | XSLoader::load (__PACKAGE__, $VERSION); |
119 | XSLoader::load (__PACKAGE__, $VERSION); |
|
|
120 | |
|
|
121 | @OpenCL::Buffer::ISA = |
|
|
122 | @OpenCL::Image::ISA = OpenCL::Memory::; |
|
|
123 | |
|
|
124 | @OpenCL::Image2D::ISA = |
|
|
125 | @OpenCL::Image3D::ISA = OpenCL::Image::; |
44 | } |
126 | } |
45 | |
127 | |
46 | 1; |
128 | 1; |
47 | |
129 | |
48 | =back |
130 | =back |