source: CIVL/examples/translation/openclversion2/square.cvl@ 4fc1b8d

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 4fc1b8d was aec3070, checked in by Jacob Trieu <fuufusuu@…>, 12 years ago

square.cvl

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

  • Property mode set to 100644
File size: 5.6 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5//CIVL DOES NOT SUPPORT FLOATS AS IS, RANDOM IS UNINTERPRETED
6/*
7If increase MAX_DATA_SIZE, nothing happens if DATA_SIZE is given a concrete value
8If I increase DATA_SIZE to 2, I get
9Computed '2/2' correct values!
10Computed '1/2' correct values!
11
12If I make num_devices >= data_size, I get a num/num correct values, like the default
13data = 3, devices = 1
14Computed '3/3' correct values!
15Computed '2/3' correct values!
16Computed '2/3' correct values!
17Computed '1/3' correct values!
18
19data = 3, devices = 2
20Computed '3/3' correct values!
21Computed '2/3' correct values!
22
23data = 3, devices = 3
24Computed '3/3' correct values!
25*/
26$input int DATA_SIZE;
27$input int NUM_DEVICES;
28$input int MAX_DATA_SIZE;
29$input int MAX_NUM_DEVICES;
30$input int CL_DEVICE_MAX_WORK_GROUP_SIZE;
31$input int LOCAL;
32$assume 0 < DATA_SIZE && DATA_SIZE < MAX_DATA_SIZE;
33$assume 0 < NUM_DEVICES && NUM_DEVICES < MAX_NUM_DEVICES;
34$gbarrier gbarrier = $gbarrier_create($here, NUM_DEVICES);
35//struct goes here
36
37
38typedef struct
39{
40 int device_id;
41 int workgroup;
42 int global_id;
43 int local_id;
44
45 //kernel variables
46 int * input;
47 int * output;
48 int count;
49}kernel;
50
51//kernel goes here
52void square(int workgroup, int global_id, int local_id, int* input, int* output, const unsigned int count)
53{
54 //int i = get_global_id(0);
55 int i = global_id;
56 if (i < count)
57 {
58 output[i] = input[i] * input[i];
59 //printf("output[%d] is %d\n", i, output[i]);
60 }
61}
62
63void worksquare(size_t local, size_t global, kernel param)
64{
65 for(int i = local * param.workgroup; i < local * param.workgroup + local; i++)
66 {
67 param.local_id = i % local;
68 param.global_id = i;
69 //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);
70 square(param.workgroup, param.global_id, param.local_id, param.input, param.output, param.count);
71 }
72}
73/*
74Note that the original lines were "__kernel void square( \n" \
75" __global int* input, \n" \
76" __global int* output, \n" \
77" const unsigned int count) \n" \
78
79Any parser must take note of and don't input \n, "", or \ as is
80__global int * input, __global int * output, int count;
81*/
82
83
84int main(int argc, char** argv)
85{
86 //get the number from clGetDeviceIDs 3rd parameter
87 //int num_devices = 1;
88 $assert (LOCAL < CL_DEVICE_MAX_WORK_GROUP_SIZE);
89 //variables from __kernel come here
90 int * input;
91 int * output;
92 int count;
93
94 size_t global; // global domain size for our calculation
95 size_t local; // local domain size for our calculation
96
97 //from the code before
98 int data[DATA_SIZE]; // original data set given to device
99 int results[DATA_SIZE]; // results returned from device
100 int correct; // number of correct results returned
101 //handle the definitions being put in different places
102
103 int i = 0;
104 count = DATA_SIZE; //count defined here
105 for(i = 0; i < count; i++)
106 {
107 data[i] = i;
108 }
109
110
111
112 //comes from clCreateBuffer
113 input = (int *) malloc(sizeof(int) * count);
114 output = (int *) malloc(sizeof(int) * count);
115
116 //Possibly keep a list of variables, with a flag for whether they are init or not
117 //Not init, malloc one from what is found in
118 //output = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(int) * count, NULL, NULL);
119
120
121 memcpy(input, data, sizeof(int) * count);
122
123 //came from clEnqueueWriteBuffer rather than the start of code
124
125
126 //Phase after this is the definitions
127 int device_id[NUM_DEVICES];
128 //put device_ids
129 for(int i = 0; i < NUM_DEVICES; i++)
130 {
131 device_id[i] = i;
132 }
133
134 //from clCreateContext, uses the device input
135 //but there may be a loop, take it into account in the next example
136
137 //
138 //"Get" local size from clEnqueueNDRangeKernel, but is really an input
139 local = LOCAL;
140
141
142 global = count;
143 //Creates an array of the struct according to clEnqueueNDRangeKernel
144 //Have to split array into parts using local and global, and those are a workgroup
145 //For now, assume local is 1, or else inputting the arrays will be odd, for now
146 $assert(global%local == 0);
147 kernel param[global/local];
148 for(int i = 0; i < global/local; i++)
149 {
150 //Also picks the device to be used
151 param[i].device_id = device_id[0];
152 //other parts of the struct
153 param[i].input = input;
154 param[i].output = output;
155 param[i].count = count;
156 }
157
158
159 //spawns processes according to parameters in clEnqueueNDRangeKernel
160 $proc procs[global/local];
161 for(int i = 0; i < global/local; i++)
162 {
163 param[i].workgroup = i;
164 //procs[i] = $spawn square(param[i].global_id, param[i].input, param[i].output, param[i].count);
165 procs[i] = $spawn worksquare(local, global, param[i]);
166 }
167
168 for(int i = 0; i < global/local; i++)
169 {
170 $wait(procs[i]);
171 }
172
173 //$barrier barrier = $barrier_create($here, gbarrier, now[i].device_id);
174 //$barrier_call(barrier);
175 //$barrier_destroy(barrier);
176
177 $gbarrier_destroy(gbarrier);
178
179 //use the information from clEnqueueReadBuffer
180 //may have to alter later
181 for(int i = 0; i < count; i++)
182 {
183 results[i] = output[i];
184 }
185
186
187 correct = 0;
188 for(i = 0; i < count; i++)
189 {
190 //printf("results at %i is %d, data^2 is %d \n", i, results[i], data[i] * data[i]);
191 if(results[i] == data[i] * data[i])
192 {
193 correct++;
194 }
195 }
196
197 // Print a brief summary detailing the results
198 //
199 printf("Computed '%d/%d' correct values!\n", correct, count);
200
201
202 return 0;
203}
Note: See TracBrowser for help on using the repository browser.