source: CIVL/examples/opencl/2.14/life.cvl

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 4.8 KB
RevLine 
[3ff27cf]1#include <civlc.cvh>
[cc87898]2
3#include "openCLshared.cvl"
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <math.h>
8
9$input int ITERATIONS;
10$input int WIDTH;
11$input int HEIGHT;
12$input int INPUT;
13
14typedef struct
15{
16 int workgroup;
17 int global_id;
18 int local_id;
19
20 //kernel variables
21 bool * input;
22 bool *output;
23 int height;
24 int width;
25
26}args;
27
28
29cl_kernel clCreateKernel(args * argument)
30{
31 cl_kernel kernel;
32 kernel.arguments = argument;
33
34 return kernel;
35}
36
37//kernel goes here
38void life(int workgroup,
39 int global_id,
40 int local_id,
41 bool * input,
42 bool* output,
43 int height,
44 int width)
45{
46 int i = global_id;
47 int rowUp = i - width;
48 int rowDown = i + width;
49 bool outOfBounds = (i < width);
50 //|= not supported in ABC yet
51 outOfBounds = (i > (width * (height-1)));
52 if (outOfBounds)
53 {
54 output[i] = false; return;
55 }
56
57 outOfBounds = (i % width == 0);
58 if (outOfBounds)
59 {
60 output[i] = false; return;
61 }
62
63 outOfBounds = (i % width == width-1);
64 if (outOfBounds)
65 {
66 output[i] = false; return;
67 }
68 int neighbours = input[rowUp-1] + input[rowUp] + input[rowUp+1];
69 neighbours += input[i-1] + input[i+1];
70 neighbours += input[rowDown-1] + input[rowDown] + input[rowDown+1];
71 if (neighbours == 3 || (input[i] && neighbours == 2))
72 {
73 output[i] = true;
74 }
75 else
76 {
77 output[i] = false;
78 }
79}
80
81void workfunc(size_t local, size_t global, cl_kernel param)
82{
83 for(int i = local * param.workgroup; i < local * param.workgroup + local; i++)
84 {
85 param.local_id = i % local;
86 param.global_id = i;
87 //printf("My workgroup id is %d, my global id is %d, my local id is %d\n", param.workgroup, param.global_id, param.local_id);
88 life(param.workgroup, param.global_id, param.local_id, ((args*)param.arguments)->input, ((args*)param.arguments)->output, ((args*)param.arguments)->height, ((args*)param.arguments)->width);
89 }
90}
91
92int clEnqueueNDRangeKernel(cl_command_queue commands, cl_kernel kernel, int global, int local)
93{
[3ff27cf]94 $assert((global % local == 0));
[cc87898]95 cl_kernel param[global/local];
96 $proc procs[global/local];
97 for(int i = 0; i < global/local; i++)
98 {
99 param[i] = kernel;
100 param[i].workgroup = i;
101 procs[i] = $spawn workfunc(local, global, param[i]);
102 }
103
104 //this part here is the new clFinish(commands);
105 for(int i = 0; i < global/local; i++)
106 {
107 $wait(procs[i]);
108 }
109
110 return CL_SUCCESS;
111}
112
113
114//how to deal with own implementation of clCreateKernelFromSource?
115
116// The board
117static const size_t board_size = WIDTH * HEIGHT;
118static bool board[board_size];
119// Storage for the board.
120static bool * input;
121static bool * output;
122// OpenCL state
123static cl_command_queue queue;
124static cl_kernel kernel;
125static cl_device_id device_id;
126static cl_context context;
127
128void printBoard(void)
129{
130 unsigned i = 0;
131
132 for (unsigned y=0 ; y<HEIGHT ; y++)
133 {
134 for (unsigned x=0 ; x<WIDTH ; x++)
135 {
136 //putc(board[i++] ? '*' : ' ', stdout);
137 if (board[i] == 1)
138 {
139 printf("*");
140 }
141 else
142 {
143 printf(" ");
144 }
145 i++;
146 }
147 printf("\n");
148 }
149}
150
151void createQueue(void)
152{
153 int err;
154 err = clGetDeviceIDs(1, &device_id);
155
156 queue = clCreateCommandQueue(device_id);
157}
158
159void prepareKernel(void)
160{
161 input = (bool*)malloc(sizeof(board));
162 output = (bool*)malloc(sizeof(board));
163
164 ((args*)kernel.arguments)->input = input;
165 ((args*)kernel.arguments)->output = output;
166 ((args*)kernel.arguments)->height = HEIGHT;
167 ((args*)kernel.arguments)->width = WIDTH;
168}
169
170void runGame(int iterations)
171{
172 if(iterations == 0) {return;}
173 int err;
174 size_t workgroup_size;
175 workgroup_size = INPUT;
176
177 memcpy(input, board, sizeof(board));
178
179 for (int i = 0; i < iterations; i++)
180 {
181 err = clEnqueueNDRangeKernel(queue, kernel, board_size, workgroup_size);
182
183 if (i < iterations - 1)
184 {
185 memcpy(output, input, sizeof(board));
186 }
187 }
188 memcpy(board, output, sizeof(board));
189}
190
191//CIVL models scanf() differently, uses symbolic expressions and loops forever here
192//Always possible for iterations > 0
193int main(int argc, char** argv)
194{
195 args * arguments;
196 arguments = (args*)malloc(sizeof(args));
197
198/*
199 for(unsigned int i=0 ; i<board_size; i++)
200 {
201 board[i] = (i % 2);
202 //done this way because you can't see what numbers come from random, and it seems that it just does ******* anyhow
203 //printf("board[%d] is %d\n", i, board[i]);
204 }
205 */
206 for(unsigned int i=0 ; i<board_size; i = i + 2)
207 {
208 board[i] = 1;
209 }
210 //proves that the kernel "works", although it runs through multiple times
211 createQueue();
212
213 kernel = clCreateKernel(arguments);
214
215 prepareKernel();
216
217
218 printBoard();
219 printf("Running for how %d iterations\n", ITERATIONS);
220 for(int i = 0; i < ITERATIONS; i++)
221 {
222 printf("Running iteration %d\n", i);
223 runGame(ITERATIONS);
224 printBoard();
225 }
226
227
228 free(arguments);
229
230 free(input);
231 free(output);
232
233
234
235 return 0;
236}
Note: See TracBrowser for help on using the repository browser.