source: CIVL/examples/translation/openclversion2.15/multiple.cvl@ 9c5dca0

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

sub example

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

  • Property mode set to 100644
File size: 4.5 KB
Line 
1
2
3#include "cl.cvl"
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <civlc.h>
8#include "multiplekernel.cvl"
9
10int numArgs = 2;
11int numKernels = 4;
12/*
13 This version of the kernel has a flag for each element in the param array
14 If the mallocflag is set to 1, it means that it will be freed by clReleaseKernel
15*/
16typedef struct
17{
18 void * param[numArgs];
19 int mallocflag[numArgs];
20}args;
21/*
22 clCreateKernel in this iteration turns each flag to 0 to start off with, otherwise it gets a symbolic expression
23*/
24cl_kernel clCreateKernel(args * argument, char * function)
25{
26 cl_kernel kernel;
27 kernel.arguments = argument;
28 kernel.method = function;
29
30 for(int j = 0; j < numArgs; j++)
31 {
32 ((args*)kernel.arguments)->mallocflag[j] = 0;
33 }
34
35 return kernel;
36}
37/*
38 Checks the flag to make sure that it was a local variable that must be freed every step of the way
39*/
40void clReleaseKernel(cl_kernel kernel)
41{
42 for (int i = 0; i < numArgs; i++)
43 {
44 //printf("I am argument %d with value %d\n", i, ((args*)kernel.arguments)->mallocflag[i]);
45 if (((args*)kernel.arguments)->mallocflag[i] == 1)
46 {
47 //printf("and I pass the flag check\n");
48 free(((args*)kernel.arguments)->param[i]);
49 }
50 }
51}
52//Workfunc and clEnqueueNDRangeKernel are the same.
53void workfunc(size_t local, size_t global, cl_kernel param)
54{
55 $proc procs[local];
56 char * reduceChar = "add";
57 for(int i = local * param.workgroup; i < local * param.workgroup + local; i++)
58 {
59 int n = *(int*)(((args*)param.arguments)->param[0]);
60 param.local_id = i % local;
61 param.global_id = i;
62 //printf("My workgroup id is %d, my global id is %d, my local id is %d, and my method is %s\n", param.workgroup, param.global_id, param.local_id, param.method);
63
64
65 //if(strcmp(param.method, reduceChar) == 0)
66 //{
67 procs[param.local_id] = $spawn add(param.workgroup, param.global_id, param.local_id, n, ((args*)param.arguments)->param[1]);
68 //}
69 }
70 for(int j = 0; j < local; j++)
71 {
72 $wait(procs[j]);
73 }
74}
75
76int clEnqueueNDRangeKernel(cl_kernel kernel, size_t global, size_t local)
77{
78
79 $assert(global % local == 0);
80 int numworkgroups = global/local;
81 cl_kernel param[numworkgroups];
82 $proc procs[numworkgroups];
83 //consider $parfor
84
85 /*
86 $domain(1) dom = {0 .. numworkgroups - 1};
87
88 $for(int i: dom)
89 {
90 param[i] = kernel;
91 param[i].workgroup = i;
92 }
93 $parfor(int i: dom)
94 {
95 workfunc(local, global, param[i]);
96 }
97 */
98
99 for(int i = 0; i < global/local; i++)
100 {
101 param[i] = kernel;
102 param[i].workgroup = i;
103 procs[i] = $spawn workfunc(local, global, param[i]);
104 }
105
106 //this part here is the new clFinish(commands);
107 for(int i = 0; i < global/local; i++)
108 {
109 $wait(procs[i]);
110 }
111
112 return CL_SUCCESS;
113
114}
115
116int main(int argc, char** argv)
117{
118 int global = numKernels;
119 int local = 2;
120
121 args * arguments;
122 arguments = (args*)malloc(sizeof(args) * numKernels);
123 //Must have enough arguments for each kernel
124
125 int star = 1;
126
127 int * one = (int*)malloc(sizeof(int));
128 memcpy(one, &star, sizeof(int));
129
130 //cl_kernel *kernels = (cl_kernel*)malloc(numKernels * sizeof(cl_kernel));
131 cl_kernel kernels[numKernels];
132
133 //printf("%d, %d\n", star, *one);
134
135 //For loop to create multiple kernels, the programmer must put the loop himself
136 for (int i = 0; i < numKernels; i++)
137 {
138 kernels[i] = clCreateKernel(arguments+i, "add");
139
140
141 }
142 //For each kernel, put in the variables
143 for (int j = 0; j < numKernels; j++)
144 {
145
146 ((args*)kernels[j].arguments)->param[0] = (int*)malloc(sizeof(int));
147 ((args*)kernels[j].arguments)->mallocflag[0] = 1;
148 memcpy(((args*)kernels[j].arguments)->param[0], &star, sizeof(int));
149
150 //param[0] is a __local variable, so it gets the flag put to 1
151
152 //printf("I am kernel of index %d, with a value of %d\n", j, ((args*)kernels[j].arguments)->param[0]);
153
154 ((args*)kernels[j].arguments)->param[1] = one;
155 //This is a __global variable, so it does not get the flag changed in this iteration.
156 //TODO: determine if global variables were freed by clReleaseKernel or the programmer.
157 }
158
159 //printf("assigned properly\n");
160
161 for (int i = 0; i < numKernels; i++)
162 {
163 clEnqueueNDRangeKernel(kernels[i], global, local);
164 }
165 int ans = (int)((args*)kernels[0].arguments)->param[1];
166 //memcpy(ans, &((args*)kernels[0].arguments)->param[1], sizeof(int));
167 printf("There are %d kernels, and the final value is %d\n", numKernels, ans);
168
169 for (int k = 0; k < numKernels; k++)
170 {
171 clReleaseKernel(kernels[k]);
172 }
173
174
175
176 free(one);
177 free(arguments);
178 return 0;
179}
180
181
Note: See TracBrowser for help on using the repository browser.