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

1.23 2.0 main test-branch
Last change on this file since dccd621 was 6317abc, checked in by Ziqing Luo <ziqing@…>, 12 years ago

renaming opencl version files
move div0 to arithmetic

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

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